-
Notifications
You must be signed in to change notification settings - Fork 0
Docker Compose Examples
Alexander Zinchenko edited this page Jun 22, 2026
·
1 revision
services:
vpn:
image: azinchen/nordvpn-wg:latest
container_name: nordvpn
cap_add:
- NET_ADMIN
- SYS_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
environment:
- TOKEN=your_nordvpn_token_here
- COUNTRY=United States;CA;38
- CITY=New York;Los Angeles;Toronto
- RANDOM_TOP=10
- RECREATE_VPN_CRON=0 */6 * * *
- NETWORK=192.168.1.0/24
ports:
- "8080:8080"
- "3000:3000"
restart: unless-stopped
webapp:
image: nginx:alpine
container_name: webapp
network_mode: "service:vpn"
depends_on:
- vpn
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
api-service:
image: node:alpine
container_name: api-service
network_mode: "service:vpn"
depends_on:
- vpn
working_dir: /app
volumes:
- ./app:/app
command: ["npm", "start"]
restart: unless-stoppedservices:
vpn:
image: azinchen/nordvpn-wg:latest
container_name: nordvpn
cap_add:
- NET_ADMIN
- SYS_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
environment:
- TOKEN=your_nordvpn_token_here
- COUNTRY=Netherlands;DE;209
- CITY=Amsterdam;Berlin;Frankfurt
- GROUP=Standard VPN servers
- RANDOM_TOP=5
- RECREATE_VPN_CRON=0 */4 * * *
- CHECK_CONNECTION_CRON=*/5 * * * *
- CHECK_CONNECTION_URL=https://1.1.1.1;https://8.8.8.8
- NETWORK=192.168.1.0/24;172.20.0.0/16
ports:
- "8080:8080"
- "3000:3000"
- "9000:9000"
- "6379:6379"
restart: unless-stopped
webapp:
image: nginx:alpine
container_name: webapp
network_mode: "service:vpn"
depends_on:
vpn:
condition: service_healthy
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
- ./web:/usr/share/nginx/html:ro
restart: unless-stopped
api-service:
image: node:alpine
container_name: api-service
network_mode: "service:vpn"
depends_on:
- vpn
- webapp
working_dir: /app
volumes:
- ./api:/app
command: ["npm", "start"]
restart: unless-stopped
redis:
image: redis:alpine
container_name: redis
network_mode: "service:vpn"
depends_on:
- vpn
volumes:
- ./config/redis:/data
restart: unless-stopped
# Service that DOESN'T use VPN (runs on host network)
monitoring:
image: grafana/grafana:latest
container_name: monitoring
network_mode: host
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- ./config/grafana:/var/lib/grafana
restart: unless-stoppedservices:
vpn:
image: azinchen/nordvpn-wg:latest
container_name: nordvpn
cap_add:
- NET_ADMIN
- SYS_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
environment:
- TOKEN=your_nordvpn_token_here
- COUNTRY=CA;38
- CITY=Toronto;Montreal
- NETWORK=192.168.1.0/24
restart: unless-stopped
app:
image: nginx:alpine
container_name: webapp
network_mode: "service:vpn"
depends_on:
- vpn
volumes:
- ./html:/usr/share/nginx/html
restart: unless-stopped
nginx-proxy:
image: nginx:alpine
container_name: proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- vpn
restart: unless-stopped-
Ports must be published on the VPN container, not on application containers using
network_mode: "service:vpn". - Use
depends_onto ensure the VPN starts before dependent services. - Services that should not use the VPN can use
network_mode: hostor a separate Docker network. - When the VPN container restarts, all dependent containers must also be restarted. See Updating and Maintenance.
- WireGuard needs the
SYS_ADMINcapability andnet.ipv4.conf.all.src_valid_mark=1sowg-quickcan set its routing policy. If your host blocks those,privileged: trueworks as a last resort.
Configuration
- Server Selection
- Server Groups
- IPv6 Configuration
- Automatic Reconnection
- Local Network Access
- VPN Gateway Mode
- Custom DNS
- Permissions
Security
Examples
Operations
Reference