Docker Compose för lokala stackar
Kör PHP, en databas och cache tillsammans lokalt.
Docker Compose för lokala stackar är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.
Lokala stackar med Compose
Riktiga PHP-appar är aldrig bara PHP – de behöver en databas, en cache, ibland en kö och en mail catcher. Docker Compose deklarerar alla dessa som tjänster i en fil och kopplar dem till ett gemensamt nätverk så att de når varandra via namn.
I den här lektionen bygger ni en komplett lokal stack: PHP-FPM + nginx + MySQL + Redis, med volymer, healthchecks och beroendeordning.
Tjänstestruktur
En Compose-fil listar tjänster under services:. Varje tjänst kan byggas med build från en Dockerfile eller hämta en image. Compose skapar ett standardnätverk där varje tjänst nås via sin nyckel – PHP-appen ansluter till MySQL via värdnamnet db, inte 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 framför FPM
FPM kommunicerar med FastCGI via port 9000, inte HTTP. nginx avslutar HTTP-anslutningen och proxar .php-förfrågningar till app:9000. nginx-konfigurationen refererar till PHP-tjänsten via dess Compose-namn.
# 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;
}
}Konfigurera webbtjänsten
nginx-tjänsten monterar samma kod (för att kunna lösa SCRIPT_FILENAME) och konfigurationen, publicerar port 80 och är beroende av appen. Båda delar /app så att sökvägarna stämmer på båda sidor av FastCGI.
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:
- appBeständiga volymer
Containerfilsystem är temporära. Namngivna volymer bevarar databasfiler mellan docker compose down. Bind mounts (./:/app) synkroniserar värddatorns kod live under utveckling. Använd namngivna volymer för tillståndsdata och bind mounts för källkod.
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`Healthchecks och depends_on
depends_on ensamt väntar bara på att containern ska starta, inte på att MySQL accepterar anslutningar. Lägg till en healthcheck och använd condition: service_healthy så att appen väntar tills databasen faktiskt är redo.
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 passMiljö och .env
Compose läser automatiskt in en syskonfil .env för variabelinterpolering, och ni skickar appkonfiguration via environment eller env_file. Håll hemligheter utanför den incheckade Compose-filen; referera i stället till variabler.
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=secretAnsluta från PHP
Inuti nätverket är värdnamnen tjänstenamn. PHP-koden ansluter direkt till db och redis. Det här utdraget tolkar en DSN på det sätt ett konfigurationslager skulle göra och visar hur Compose-tjänstens namn förs vidare till anslutningssträngen.
<?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 för lokal utveckling
Montera Xdebug-konfiguration endast lokalt (via dev-byggmålet). Ange client_host till host.docker.internal så att debuggern når IDE:n på värddatorn. Skicka aldrig Xdebug till produktion – det försämrar prestandan kraftigt.
; 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=9003Köra engångskommandon
docker compose run startar en temporär container för migreringar, tester eller Composer; exec kör inuti en redan körande tjänst. Använd run --rm för uppgifter så att den tillfälliga containern städas bort.
# 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 webOverride-filer
Compose slår automatiskt ihop docker-compose.yml med docker-compose.override.yml. Behåll produktionsliknande standardvärden i basfilen och lägg utvecklingsspecifika volymer, portar och Xdebug i override-filen – då använder CI basen och utvecklare får tilläggen automatiskt.
# 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)Snabbkontroll
Varför är en enkel depends_on: [db] otillräcklig innan migreringar körs?
Sammanfattning
Ni satte ihop en lokal stack med Compose: PHP-FPM bakom nginx (FastCGI till app:9000), MySQL och Redis nåbara via tjänstenamn, namngivna volymer för beständighet, healthchecks som styr depends_on, miljöstyrd konfiguration, Xdebug i en override endast för utveckling och engångskommandon via run/exec.
Kom ihåg: tjänstenamn är DNS-värdnamn, override-filer håller utvecklingstillägg borta från CI och healthchecks är bättre än naiv startordning.
Lär dig PHP med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 49
- Lektioner
- 195
Vanliga frågor
Är lektionen ”Docker Compose för lokala stackar” gratis?
Ja – hela texten till ”Docker Compose för lokala stackar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Docker Compose för lokala stackar”?
Kör PHP, en databas och cache tillsammans lokalt. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig PHP Academy?
Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Docker Compose för lokala stackar”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här PHP Academy-lektionen?
Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Containerisera en PHP-applikation
- Byggen i flera steg och optimering
- Docker Compose för lokala stackar
- CI/CD med GitHub Actions