Docker Compose dla lokalnych stosów
Uruchom lokalnie PHP, bazę danych i pamięć podręczną razem
Docker Compose dla lokalnych stosów to bezpłatna lekcja PHP Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej PHP Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs PHP Academy zawiera 4 lekcji w sumie.
Lokalne stosy z Compose
Rzeczywiste aplikacje PHP nigdy nie składają się wyłącznie z PHP — potrzebują bazy danych, pamięci podręcznej, a czasami także kolejki i narzędzia do przechwytywania poczty. Docker Compose definiuje wszystkie te elementy jako usługi w jednym pliku i łączy je we wspólnej sieci, dzięki czemu mogą docierać do siebie po nazwach.
W tej lekcji zostanie zbudowany kompletny lokalny stos: PHP-FPM + nginx + MySQL + Redis, z wolumenami, kontrolami zdrowia i kolejnością zależności.
Szkielet usług
Plik Compose wymienia usługi pod sekcją services:. Każda z nich może być zbudowana na podstawie Dockerfile za pomocą build albo może pobierać obraz za pomocą image. Compose tworzy domyślną sieć, w której każda usługa jest dostępna pod swoim kluczem — aplikacja PHP łączy się z MySQL przez host db, a nie przez localhost.
services:
app:
build:
context: .
target: dev # multi-stage dev target
volumes:
- ./:/app # live code mount
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.4
redis:
image: redis:7-alpinenginx przed FPM
FPM używa protokołu FastCGI na porcie 9000, a nie HTTP. nginx obsługuje żądania HTTP i przekazuje żądania .php do app:9000. Konfiguracja nginx odwołuje się do usługi PHP za pomocą jej nazwy w Compose.
# docker/nginx/default.conf
server {
listen 80;
root /app/public;
index index.php;
location / {
try_files $uri /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000; # service name from compose
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}Konfigurowanie usługi WWW
Usługa nginx montuje ten sam kod, aby rozwiązać SCRIPT_FILENAME, a także montuje konfigurację, publikuje port 80 i zależy od app. Obie usługi współdzielą /app, aby ścieżki po obu stronach FastCGI się zgadzały.
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
volumes:
- ./:/app:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- appTrwałe wolumeny
Systemy plików kontenerów są nietrwałe. Wolumeny nazwane zachowują pliki bazy danych po wykonaniu docker compose down. Montowania bind (./:/app) synchronizują kod z hosta na bieżąco podczas pracy deweloperskiej. Wolumenów nazwanych należy używać dla danych wymagających trwałości, a montowań bind dla kodu źródłowego.
services:
db:
image: mysql:8.4
environment:
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootsecret
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata: # survives `down`, removed only by `down -v`Healthchecki i depends_on
Samo depends_on czeka tylko na uruchomienie kontenera, a nie na to, aż MySQL zacznie przyjmować połączenia. Należy dodać healthcheck i użyć condition: service_healthy, aby aplikacja czekała, aż baza danych będzie faktycznie gotowa.
services:
db:
image: mysql:8.4
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-prootsecret"]
interval: 5s
timeout: 3s
retries: 10
app:
build: .
depends_on:
db:
condition: service_healthy # waits for healthcheck passŚrodowisko i .env
Compose automatycznie wczytuje sąsiedni plik .env na potrzeby interpolacji zmiennych, a konfigurację aplikacji przekazuje się za pomocą environment lub env_file. Sekretów nie należy umieszczać w zatwierdzonym pliku Compose; zamiast tego należy odwoływać się do zmiennych.
services:
app:
build: .
env_file:
- .env
environment:
DATABASE_URL: "mysql://app:secret@db:3306/app"
REDIS_URL: "redis://redis:6379"
# .env (gitignored) provides ${...} substitutions
# MYSQL_PASSWORD=secretŁączenie z poziomu PHP
Wewnątrz sieci nazwami hostów są nazwy usług. Kod PHP łączy się bezpośrednio z db i redis. Ten fragment parsuje DSN tak, jak zrobiłaby to warstwa konfiguracji, pokazując, jak nazwa usługi Compose trafia do parametrów połączenia.
<?php
$dsn = 'mysql://app:secret@db:3306/app';
$p = parse_url($dsn);
printf("driver: %s\n", $p['scheme']);
printf("host: %s\n", $p['host']); // 'db' resolves via compose DNS
printf("port: %d\n", $p['port']);
printf("db: %s\n", ltrim($p['path'], '/'));
$pdoDsn = sprintf('mysql:host=%s;port=%d;dbname=%s', $p['host'], $p['port'], ltrim($p['path'], '/'));
echo $pdoDsn . PHP_EOL;
?>Xdebug w lokalnym środowisku
Konfigurację Xdebug należy montować tylko lokalnie, za pomocą celu budowania dev. Wartość client_host należy ustawić na host.docker.internal, aby debugger mógł dotrzeć do IDE na hoście. Xdebug nigdy nie powinien trafiać na produkcję — bardzo obniża wydajność.
; docker/php/xdebug.ini (mounted only in dev)
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003Uruchamianie poleceń jednorazowych
docker compose run uruchamia tymczasowy kontener na potrzeby migracji, testów lub Composera, natomiast exec wykonuje polecenie wewnątrz już działającej usługi. Do takich zadań należy używać run --rm, aby tymczasowy kontener został posprzątany.
# Run migrations against the running db
docker compose exec app php bin/console doctrine:migrations:migrate
# One-off: install deps without a long-lived container
docker compose run --rm app composer install
# Tail logs of just the web service
docker compose logs -f webPliki override
Compose automatycznie łączy plik docker-compose.yml z plikiem docker-compose.override.yml. Domyślne ustawienia zbliżone do produkcyjnych należy trzymać w pliku bazowym, a wolumeny, porty i Xdebug używane tylko lokalnie umieścić w pliku override — dzięki temu CI korzysta z pliku bazowego, a deweloperzy automatycznie otrzymują dodatkowe elementy.
# docker-compose.override.yml (auto-merged, dev only)
services:
app:
volumes:
- ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini:ro
environment:
APP_ENV: dev
# CI runs: docker compose -f docker-compose.yml up (no override)Szybkie sprawdzenie
Dlaczego samo depends_on: [db] nie wystarcza przed uruchomieniem migracji?
Podsumowanie
Złożono lokalny stos za pomocą Compose: PHP-FPM za nginx, przekazujący żądania FastCGI do app:9000, MySQL i Redis dostępne pod nazwami usług, wolumeny nazwane zapewniające trwałość danych, kontrole zdrowia warunkujące depends_on, konfigurację opartą na zmiennych środowiskowych, Xdebug w nadpisaniu używanym tylko lokalnie oraz polecenia jednorazowe uruchamiane przez run/exec.
Warto pamiętać: nazwy usług są nazwami hostów DNS, pliki override pozwalają trzymać dodatkowe elementy deweloperskie poza CI, a kontrole zdrowia są lepsze niż naiwne ustalanie kolejności uruchamiania.
Często zadawane pytania
Czy lekcja „Docker Compose dla lokalnych stosów” jest bezpłatna?
Tak — pełny tekst „Docker Compose dla lokalnych stosów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu PHP Academy, przejdź na CoddyKit PRO. Kurs PHP Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Docker Compose dla lokalnych stosów”?
Uruchom lokalnie PHP, bazę danych i pamięć podręczną razem Ćwiczysz PHP Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć PHP Academy?
Nie wymagamy żadnego doświadczenia. PHP Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Docker Compose dla lokalnych stosów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji PHP Academy?
Tak. Każda lekcja PHP Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konteneryzacja aplikacji PHP
- Kompilacje wieloetapowe i optymalizacja
- Docker Compose dla lokalnych stosów
- CI/CD z GitHub Actions