Týždeň 4: Viackontajnerová aplikácia pomocou Docker Compose
Naučíte sa:
- Definovať viackontajnerovú aplikáciu pomocou
docker compose - Prepojiť služby pomocou internej siete
- Použiť premenné prostredia a
.envsúbor - Využiť volume na perzistenciu dát
- Konfigurovať aplikáciu bez úpravy zdrojového kódu
Teoretický úvod
V predchádzajúcom cvičení sme vytvorili vlastný Docker obraz a spustili jeden kontajner pomocou príkazu docker run. Takýto prístup je vhodný pre jednoduché aplikácie, ktoré pozostávajú z jednej služby.
V praxi však aplikácie zvyčajne pozostávajú z viacerých častí:
- webová aplikácia
- databáza
- cache (napr. Redis)
- reverzný proxy server
- a ďalšie služby
Spúšťať každú službu samostatne pomocou docker run by bolo neprehľadné a náročné na údržbu.
Na tento účel existuje Docker Compose.
Docker Compose umožňuje:
- definovať viacero služieb v jednom súbore (
docker-compose.yml) - automaticky vytvoriť internú sieť medzi službami
- spravovať volumes
- používať premenné prostredia
- spustiť celú aplikáciu jedným príkazom
V tomto cvičení si vytvoríme jednoduchú aplikáciu pozostávajúcu z:
- Flask webovej aplikácie
- PostgreSQL databázy
Webová aplikácia bude ukladať počet návštev do databázy.
Architektúra aplikácie
Používateľ (prehliadač)
↓
web (Flask)
↓
db (PostgreSQL)
Služby budú komunikovať cez internú Docker sieť.
Názov služby v Compose sa automaticky stáva jej DNS menom.
1. Vytvorenie aplikácie
Najprv si pripravíme jednoduchú Flask aplikáciu, ktorá:
- pripojí sa k databáze
- vytvorí tabuľku (ak neexistuje)
- pri každej návšteve zvýši počítadlo
- zobrazí počet návštev
Vytvorte súbor app.py:
import os
import psycopg2
from flask import Flask
app = Flask(__name__)
DB_HOST = os.getenv("DB_HOST", "db")
DB_NAME = os.getenv("POSTGRES_DB", "appdb")
DB_USER = os.getenv("POSTGRES_USER", "appuser")
DB_PASS = os.getenv("POSTGRES_PASSWORD", "secret")
APP_MESSAGE = os.getenv("APP_MESSAGE", "Hello from Docker Compose!")
def get_connection():
return psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASS
)
@app.route("/")
def index():
conn = get_connection()
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS visits (
id SERIAL PRIMARY KEY
);
""")
cur.execute("INSERT INTO visits DEFAULT VALUES;")
conn.commit()
cur.execute("SELECT COUNT(*) FROM visits;")
count = cur.fetchone()[0]
cur.close()
conn.close()
return f"<h1>{APP_MESSAGE}</h1><p>Počet návštev: {count}</p>"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
2. Definovanie závislostí
Vytvorte súbor requirements.txt:
Flask==3.0.2
psycopg2-binary==2.9.9
3. Príprava Docker obrazu pre web službu
Teraz vytvoríme Dockerfile, ktorý pripraví obraz našej aplikácie.
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
Tento obraz:
- používa oficiálny Python image
- nainštaluje závislosti
- skopíruje aplikáciu
- spustí Flask server
4. Definovanie viacerých služieb pomocou Docker Compose
Teraz vytvoríme súbor docker-compose.yml.
version: "3.9"
services:
db:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
environment:
DB_HOST: db
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
APP_MESSAGE: ${APP_MESSAGE}
restart: always
volumes:
db_data:
Čo sa tu deje?
servicesdefinuje jednotlivé kontajnerydbpoužíva hotový obraz z Docker Hubwebsa zostavuje z lokálneho Dockerfiledepends_onzabezpečí správne poradie spusteniavolumeszabezpečuje perzistenciu dát${PREMENNA}znamená, že hodnota sa načíta z.env
5. Konfigurácia pomocou premenných prostredia
Vytvorte súbor .env:
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=supersecret
APP_MESSAGE=Ahoj zo sveta Docker Compose!
Docker Compose automaticky načíta tento súbor.
Výhodou je, že:
- konfiguráciu môžeme meniť bez úpravy kódu
- rovnaký Compose súbor môžeme použiť v rôznych prostrediach
6. Spustenie celej aplikácie
Zostavenie a spustenie:
docker compose up --build
Spustenie na pozadí:
docker compose up -d --build
Overenie stavu:
docker compose ps
Zobrazenie logov:
docker compose logs -f
7. Testovanie aplikácie
Otvorte prehliadač:
http://localhost:5000
Obnovte stránku niekoľkokrát.
Počet návštev sa bude zvyšovať.
8. Overenie perzistencie dát
Zastavte aplikáciu:
docker compose down
Znovu ju spustite:
docker compose up -d
Počet návštev zostane zachovaný.
Je to preto, že používame named volume:
volumes:
- db_data:/var/lib/postgresql/data
Ak by ste použili:
docker compose down -v
volume sa vymaže a databáza sa inicializuje nanovo.
9. Zmena konfigurácie bez rebuild
Zmeňte hodnotu v .env:
APP_MESSAGE=Nová správa z prostredia!
Potom reštartujte iba web službu:
docker compose up -d --build web
Aplikácia zobrazí novú správu bez zmeny zdrojového kódu.
10. Užitočné príkazy
Zastavenie:
docker compose down
Spustenie príkazu v bežiacom kontajneri:
docker compose exec db psql -U appuser -d appdb
Škálovanie služby:
docker compose up --scale web=3
Zhrnutie
V tomto cvičení ste sa naučili:
- vytvoriť viackontajnerovú aplikáciu
- používať Docker Compose
- prepájať služby cez internú sieť
- používať
.envsúbor - pracovať s volumes
- konfigurovať aplikáciu pomocou premenných prostredia
Docker Compose výrazne zjednodušuje vývoj aj testovanie komplexných aplikácií a umožňuje reproducibilné prostredie jedným príkazom.