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