Skip to content

🔧 Tutorial Deployment Flask z Podman + Traefik - Jak używać Traefik jako zaawansowanego reverse proxy Jak konfigurować service discovery Jak używać labels w kontenerach Jak monitorować aplikacje przez dashboard

License

Notifications You must be signed in to change notification settings

DevOpsTerminal/python-podman-traefik

Repository files navigation

Tutorial Deployment Flask z Podman + Traefik

Jak używać Traefik jako zaawansowanego reverse proxy Jak konfigurować service discovery Jak używać labels w kontenerach Jak monitorować aplikacje przez dashboard

Czego się nauczysz?

  • Jak używać Traefik jako zaawansowanego reverse proxy
  • Jak konfigurować service discovery
  • Jak używać labels w kontenerach
  • Jak monitorować aplikacje przez dashboard

⚠️ Uwaga: Ten tutorial jest bardziej zaawansowany niż Caddy!


Krok 1: Przygotowanie środowiska

Sprawdzenie narzędzi

podman info
podman-compose --version
docker compose version 

Instalacja podstawowych narzędzi na debian, Ubuntu

# Zaktualizuj system 
sudo apt update && sudo apt upgrade -y

# Zainstaluj Podman
sudo apt install podman -y

# Zainstaluj podman-compose (potrzebne do docker-compose.yml)
pip3 install podman-compose

# Lub alternatywnie docker-compose
sudo apt install docker-compose-plugin -y

Instalacja podstawowych narzędzi na Fedora

# Zaktualizuj system
sudo dnf upgrade --refresh -y

# Zainstaluj Podman
sudo dnf install podman -y

# Zainstaluj podman-compose (potrzebne do docker-compose.yml)
pip3 install --user podman-compose

# Upewnij się, że ~/.local/bin jest w PATH (jeśli nie, dodaj do ~/.bashrc lub ~/.zshrc)
export PATH=$HOME/.local/bin:$PATH

# (Opcjonalnie) Zainstaluj docker-compose-plugin z Dockerem
sudo dnf install dnf-plugins-core -y
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

# (Opcjonalnie) Włącz Docker jeśli został zainstalowany
sudo systemctl enable --now docker

Krok 2: Struktura projektu

mkdir -p ~/traefik-setup/{sklep,blog,api,portfolio}
cd ~/traefik-setup

Główny docker-compose.yml

nano docker-compose.yml
version: '3.8'

networks:
  web:
    driver: bridge

services:
  # Traefik - reverse proxy z dashboard
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    command:
      # Włącz API i dashboard
      - "--api.insecure=true"
      - "--api.dashboard=true"
      
      # Konfiguracja dostawców
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=web"
      
      # Entrypoints (porty wejściowe)
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      
      # SSL z Let's Encrypt
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.myresolver.acme.email=twoj@email.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      
      # Przekierowanie HTTP na HTTPS
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
    
    ports:
      - "80:80"
      - "443:443"
      - "8082:8080"  # Dashboard
    
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    
    networks:
      - web
    
    labels:
      - "traefik.enable=true"
      # Dashboard
      - "traefik.http.routers.dashboard.rule=Host(`dashboard.twoja-domena.pl`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls.certresolver=myresolver"

  # Sklep Flask App
  sklep:
    build: ./sklep
    container_name: sklep
    restart: unless-stopped
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sklep.rule=Host(`sklep.twoja-domena.pl`)"
      - "traefik.http.routers.sklep.entrypoints=websecure"
      - "traefik.http.routers.sklep.tls.certresolver=myresolver"
      - "traefik.http.services.sklep.loadbalancer.server.port=5000"

  # Blog Flask App
  blog:
    build: ./blog
    container_name: blog
    restart: unless-stopped
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.blog.rule=Host(`blog.twoja-domena.pl`)"
      - "traefik.http.routers.blog.entrypoints=websecure"
      - "traefik.http.routers.blog.tls.certresolver=myresolver"
      - "traefik.http.services.blog.loadbalancer.server.port=5000"

  # API Flask App
  api:
    build: ./api
    container_name: api
    restart: unless-stopped
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.twoja-domena.pl`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=myresolver"
      - "traefik.http.services.api.loadbalancer.server.port=5000"
      # CORS dla API
      - "traefik.http.routers.api.middlewares=cors"
      - "traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST,DELETE"
      - "traefik.http.middlewares.cors.headers.accesscontrolalloworigin=*"
      - "traefik.http.middlewares.cors.headers.accesscontrolmaxage=100"
      - "traefik.http.middlewares.cors.headers.addvaryheader=true"

  # Portfolio Flask App
  portfolio:
    build: ./portfolio
    container_name: portfolio
    restart: unless-stopped
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portfolio.rule=Host(`portfolio.twoja-domena.pl`)"
      - "traefik.http.routers.portfolio.entrypoints=websecure"
      - "traefik.http.routers.portfolio.tls.certresolver=myresolver"
      - "traefik.http.services.portfolio.loadbalancer.server.port=5000"

Krok 3: Przygotowanie aplikacji Flask

Przykład aplikacji (sklep/app.py)

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def home():
    return jsonify({
        "message": "Witaj w moim sklepie!",
        "version": "1.0",
        "endpoints": ["/", "/produkty", "/kategorie"]
    })

@app.route('/produkty')
def produkty():
    return jsonify({
        "produkty": [
            {"id": 1, "nazwa": "Laptop", "cena": 2999},
            {"id": 2, "nazwa": "Telefon", "cena": 1299}
        ]
    })

@app.route('/kategorie')
def kategorie():
    return jsonify({
        "kategorie": ["Elektronika", "Ubrania", "Książki"]
    })

if __name__ == '__main__':
    app.run(debug=True)

requirements.txt (dla każdej aplikacji)

Flask==2.3.3
gunicorn==21.2.0
flask-cors==4.0.0

Dockerfile (ten sam dla wszystkich)

FROM python:3.11-slim

WORKDIR /app

# Kopiuj requirements i zainstaluj zależności
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Kopiuj aplikację
COPY . .

EXPOSE 5000

# Używaj Gunicorn do produkcji
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]

Krok 4: Konfiguracja dla testów bez domeny

docker-compose-local.yml (do testów na IP)

version: '3.8'

networks:
  web:
    driver: bridge

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8082:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - web

  sklep:
    build: ./sklep
    container_name: sklep
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sklep.rule=PathPrefix(`/sklep`)"
      - "traefik.http.services.sklep.loadbalancer.server.port=5000"

  blog:
    build: ./blog
    container_name: blog
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.blog.rule=PathPrefix(`/blog`)"
      - "traefik.http.services.blog.loadbalancer.server.port=5000"

  api:
    build: ./api
    container_name: api
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=PathPrefix(`/api`)"
      - "traefik.http.services.api.loadbalancer.server.port=5000"

  portfolio:
    build: ./portfolio
    container_name: portfolio
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portfolio.rule=PathPrefix(`/portfolio`)"
      - "traefik.http.services.portfolio.loadbalancer.server.port=5000"

Krok 5: Testowanie środowiska (Ansible)

Do automatycznych testów środowiska możesz użyć playbooka:

ansible-playbook ansible/test.yml

Testuje on:

Przykład Makefile

up:
	podman-compose -f docker-compose.yml up -d

down:
	podman-compose -f docker-compose.yml down

logs:
	podman-compose -f docker-compose.yml logs

test:
	ansible-playbook ansible/test.yml

ps:
	podman ps -a

restart:
	podman-compose -f docker-compose.yml down && podman-compose -f docker-compose.yml up -d

Krok 6: Debugowanie

  • Jeśli dashboard nie działa na /dashboard/, sprawdź porty i ścieżki w traefik.yml.
  • Sprawdź logi Traefika: make logs
  • Sprawdź, czy backendy odpowiadają na /projekt1 i /projekt2.

Krok 7: Automatyzacja i zarządzanie

Skrypt zarządzania

nano ~/manage-traefik.sh
#!/bin/bash

case $1 in
  start)
    echo "🚀 Uruchamianie wszystkich serwisów..."
    cd ~/traefik-setup
    docker-compose up -d
    ;;
  stop)
    echo "🛑 Zatrzymywanie wszystkich serwisów..."
    cd ~/traefik-setup
    docker-compose down
    ;;
  restart)
    echo "🔄 Restart wszystkich serwisów..."
    cd ~/traefik-setup
    docker-compose restart
    ;;
  rebuild)
    echo "🔨 Rebuild aplikacji: $2"
    cd ~/traefik-setup
    docker-compose build $2
    docker-compose up -d $2
    ;;
  logs)
    echo "📋 Logi serwisu: $2"
    cd ~/traefik-setup
    docker-compose logs -f $2
    ;;
  status)
    echo "📊 Status wszystkich serwisów:"
    cd ~/traefik-setup
    docker-compose ps
    ;;
  dashboard)
    echo "🖥️ Dashboard dostępny na:"
    echo "http://$(curl -s ifconfig.me):8082"
    ;;
  *)
    echo "Użycie: $0 {start|stop|restart|rebuild|logs|status|dashboard}"
    echo "Przykłady:"
    echo "  $0 start"
    echo "  $0 rebuild sklep"
    echo "  $0 logs api"
    ;;
esac
chmod +x ~/manage-traefik.sh

Użycie skryptu

./manage-traefik.sh start       # Uruchom wszystko
./manage-traefik.sh rebuild sklep  # Przebuduj sklep
./manage-traefik.sh logs api    # Zobacz logi API
./manage-traefik.sh dashboard   # Pokaż URL dashboard

Krok 8: Zaawansowane funkcje Traefik

Load Balancing

# W docker-compose.yml możesz skalować serwisy:
sklep:
  # ... existing config
  deploy:
    replicas: 3
  labels:
    # Traefik automatycznie load-balancuje między replikami
    - "traefik.http.services.sklep.loadbalancer.server.port=5000"

Rate Limiting

# Dodaj middleware do limitowania requestów
labels:
  - "traefik.http.routers.api.middlewares=api-ratelimit"
  - "traefik.http.middlewares.api-ratelimit.ratelimit.burst=100"
  - "traefik.http.middlewares.api-ratelimit.ratelimit.average=50"

Basic Auth

# Wygeneruj hasło
sudo apt install apache2-utils
htpasswd -nb admin admin123
# Output: admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
labels:
  - "traefik.http.routers.dashboard.middlewares=auth"
  - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$ruca84Hq$$mbjdMZBAG.KWn7vfN/SNK/"

Krok 9: Backup i Recovery

Skrypt backup

nano ~/backup-traefik.sh
#!/bin/bash

BACKUP_DIR=~/backups/$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

echo "📦 Tworzenie backup..."

# Backup konfiguracji
cp -r ~/traefik-setup $BACKUP_DIR/

# Backup certyfikatów SSL
cp -r ~/traefik-setup/letsencrypt $BACKUP_DIR/ 2>/dev/null || true

# Backup volumes (jeśli masz dane)
docker-compose -f ~/traefik-setup/docker-compose.yml exec sklep tar -czf /tmp/sklep-data.tar.gz /app/data 2>/dev/null || true

echo "✅ Backup zapisany w: $BACKUP_DIR"

Krok 10: Troubleshooting

Częste problemy

Traefik nie widzi kontenerów

# Sprawdź sieć
docker network ls
docker network inspect traefik-setup_web

# Sprawdź labels
docker inspect sklep | grep traefik

Certyfikaty SSL nie działają

# Sprawdź logi Traefika: `make logs`
# Sprawdź plik certyfikatów
ls -la letsencrypt/

Dashboard nie działa

# Sprawdź czy port 8082 jest otwarty
sudo netstat -tlnp | grep 8082

# Sprawdź konfigurację
docker-compose exec traefik traefik version

Przydatne komendy debugowania

# Zobacz wszystkie routery
curl -s http://localhost:8082/api/http/routers | jq

# Zobacz wszystkie serwisy
curl -s http://localhost:8082/api/http/services | jq

# Status Traefik
curl -s http://localhost:8082/api/overview

📊 Porównanie: Traefik vs Caddy

Funkcja Traefik Caddy
Konfiguracja Labels w YAML Prosty Caddyfile
Dashboard ✅ Pełny dashboard ❌ Brak
Load Balancing ✅ Zaawansowany ⚠️ Podstawowy
Middleware ✅ Bogaty zestaw ⚠️ Ograniczony
Learning Curve 🔴 Stroma 🟢 Płaska
Service Discovery ✅ Automatyczny ❌ Manual

🎯 Kiedy wybrać Traefik?

Wybierz Traefik gdy:

  • Masz wiele mikrousług
  • Potrzebujesz load balancing
  • Chcesz dashboard do monitorowania
  • Planujesz skalowanie poziome
  • Potrzebujesz zaawansowane middleware

Zostań z Caddy gdy:

  • Masz proste aplikacje (jak Twoje 4 projekty Flask)
  • Chcesz szybko postawić serwer
  • Nie potrzebujesz zaawansowanych funkcji
  • Jesteś początkującym

🚀 Deployment produkcyjny z domeną

Konfiguracja DNS

# Ustaw rekordy A w swoim DNS:
# sklep.twoja-domena.pl     → IP_SERWERA
# blog.twoja-domena.pl      → IP_SERWERA
# api.twoja-domena.pl       → IP_SERWERA
# portfolio.twoja-domena.pl → IP_SERWERA
# dashboard.twoja-domena.pl → IP_SERWERA

Uruchomienie z pełną konfiguracją

cd ~/traefik-setup

# Zmień email w docker-compose.yml na swój
nano docker-compose.yml
# Znajdź: "--certificatesresolvers.myresolver.acme.email=twoj@email.com"

# Uruchom z pełną konfiguracją
docker-compose up -d

# Sprawdź logi SSL
docker-compose logs traefik | grep acme

Test SSL

# Sprawdź czy certyfikaty zostały wydane
curl -I https://sklep.twoja-domena.pl
curl -I https://api.twoja-domena.pl

# Dashboard z SSL
open https://dashboard.twoja-domena.pl

📈 Monitoring i metryki

Dodanie Prometheus + Grafana

# Dodaj do docker-compose.yml:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.prometheus.rule=Host(`prometheus.twoja-domena.pl`)"
      - "traefik.http.routers.prometheus.entrypoints=websecure"
      - "traefik.http.routers.prometheus.tls.certresolver=myresolver"

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin123
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.grafana.rule=Host(`grafana.twoja-domena.pl`)"
      - "traefik.http.routers.grafana.entrypoints=websecure"
      - "traefik.http.routers.grafana.tls.certresolver=myresolver"

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'traefik'
    static_configs:
      - targets: ['traefik:8082']

🔐 Bezpieczeństwo

Firewall

sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

Fail2ban dla Traefik

sudo apt install fail2ban

# Konfiguracja dla Traefik
sudo nano /etc/fail2ban/filter.d/traefik-auth.conf
[Definition]
failregex = ^<HOST> \- \S+ \[\] \"(GET|POST|HEAD).*\" 401
ignoreregex =
sudo nano /etc/fail2ban/jail.local
[traefik-auth]
enabled = true
port = http,https
filter = traefik-auth
logpath = /var/log/traefik/access.log
maxretry = 3
bantime = 3600

🔄 CI/CD z GitHub Actions

.github/workflows/deploy.yml

name: Deploy to VPS

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.7
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd ~/traefik-setup
          git pull origin main
          docker-compose build sklep
          docker-compose up -d sklep
          echo "✅ Deployment completed!"

Secrets w GitHub

HOST: IP_TWOJEGO_SERWERA
USERNAME: junior
SSH_KEY: (twój klucz prywatny SSH)

📱 Aplikacja mobilna do zarządzania

Prosty monitoring script

nano ~/status-check.sh
#!/bin/bash

echo "🔍 Sprawdzanie statusu aplikacji..."

services=("sklep" "blog" "api" "portfolio" "traefik")
base_url="https://twoja-domena.pl"

for service in "${services[@]}"; do
    if [ "$service" = "traefik" ]; then
        url="https://dashboard.twoja-domena.pl"
    else
        url="https://$service.twoja-domena.pl"
    fi
    
    status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
    
    if [ "$status" = "200" ]; then
        echo "$service: OK"
    else
        echo "$service: ERROR ($status)"
        # Restart kontenera
        cd ~/traefik-setup
        docker-compose restart $service
    fi
done

echo "📊 Zasoby serwera:"
echo "CPU: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')%"
echo "RAM: $(free | grep Mem | awk '{printf("%.1f%%", $3/$2 * 100.0)}')"
echo "Dysk: $(df -h / | awk 'NR==2{print $5}')"

Cron job dla monitoringu

crontab -e

# Dodaj:
*/5 * * * * ~/status-check.sh >> ~/monitoring.log 2>&1

🎓 Podsumowanie dla Juniora

Co osiągnąłeś z Traefik:

Zaawansowany reverse proxy
Service discovery
Dashboard do monitorowania
Load balancing
Middleware (CORS, Auth, Rate limiting)
Automatyczne SSL
Metryki i monitoring

Kompetencje DevOps które nabyłeś:

  • Docker/Podman - konteneryzacja
  • Traefik - advanced reverse proxy
  • YAML - konfiguracja infrastructure as code
  • SSL/TLS - zarządzanie certyfikatami
  • Monitoring - Prometheus + Grafana
  • CI/CD - GitHub Actions
  • Networking - Docker networks
  • Security - middleware, fail2ban

Następne kroki:

  1. Kubernetes - orkiestracja kontenerów
  2. Helm Charts - pakiety Kubernetes
  3. ArgoCD - GitOps deployment
  4. Service Mesh - Istio/Linkerd
  5. Observability - ELK Stack

💸 Koszt całego setup-u

Komponent Koszt/miesiąc
VPS Basic 2 EUR
Domena ~1 EUR
Łącznie ~3 EUR

Za cenę kawy masz:

  • Professional deployment setup
  • Dashboard monitoring
  • Automatic SSL
  • Load balancing
  • CI/CD ready environment

🆚 Ostateczne porównanie

Traefik - 80 linii kodu, ale potężny!

✅ Enterprise-grade features
✅ Scalable architecture  
✅ Rich ecosystem
⚠️ Steep learning curve
⚠️ More complex setup

Caddy - 30 linii kodu, ale prosty!

✅ Zero-config SSL
✅ Simple setup
✅ Perfect for small projects
⚠️ Limited advanced features
⚠️ Manual service discovery

Verdict dla Juniora:

  • Start z Caddy - naucz się podstaw
  • Przejdź na Traefik - gdy potrzebujesz więcej

Oba są świetne! Wybór zależy od potrzeb projektu! 🚀


🎉 Gratulacje!

Właśnie opanowałeś jeden z najpopularniejszych narzędzi DevOps! Traefik to standard w wielu firmach technologicznych.

Jesteś gotowy na:

  • Mid-level DevOps positions
  • Microservices architecture
  • Cloud-native development
  • Kubernetes orchestration

Keep learning! 🚀


Bezpieczeństwo dashboardu Traefik w produkcji

Dashboard Traefika w środowisku produkcyjnym jest domyślnie zabezpieczony hasłem (basic auth):

  • Dostęp do panelu jest możliwy tylko przez domenę traefik.devopsterminal.com po HTTPS.
  • Do logowania wymagany jest login i hasło (domyślnie: admin / changeme).
  • Hasło jest przechowywane jako hash bcrypt w labelu:
    - "traefik.http.middlewares.auth.basicauth.users=admin:$$2y$$05$$5HXxP9X8wJqTgYz5jK5u8uJq5VZ5QkXJ5zQ9X8wJqTgYz5jK5u8uJ"
  • Middleware auth jest przypisany tylko do dashboardu, nie do backendów.

Jak zmienić hasło?

  1. Wygeneruj nowy hash bcrypt (np. na https://bcrypt-generator.com/).
  2. Podmień wartość labela w docker-compose.prod.yml:
    - "traefik.http.middlewares.auth.basicauth.users=admin:<nowy_hash>"
  3. Zrestartuj stack (make restart-prod lub przez systemd).

Uwaga:

  • Nie udostępniaj dashboardu publicznie bez hasła!
  • Możesz dodatkowo ograniczyć dostęp po adresie IP lub przez VPN, dodając kolejne middleware.

About

🔧 Tutorial Deployment Flask z Podman + Traefik - Jak używać Traefik jako zaawansowanego reverse proxy Jak konfigurować service discovery Jak używać labels w kontenerach Jak monitorować aplikacje przez dashboard

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published