Nasadenie WordPress aplikácie do produkcie pomocou Docker Compose

produkčné nasadenie

Lokálny docker-compose up nestačí.

Produkčné nasadenie znamená:

  • Verejne dostupná aplikácia
  • HTTPS
  • Z9skanie a automatická obnova certifikátov
  • Oddelené služby
  • Zálohovanie
  • Monitoring
  • Logovanie
  • Bezpečnosť

Čo je reverzné proxy?

Reverzné proxy je server, ktorý:

  • prijíma požiadavky z internetu
  • preposiela ich interným službám
  • vracia odpoveď klientovi

Prečo reverzné proxy?

  • Ukončuje HTTPS
  • Presmerovanie HTTP → HTTPS
  • Load balancing
  • Rate limiting
  • Security headers

Čo je Load Balancing?

Load balancing je:

  • Rozdeľovanie prichádzajúcich požiadaviek medzi viac backend serverov.

Cieľom je:

  • zvýšiť dostupnosť (High Availability)
  • zvýšiť výkon
  • odstrániť single point of failure
  • umožniť horizontálne škálovanie

Prečo používať Nginx?

  • vysoký výkon (event-driven architektúra)
  • nízka spotreba pamäte
  • stabilita
  • jednoduchá konfigurácia
  • podpora HTTPS

Alternatíva – Traefik

Traefik:

  • automaticky vydáva Let's Encrypt
  • nepotrebuje samostatný certbot
  • auto service discovery
  • jednoduchšia konfigurácia

Vhodné pre:

  • viac webov na jednom serveri
  • dynamické prostredie

Digitálny certifikát

HTTPS = HTTP + TLS šifrovanie

HTTPS zabezpečuje:

  • šifrovanie komunikácie
  • integritu dát
  • overenie identity servera

Digitálny certifikát obsahuje:

  • doménu (napr. example.com)
  • verejný kľúč
  • vydavateľa (CA – Certificate Authority)
  • dobu platnosti 90 dní
  • digitálny podpis CA

Prečo je povinné v produkcii?

  • bezpečnostná politika prehliadačov
  • ochrana dát používateľov, cookies a session
  • SEO (Google zvýhodňuje HTTPS)

Kto vydáva certifikáty?

  • Let’s Encrypt
  • DigiCert
  • GlobalSign
  • Sectigo

Let’s Encrypt

Let’s Encrypt je:

bezplatná, automatizovaná certifikačná autorita (CA)

Overenie domény (challenge)

Najčastejšie:

  • HTTP-01 (cez web server)
  • DNS-01 (cez DNS záznam)

Čo je Certbot?

nástroj na získanie a obnovu certifikátov z Let’s Encrypt.

  • požiada o certifikát
  • overí vlastníctvo domény
  • uloží certifikát
  • obnovuje ho automaticky

Príklad produkčnej konfigurácie

services:
                          INTERNET
                              │  HTTPS (443)
                              ▼
                     ┌───────────────────┐
                     │       NGINX       │
                     │  Reverse Proxy    │
                     │  SSL Termination  │
                     └─────────┬─────────┘
                               │  internal network
                               ▼
                     ┌───────────────────┐
                     │    WORDPRESS      │
                     │    (php-fpm)      │
                     └─────────┬─────────┘
                               │  internal network
                               ▼
                     ┌───────────────────┐
                     │      MARIADB      │
                     │    Database       │
                     └───────────────────┘
  wordpress:
    image: wordpress:php8.2-fpm
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: ${MYSQL_USER}
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
      WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
    volumes:
      - wp_data:/var/www/html
    depends_on:
      - db
  db:
    image: mariadb:10.6
    restart: always
    env_file: .env
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
  nginx:
    image: nginx:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wp_data:/var/www/html
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./certbot/www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    depends_on:
      - wordpress
    networks:
      - internal
      - public
  certbot:
    image: certbot/certbot:latest
    volumes:
      - certbot_conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    entrypoint: /bin/sh -c "trap exit TERM; while :; do certbot renew --quiet; sleep 12h & wait $${!}; done"
volumes:
  db_data:
  wp_data:
  certbot_conf:

networks:
  internal:
  public:

Nginx konfigurácia

nginx/conf.d/wordpress.conf

server {
    listen 80;
    server_name example.com www.example.com;
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /var/www/html;
    index index.php;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_pass wordpress:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Let's Encrypt + Certbot

Vydanie certifikátu

Spustíme jednorazovo:

docker run --rm \
  -v $(pwd)/certbot/conf:/etc/letsencrypt \
  -v $(pwd)/certbot/www:/var/www/certbot \
  certbot/certbot certonly \
  --webroot \
  --webroot-path=/var/www/certbot \
  -d example.com -d www.example.com \
  --email admin@example.com \
  --agree-tos

Automatická obnova

Cron job (uložený do /etc/cron.d/certbot-renew):

0 3 * * * root \
  /usr/bin/docker run --rm \
  -v /path/certbot/conf:/etc/letsencrypt \
  -v /path/certbot/www:/var/www/certbot \
  certbot/certbot renew --quiet && \
  /usr/bin/docker compose -f /path/docker-compose.yml restart nginx

Monitoring a sledovanie metrík

Čo je monitoring?

Neustále sledovanie stavu aplikácie, infraštruktúry a služieb.

Cieľ:

  • rýchlo odhaliť problém
  • minimalizovať downtime
  • predchádzať výpadkom

Bez monitoringu nevieme, že disk je plný, že certifikát expiroval, že databáza padla, že web vracia 500 chyby ...

Čo musíme monitorovať?

  • HW : CPU, RAM, Disk
  • SW: Docker (stav kontajnerov, reštarty)
  • Aplikácia: HTTP 5xx chyby, response time, dostupnosť (uptime)

Čo je Grafana?

Grafana je:

  • Vizualizačný a alertovací nástroj pre metriky a logy.

Používa sa na:

  • tvorbu dashboardov
  • vizualizáciu dát z Prometheus, Loki, Elasticsearch…
  • nastavovanie alertov
  • sledovanie stavu aplikácií v reálnom čase

Čo je Prometheus?

  • open-source systém na zber, ukladanie a vyhodnocovanie metrík.
  • Exportéry sprístupnia metriky cez HTTP endpoint (/metrics)
  • Prometheus ich v pravidelných intervaloch sťahuje
  • Ukladá ich do vlastnej časovej databázy (time-series DB)

Čo je to metrika:

Každá metrika má:

  • názov
  • hodnotu
  • časovú značku
  • štítky (napr. container="wordpress")

Sledovanie metrík

Prometheus má vlastný jazyk: Query jazyk – PromQL

Príklad:

  • výpočet počtu HTTP požiadaviek za posledných 5 minút
  • filtrovanie podľa labelov
  • výpočty percent, priemerov, percentilov

Monitoring WordPress s Grafanou

Cieľ: sledovať stav servera, Docker kontajnerov a WordPress aplikácie.

Stack:

  • Prometheus – zbiera metriky
  • Grafana – vizualizuje metriky
  • node-exporter – metriky servera (CPU, RAM, disk)
  • cAdvisor – metriky Docker kontajnerov

Rozšírenie docker-compose.yml o monitoring

  node-exporter:
    image: prom/node-exporter:latest
    restart: always
    pid: host
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    restart: always
    privileged: true
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
  prometheus:
    image: prom/prometheus:latest
    restart: always
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
  grafana:
    image: grafana/grafana:latest
    restart: always
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
    depends_on:
      - prometheus

Zálohovanie

Cieľom je ochrana pred:

  • hardvérovou chybu
  • chybou konfigurácie
  • kybernetickým útokom
  • ľudskou chybou

Stratégie zálohovania:

  • "horúca záloha" : menej bezpečná, rýchla na vykonanie aj na obnovenie (napr. kopírovnaie na pripojený disk)
  • "studená záloha" : bezpečnejšia a pomalšia. Napr. (kopírovanie na pásku alebo CD a odloženie média do trezora)

Záloha databázy

docker compose exec db \
  mysqldump -u root -p wordpress > backup.sql

Automatizácia pomocou backup kontajnera:

backup:
  image: mariadb:10.6
  env_file: .env
  volumes:
    - ./backups:/backups
  networks:
    - internal
  entrypoint: >
    sh -c "mysqldump -h db -u root -p$$MYSQL_ROOT_PASSWORD $$MYSQL_DATABASE
    > /backups/backup_$$(date +%F).sql"
  depends_on:
    - db

Záver

Nasadenie WordPress do produkcie nie je len:

docker compose up -d

Je to:

  • architektúra
  • bezpečnosť
  • zálohovanie
  • monitoring
  • automatizácia
  • prevádzka
Reload?