Aplikacja i baza w Docker Compose
Połączysz orders-api z PostgreSQL przez nazwę usługi i poczekasz na gotowość bazy.
1. Krótka teoria
Docker Compose opisuje kilka powiązanych usług w jednym pliku YAML. Usługa orders-api buduje obraz aplikacji, a app-db uruchamia PostgreSQL. Compose tworzy wspólną sieć projektu, w której nazwa usługi app-db rozwiązuje się przez DNS. Wewnątrz orders-api adres localhost oznacza samą aplikację, nie bazę. Łańcuch połączenia powinien wskazywać app-db:5432, a nie port opublikowany na hoście. Zwykle publikuje się tylko port aplikacji; dane bazy trafiają na nazwany volume. depends_on w prostym wariancie ustala kolejność tworzenia usług, ale nie gwarantuje gotowości bazy. Dopiero healthcheck i warunek service_healthy opóźniają utworzenie aplikacji do czasu poprawnego testu pg_isready. Aplikacja i tak powinna obsługiwać późniejsze zerwania połączenia. Plik orders-api.env może zawierać DATABASE_URL wskazujący app-db:5432. Pliki env zawierające dane dostępowe trzymaj poza kontrolą wersji i ogranicz uprawnienia. docker compose down usuwa kontenery i sieć projektu, ale bez -v pozostawia nazwany volume.
2. Przykłady komend
cat compose.yaml
Pokazuje układ dwóch usług, healthcheck i nazwany volume.
services:
orders-api:
build: .
ports:
- '127.0.0.1:8000:8000'
env_file: ./orders-api.env
depends_on:
app-db:
condition: service_healthy
app-db:
image: postgres:17
env_file: ./orders-db.env
volumes:
- app-db-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
interval: 10s
timeout: 5s
retries: 5
volumes:
app-db-data:
docker compose up -d --build
Buduje obraz aplikacji i uruchamia usługi opisane w compose.yaml.
$ docker compose up -d --build
docker compose ps
Pokazuje stan obu usług i wynik healthcheck.
$ docker compose ps
docker compose logs --tail 50 app-db
Czyta komunikaty bazy w projekcie Compose.
$ docker compose logs --tail 50 app-db
docker compose exec app-db pg_isready -U orders -d orders
Sprawdza gotowość bazy z jej kontenera.
$ docker compose exec app-db pg_isready -U orders -d orders
docker compose exec orders-api python -c "import socket; print(socket.gethostbyname('app-db'))"
Potwierdza rozwiązywanie nazwy usługi bazy z aplikacji.
$ docker compose exec orders-api python -c "import socket; print(socket.gethostbyname('app-db'))"
docker compose down
Usuwa kontenery i sieć projektu, zachowując nazwany volume.
$ docker compose down
3. Zadanie praktyczne
compose.yaml z usługami orders-api i app-db. Dla bazy dodaj volume app-db-data oraz healthcheck z pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}. Przy aplikacji ustaw zależność od bazy z warunkiem service_healthy. W nieśledzonym orders-api.env ustaw adres bazy z hostem app-db. Udostępnij na hoście tylko port aplikacji. Po uruchomieniu sprawdź stan usług, DNS z aplikacji i połączenie z bazą; po docker compose down potwierdź obecność volume.
4. Typowe błędy
- Używanie localhost w aplikacji jako adresu osobnego kontenera bazy.
- Zakładanie, że samo depends_on czeka na gotowość PostgreSQL.
- Publikowanie portu 5432 bez potrzeby.
- Dodawanie plików env z hasłem do repozytorium.
- Przekonanie, że healthcheck zastępuje obsługę utraty połączenia w aplikacji.
5. Podsumowanie
Compose opisuje aplikację i bazę jako usługi. Ich wspólna sieć zapewnia adresowanie po nazwie, healthcheck pomaga przy starcie, a volume utrzymuje dane. Aplikacja musi również reagować na awarie bazy po uruchomieniu.