0Pricing
PHP Academy · Lekcja

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-alpine

nginx 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:
      - app

Trwał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=9003

Uruchamianie 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 web

Pliki 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

  1. Konteneryzacja aplikacji PHP
  2. Kompilacje wieloetapowe i optymalizacja
  3. Docker Compose dla lokalnych stosów
  4. CI/CD z GitHub Actions
← Powrót do PHP Academy