Table of Contents
Inleiding
Moderne webapplicaties draaien zelden als een monolithisch proces. In plaats daarvan zijn ze samengesteld uit meerdere samenwerkende diensten: een frontend, een API, een database, een cache, een boodschappenwachtrij en misschien een jobrunner. Handmatig beheren van de levenscyclus van elke container, hun netwerking, en hun afhankelijkheden wordt snel foutgevoelig en tijdrovend. Docker Compose en Nginx samen bieden een battle-geteste, productievriendelijke oplossing voor het definiëren en implementeren van deze multi-container systemen met minimale wrijving. Docker Compose kunt u uw hele applicatie stack in een YAML-bestand beschrijven, terwijl Nginx fungeert als een betrouwbare reverse proxy en load balancer, routing verkeer naar de juiste service. In deze uitgebreide gids, zullen we lopen door een realistische setup, graven in configuratie details, dekking van de beste praktijken van de veiligheid, en laat u zien hoe u van ontwikkeling tot productie te schalen.
Vereisten
Voordat u induikt, zorg ervoor dat u het volgende op uw systeem geïnstalleerd heeft:
- Doktermotor (versie 20.10 of nieuwer)
- Docker Compose (V2 is nu geïntegreerd in Docker CLI; verifieer met )
- Basisbekendheid met terminal commando's en YAML syntax.
Optioneel heb je een domeinnaam die naar je server wijst als je van plan bent de SSL configuratie sectie te volgen.
Begrijpen van de Docker Compose in Diepte
Docker Compose is niet alleen een eenvoudige . Docker run . Het is een declarative tool waarmee u diensten, netwerken, volumes, omgevingsvariabelen, herstart beleid, en gezondheidscontroles in een enkel bestand genaamd . De samenstelling specificatie (nu onderdeel van de ]Compone Specification ) standaardiseert hoe multi-container toepassingen worden beschreven, waardoor uw setup draagbaar over verschillende CI/CD pijpleidingen en cloud providers.
Diensten
Elke containerafbeelding, de poorten, volumes, omgeving en afhankelijkheden worden gedefinieerd onder de sleutel. Diensten kunnen met elkaar communiceren via een speciaal brugnetwerk dat Compose automatisch aanmaakt. Dit betekent dat je nooit hostpoorten hoeft te openen voor inter-service communicatie .Alleen de omgekeerde proxy hoeft poorten aan de buitenwereld bloot te stellen.
Netwerken
Standaard creëert Compose één netwerk voor alle diensten, waardoor ze DNS-gebaseerde service ontdekking krijgen met behulp van de servicenaam als hostnaam. Bijvoorbeeld, een service genaamd kan worden bereikt door andere diensten gewoon als . U kunt ook aangepaste netwerken voor isolatie definiëren . Bijvoorbeeld, het plaatsen van alleen de omgekeerde proxy op een openbaar-georiënteerd netwerk en het houden van database containers op een intern netwerk.
networks:
frontend:
backend:
services:
nginx:
networks:
- frontend
app:
networks:
- frontend
- backend
db:
networks:
- backend
Volumen
Volumes zijn het meest geschikte mechanisme voor het aanhouden van gegevens gegenereerd door Docker containers. In Compose, kunt u de opgegeven volumes op het hoogste niveau en mount ze in diensten. Dit is essentieel voor databases, bestand uploads, en elke stateful service.
volumes:
db_data:
services:
postgres:
image: postgres:16
volumes:
- db_data:/var/lib/postgresql/data
Milieuvariabelen
Externaliseer configuratie met omgevingsvariabelen. U kunt ze hardcoderen in het Compose bestand voor ontwikkeling, maar voor de productie moet u bestanden of Docker geheimen gebruiken. Stel automatisch een bestand samen dat zich in dezelfde map bevindt als u niet opgeeft.
services:
api:
image: my-api:latest
env_file:
- ./api.env
environment:
- NODE_ENV=production
Nginx configureren als een omgekeerde proxy
Nginx schijnt als een omgekeerde proxy vanwege zijn hoge prestaties, lage geheugenvoetafdruk en rijke functieset. In een multi-container architectuur, Nginx zit aan de rand, accepteert client verzoeken, en stuurt ze naar de juiste service op basis van de aanvraag URI, headers, of zelfs body content. Het kan ook omgaan met SSL-afgifte, caching, snelheid beperken, en het laden balanceren.
Basis Proxy omgekeerd met meerdere upstreams
Hier is een completere configuratie die laat zien hoe je het verkeer tussen twee verschillende toepassingen kunt splitsen, waaronder het verwerken van statische activa en WebSockets:
upstream app1_upstream {
server app1:8000;
}
upstream app2_upstream {
server app2:8001;
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# App 1 – main web frontend
location / {
proxy_pass http://app1_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# App 2 – admin dashboard
location /admin/ {
proxy_pass http://app2_upstream/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# WebSocket support (e.g., for live updates)
location /ws/ {
proxy_pass http://app1_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Static assets – serve directly for better performance
location /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
Let op het gebruik van blokken. Hiermee kunt u een groep servers definiëren voor het laden van balancering. Zelfs met een enkele server, maakt het met een upstream groep het gemakkelijk om later meer replica's toe te voegen zonder het serverblok aan te raken.
SSL/TLS met Let's Encrypt
Voor de productie is het bedienen van HTTPS niet onderhandelbaar. U kunt de certificaatvernieuwing automatiseren met behulp van Certbot of acme.sh in een zijspancontainer. Een gebruikelijk patroon is om de certificaten als volumes in de Nginx container te monteren. Bijvoorbeeld:
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./certs:/etc/nginx/certs:ro
- ./static:/var/www/static:ro
ports:
- "80:80"
- "443:443"
depends_on:
- app1
- app2
Voor automatische vernieuwing kunt u een metgezelcontainer toevoegen zoals of die een cron job uitvoert en Nginx herlaadt wanneer certificaten worden ververst.
Laden Balancering en gezondheidscontroles
Wanneer u een service opschaalt naar meerdere replica's, kan Nginx verzoeken verspreiden met behulp van ronde robin, de minste verbindingen, of IP hash. Combineer dit met Docker Composeer de optie :
upstream api_servers {
least_conn;
server api:80 max_fails=3 fail_timeout=30s;
}
Om ongezonde containers te detecteren, kan Nginx worden geconfigureerd met (vereist NGINX Plus of gebruik de uit de open-source versie met een kleine werkronde). Een eenvoudiger alternatief is om te vertrouwen op Dockers gezondheidscontroles en alleen containers die passeren te registreren.
Het bouwen van de Docker Bestand samenstellen . . Een voorbeeld van de echte wereld
Laten we alles combineren tot een praktisch Compose bestand voor een webapplicatie bestaande uit een Node.js API, een React frontend die wordt geserveerd door Nginx, een PostgreSQL database en een Redis cache. De Nginx container zal statische bestanden en proxy API verzoeken dienen.
version: "3.9"
services:
nginx:
image: nginx:alpine
container_name: reverse-proxy
restart: unless-stopped
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./frontend/build:/var/www/frontend:ro
- ./certs:/etc/nginx/certs:ro
ports:
- "80:80"
- "443:443"
depends_on:
- api
- frontend
networks:
- public
frontend:
image: my-frontend:latest
# In production, frontend is built into static files and served by Nginx
# This container may run a dev server, but Nginx will bypass it for static files
container_name: frontend-dev
ports:
- "3000:3000"
networks:
- public
# healthcheck: ...
api:
image: my-api:latest
container_name: api-server
restart: unless-stopped
env_file:
- ./api/.env.production
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
networks:
- public
- internal
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
interval: 30s
timeout: 10s
retries: 3
postgres:
image: postgres:16-alpine
container_name: database
restart: unless-stopped
environment:
POSTGRES_USER: app_user
POSTGRES_DB: app_db
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- pgdata:/var/lib/postgresql/data
secrets:
- db_password
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app_user"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: cache
restart: unless-stopped
volumes:
- redisdata:/data
networks:
- internal
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
volumes:
pgdata:
redisdata:
networks:
public:
internal:
internal: true
secrets:
db_password:
file: ./secrets/db_password.txt
Belangrijkste punten in dit bestand:
- Network isolatie: Het netwerk wordt gedefinieerd als , wat betekent dat alleen diensten verbonden aan het kan communiceren. De database en cache zijn niet bereikbaar van buiten de Docker overlay.
- Geheimen: Gevoelige gegevens zoals wachtwoorden worden opgeslagen als Docker-geheimen, gemonteerd als bestanden in de container. Dit voorkomt dat ze lekken in omgevingsvariabelen die kunnen worden blootgesteld via .
- Gezondheidscontroles: Diensten verklaren gezondheidscontroles zodat kan wachten op de voorwaarde ]. Nginx zal pas beginnen nadat de API gezond is.
- Statische activa: De frontend build output wordt direct in Nginx gemonteerd, zodat Nginx statische bestanden kan bedienen zonder de frontend dev server te raken. Dit verbetert de prestaties en scheidt zorgen.
Stap voor stap de toepassing inzetten .
Met het Compose-bestand en de Nginx-configuratie klaar, is implementatie gepaard gegaan met een paar eenvoudige commando's. Ten eerste, zorg ervoor dat alle configuratiebestanden op hun plaats zijn:
project/
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
├── api/
│ └── .env.production
├── frontend/
│ └── build/
├── certs/
│ └── (fullchain.pem, privkey.pem)
└── secrets/
└── db_password.txt
Dan rennen:
docker compose pull # pull latest images
docker compose up -d # start all services in background
docker compose ps # verify services are running
docker compose logs -f # tail logs for all services
Zodra alles is opgestaan, test de toepassing door een bezoek aan uw domein. Controleer Nginx logs om te bevestigen dat verzoeken correct worden weergegeven. Als u de configuratie of omgevingsvariabelen moet bijwerken, bewerk de relevante bestanden en voer:
docker compose up -d --no-deps --build nginx # rebuild only nginx if config changed
Voor uitzettingen in nul-downtime, overwegen blauwgroen of rolling updates met Composes feature en Nginx upstream health checks.
Schalen en prestatie-tunen
Docker Compose maakt het triviaal om staatloze diensten zoals de API te schalen:
docker compose up -d --scale api=3
Nu worden drie replica's van de API container uitgevoerd. Nginx, geconfigureerd met het upstream blok, zal automatisch verzoeken onder hen verdelen. Om de prestaties verder te verbeteren:
- Gzipcompressie inschakelen in Nginx voor tekstgebaseerde reacties.
- De juiste cache-headers instellen voor statische activa (zoals in het voorbeeld is aangegeven).
- Gebruik een CDN voor wereldwijde levering van statische bestanden.
- Tune Nginx-werknemer verwerkt om CPU-kernen te matchen:
- Verhoog de verbindingslimieten:
Voor databases, zorg ervoor dat u verbinding poolen in uw API en overwegen met behulp van PgBouncer als een zijspan container.
Problemen oplossen van gemeenschappelijke problemen
Zelfs met een goed gestructureerde setup, dingen kunnen mis gaan. Hier zijn frequente valkuilen en hoe ze te repareren:
- Container kan geen andere dienst bereiken bij naam: Controleer of beide diensten op hetzelfde Docker-netwerk zijn. Gebruik om te testen.
- Nginx geeft 502 Bad Gateway: De upstream container kan niet draaien of luistert niet op de verwachte poort. Controleer met ]. Zorg er ook voor dat de proxy pass URL het juiste protocol en poort bevat.
- Toestemmingsfouten met volumes: Bestanden die in containers zijn gemonteerd erven de eigenaar van de host. Gebruik gebruikersnaamruimtes of stel de richtlijn in in Nginx en de service container.
- SSL-certificaat niet vernieuwen: Als u certbot standalone gebruikt, zorg dan dat poorten 80 en 443 niet door Nginx geblokkeerd worden tijdens de vernieuwing. Gebruik een webraotmethode of certbot met docker om conflicten te voorkomen.
- Milieuvariabelen niet geladen: Controleer het bestand is op de juiste locatie of gebruik de richtlijn juist. U kunt env in de container afdrukken met .
Beste praktijken op het gebied van beveiliging
Voor het uitvoeren van multicontainertoepassingen in productie is waakzaamheid vereist:
- Laat nooit containers draaien als root tenzij noodzakelijk. Gebruik de richtlijn of geef een aan in het Dockerbestand.
- Houd afbeeldingen up-to-date met regelmatige kwetsbaarheid scannen. Gebruik officiële basisafbeeldingen en pinversies.
- Belichting van het netwerk beperken: Stel alleen de omgekeerde proxy-poorten bloot aan het internet. Alle andere diensten moeten op interne netwerken zijn.
- Gebruik geheimenbeheer voor wachtwoorden, API sleutels en tokens. Docker geheimen zijn een goede start; voor grotere setups, overwegen HashiCorp Vault.
- Laat Docker Content Trust gebruiken om de handtekeningen van de afbeelding te verifiëren.
- Regelmatig loggen en auditeren containeractiviteit met of een gecentraliseerde logoplossing zoals ELK stack.
- Toepassen van resource limits in uw Compose bestand om te voorkomen dat een enkele container uithongeren anderen:
services:
api:
deploy:
resources:
limits:
cpus: '0.50'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
Deze limieten worden gerespecteerd bij het gebruik van Docker zwerm; voor gewone Compose, worden ze afgedwongen met (hoewel het beter is om zwerm of K8s te gebruiken voor productie orkestratie).
Conclusie
Docker Compose en Nginx vormen samen een krachtig, schaalbaar en onderhoudbaar platform voor het implementeren van multi-container webapplicaties. Door het definiëren van uw stack in één YAML-bestand, bereikt u milieupariteit van ontwikkeling tot productie. Nginx, als omgekeerde proxy, biedt een centraal punt voor SSL-afgifte, verkeersrouting, load balancing en caching. We hebben de essentiële componenten behandeld: servicedefinities, netwerking, volumes, omgevingsvariabelen, Nginx-configuratie met beveiliging en prestatieoptimalisaties, schalentips en probleemoplossing. Met deze stichting bent u klaar voor architect, implementatie en gebruik van moderne containergeïnstalleerde toepassingen met vertrouwen. Raadpleeg voor meer lezen de ] Docker Compose documentatie[ en de Nginx documentatie[, en verkennen van real-world voorbeelden van Awesome Compose[ voor inspiratie.]Docker Compose documentation[[