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 .env sú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?

  • services definuje jednotlivé kontajnery
  • db používa hotový obraz z Docker Hub
  • web sa zostavuje z lokálneho Dockerfile
  • depends_on zabezpečí správne poradie spustenia
  • volumes zabezpeč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ť .env sú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.

Previous Post Next Post

Týždeň 4: Viackontajnerová aplikácia pomocou Docker Compose