Docker Compose Implementatie op een VPS
Volledige handleiding voor het implementeren van applicaties met Docker Compose op een VPS. Van installatie tot multi-container opstellingen met netwerken en volumes.
Docker Compose Implementatie op een VPS
Docker Compose is de eenvoudigste manier om applicaties op je VPS te implementeren en te beheren. Als je op zoek bent naar de beste VPS voor Docker, bekijk dan eerst onze vergelijking. Definieer daarna je volledige stack in één bestand, implementeer met één commando en werk bij zonder downtime.
Waarom Dit Belangrijk Is
Traditionele implementaties zijn omslachtig:
- Afhankelijkheden botsen tussen applicaties
- Het “werkt op mijn machine”-syndroom
- Complexe handmatige configuratie voor elke server
- Terugdraaien vereist geluk en een gebed
Docker Compose lost dit op:
- Geïsoleerde omgevingen - Apps kunnen elkaar niet verstoren
- Reproduceerbare implementaties - Zelfde configuratie, zelfde resultaat, elke keer
- Versiebeheer - Je infrastructuur is code
- Eenvoudig terugdraaien - De vorige versie is één commando verwijderd
Vereisten
- Een VPS met Ubuntu 22.04+ (wij raden Hostinger VPS aan vanwege hun Docker-geoptimaliseerde images)
- Basiskennis van de commandoregel
- SSH-toegang tot je server
Stap 1: Docker Installeren
# Verwijder oude versies
sudo apt remove docker docker-engine docker.io containerd runc
# Installeer afhankelijkheden
sudo apt update
sudo apt install ca-certificates curl gnupg -y
# Voeg Docker's GPG-sleutel toe
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Voeg repository toe
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Installeer Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# Voeg je gebruiker toe aan de docker-groep (uitloggen/inloggen vereist)
sudo usermod -aG docker $USER
# Controleer de installatie
docker --version
docker compose version
Log uit en weer in zodat de groepswijzigingen van kracht worden.
Stap 2: Je Projectstructuur Aanmaken
mkdir -p ~/apps/myapp
cd ~/apps/myapp
Aanbevolen structuur:
myapp/
├── docker-compose.yml # Hoofd compose-bestand
├── docker-compose.prod.yml # Productie-overschrijvingen
├── .env # Omgevingsvariabelen (nooit committen!)
├── .env.example # Sjabloon voor omgevingsvariabelen
├── nginx/
│ └── nginx.conf # Aangepaste Nginx-configuratie
├── data/ # Persistente data (gitignored)
└── logs/ # Applicatielogboeken (gitignored)
Stap 3: Je Eerste docker-compose.yml Schrijven
Laten we een complete webstack implementeren:
# docker-compose.yml
services:
app:
image: node:20-alpine
working_dir: /app
volumes:
- ./src:/app
- /app/node_modules
command: npm start
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
networks:
- internal
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: myapp
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- internal
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
depends_on:
- app
restart: unless-stopped
networks:
- internal
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
command: redis-server --appendonly yes
restart: unless-stopped
networks:
- internal
volumes:
postgres_data:
redis_data:
networks:
internal:
driver: bridge
Stap 4: Omgevingsvariabelen Correct Gebruiken
Maak je .env-bestand aan:
# .env
DB_PASSWORD=your-super-secret-password-here
REDIS_PASSWORD=another-secret
API_KEY=your-api-key
Maak .env.example aan als documentatie:
# .env.example
DB_PASSWORD=
REDIS_PASSWORD=
API_KEY=
Commit .env nooit naar git! Voeg toe aan .gitignore:
echo ".env" >> .gitignore
echo "data/" >> .gitignore
echo "logs/" >> .gitignore
Stap 5: Productie-overschrijvingen
Maak een productiespecifiek bestand aan:
# docker-compose.prod.yml
services:
app:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
db:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
Implementeer met:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Stap 6: Veelgebruikte Docker Compose-commando’s
# Start alle services
docker compose up -d
# Bekijk logboeken
docker compose logs -f
# Bekijk logboeken van een specifieke service
docker compose logs -f app
# Stop alle services
docker compose down
# Stop en verwijder volumes (LET OP - verwijdert data!)
docker compose down -v
# Herbouwen en herstarten
docker compose up -d --build
# Herstart een specifieke service
docker compose restart app
# Bekijk actieve containers
docker compose ps
# Voer een commando uit in een container
docker compose exec app sh
# Bekijk resourcegebruik
docker stats
Stap 7: Implementaties Zonder Downtime
Voor updates zonder downtime:
# Haal nieuwe images op
docker compose pull
# Maak alleen gewijzigde containers opnieuw aan
docker compose up -d --no-deps app
Of gebruik rolling updates met meerdere replica’s:
services:
app:
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
Stap 8: Gezondheidscontroles
Voeg altijd gezondheidscontroles toe:
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Controleer de gezondheidsstatus:
docker compose ps
docker inspect --format='{{json .State.Health}}' container_name
Stap 9: Geheimen Beheren
Gebruik voor gevoelige gegevens Docker secrets of externe geheimenbeheerders:
services:
app:
secrets:
- db_password
- api_key
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
file: ./secrets/api_key.txt
Stap 10: Back-upstrategie
Maak een back-upscript aan:
#!/bin/bash
# backup.sh
BACKUP_DIR="/backups/$(date +%Y-%m-%d)"
mkdir -p "$BACKUP_DIR"
# Back-up van PostgreSQL
docker compose exec -T db pg_dump -U user myapp > "$BACKUP_DIR/db.sql"
# Back-up van volumes
docker run --rm \
-v myapp_postgres_data:/data:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf /backup/postgres_data.tar.gz /data
# Back-up van Redis
docker compose exec -T redis redis-cli BGSAVE
docker cp "$(docker compose ps -q redis)":/data/dump.rdb "$BACKUP_DIR/"
echo "Back-up voltooid: $BACKUP_DIR"
Praktijkvoorbeelden
WordPress met Database
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${WP_DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: ${WP_DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
volumes:
wordpress_data:
db_data:
Full-Stack JavaScript-app
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
- REACT_APP_API_URL=http://api:4000
depends_on:
- api
api:
build: ./api
ports:
- "4000:4000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: pass
POSTGRES_USER: user
POSTGRES_DB: app
redis:
image: redis:7-alpine
volumes:
- redisdata:/data
volumes:
pgdata:
redisdata:
Zelf-gehoste Git met Gitea
services:
gitea:
image: gitea/gitea:latest
ports:
- "3000:3000"
- "222:22"
volumes:
- gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=${DB_PASSWORD}
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: gitea
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: gitea
restart: unless-stopped
volumes:
gitea_data:
postgres_data:
Best Practices
- Versies van images vastleggen - Gebruik
postgres:16-alpine, nietpostgres:latest - Gebruik .env-bestanden - Houd geheimen buiten compose-bestanden (zie onze VPS-beveiligingshandleiding)
- Benoemde volumes voor data - Gebruik geen bind mounts voor databases
- Gezondheidscontroles overal - Weet wanneer services echt klaar zijn
- Resourcelimieten - Voorkom dat doorgedraaide containers je server neerhalen
- Logboeklimieten - Stel max-size in om te voorkomen dat de schijf volloopt
- Gebruik netwerken - Isoleer services die niet met elkaar hoeven te communiceren
- depends_on met condities - Wacht tot services gezond zijn, niet alleen gestart
Veelgemaakte Fouten om te Vermijden
❌ Het latest-label gebruiken - Builds worden niet-reproduceerbaar
❌ Data opslaan in containers - Data verdwijnt als de container wordt verwijderd
❌ .env-bestanden committen - Geheimen belanden voorgoed in de git-geschiedenis
❌ Geen gezondheidscontroles - depends_on wacht niet op de gereedheid van de app
❌ Logboeken negeren - Ze vullen je schijf zonder limieten
❌ Databasepoorten blootstellen - Stel alleen bloot wat externe toegang nodig heeft
❌ Draaien als root - Gebruik de USER-instructie in Dockerfiles
❌ Geen herstartbeleid - Containers komen niet terug na crashes
Debugtips
# Bekijk waarom een container mislukt
docker compose logs app --tail=100
# Open een shell in een actieve container
docker compose exec app sh
# Open een shell in een gestopte container
docker compose run app sh
# Bekijk containerdetails
docker inspect $(docker compose ps -q app)
# Controleer netwerkverbinding
docker compose exec app ping db
# Bekijk omgevingsvariabelen
docker compose exec app env
Veelgestelde Vragen
Hoeveel RAM heb ik nodig?
Voor kleine projecten is 2 GB meestal voldoende. Elke container heeft overhead, dus reken op ~100 MB per container plus de werkelijke appbehoeften. Hostinger VPS-plannen beginnen bij 4 GB, wat de meeste stacks comfortabel aankan.
Moet ik Docker Compose of Kubernetes gebruiken?
Docker Compose voor single-server implementaties (voor de meeste mensen). Kubernetes wanneer je multi-node clusters, automatisch schalen nodig hebt of een toegewijd DevOps-team hebt. Maak het niet ingewikkelder dan nodig.
Hoe werk ik een actieve applicatie bij?
# Haal de nieuwste images op
docker compose pull
# Maak gewijzigde containers opnieuw aan
docker compose up -d
Voor aangepaste builds: docker compose up -d --build
Kan ik Docker Compose gebruiken met Nginx Proxy Manager?
Ja! Stel geen poorten rechtstreeks bloot, maar zet containers op hetzelfde netwerk als NPM. Zie onze reverse proxy-handleiding.
Hoe bewaar ik data persistent?
Gebruik benoemde volumes (Docker beheert de locatie) of bind mounts (jij geeft het pad op). Benoemde volumes worden aanbevolen voor databases.
Wat is het verschil tussen up en start?
up maakt containers aan en start ze. start start alleen bestaande gestopte containers. Gebruik altijd up -d.
Volgende stappen: Stel geautomatiseerde back-ups in om je Docker-data te beschermen, en voeg monitoring toe om de containergezondheid bij te houden.
Ready to get started?
Get the best VPS hosting deal today. Hostinger offers 4GB RAM VPS starting at just $4.99/mo.
Get Hostinger VPS — $4.99/mo// up to 75% off + free domain included
// related topics
// related guides
$1 VPS Hosting 2026: Cheapest VPS Servers Starting at $1/Month
Looking for $1 VPS hosting? Compare the cheapest VPS providers starting from $1-3/month. Real specs, no hidden fees, honest reviews of budget VPS options.
tutorialCaddy Reverse Proxy Guide 2026: Automatic HTTPS Made Easy
Set up Caddy as a reverse proxy with automatic HTTPS, zero-config SSL, and simple Caddyfile syntax. Complete VPS deployment guide.
tutorialCloudflare Tunnel VPS Guide 2026: Expose Services Without Opening Ports
Set up Cloudflare Tunnel on your VPS to expose web apps securely without opening ports or revealing your server IP. Complete guide with Docker and DNS config.
tutorialCoolify VPS Setup Guide 2026: Self-Hosted Vercel Alternative
Deploy Coolify on your VPS for a self-hosted Vercel/Netlify experience. Complete setup guide with Docker, SSL, and app deployments.
Andrius Putna
I am Andrius Putna. Geek. Since early 2000 in love tinkering with web technologies. Now AI. Bridging business and technology to drive meaningful impact. Combining expertise in customer experience, technology, and business strategy to deliver valuable insights. Father, open-source contributor, investor, 2xIronman, MBA graduate.
// last updated: February 6, 2026. Disclosure: This article may contain affiliate links.