Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ services:
POSTGRES_DB: ${POSTGRES_DB:-vibestack}
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER:-postgres}"]
interval: 10s
Expand All @@ -39,6 +41,8 @@ services:
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redisdata:/data
networks:
- internal
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
Expand All @@ -57,6 +61,8 @@ services:
postgres:
condition: service_healthy
env_file: .env
networks:
- internal

web:
build:
Expand All @@ -75,8 +81,14 @@ services:
migrate:
condition: service_completed_successfully
env_file: .env
ports:
- "3001:3001"
# No host port: Traefik (Dokploy) routes to the container over
# dokploy-network using the port set in the Domain config. Publishing
# to the host would collide with other apps sharing this VPS.
expose:
- "3001"
networks:
- internal
- dokploy-network
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/api/health || exit 1"]
interval: 30s
Expand All @@ -94,8 +106,11 @@ services:
APP_PORT: 3000
restart: unless-stopped
env_file: .env
ports:
- "3000:3000"
expose:
- "3000"
networks:
- internal
- dokploy-network
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/api/health || exit 1"]
interval: 30s
Expand All @@ -120,8 +135,11 @@ services:
migrate:
condition: service_completed_successfully
env_file: .env
ports:
- "3002:3002"
expose:
- "3002"
networks:
- internal
- dokploy-network
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3002/api/health || exit 1"]
interval: 30s
Expand All @@ -136,6 +154,8 @@ services:
postgres:
condition: service_healthy
env_file: .env
networks:
- internal
volumes:
- ./scripts/backup-r2.sh:/usr/local/bin/backup-r2.sh:ro
entrypoint:
Expand All @@ -146,6 +166,16 @@ services:
echo "0 3 * * * /usr/local/bin/backup-r2.sh >> /var/log/backup.log 2>&1" | crontab -
crond -f -l 2

networks:
# Private network for app <-> postgres/redis traffic.
internal:
driver: bridge
# Dokploy's shared Traefik network. Must already exist on the host
# (created by the Dokploy install). web/marketing/admin join it so the
# reverse proxy can route the domains to them — no host ports needed.
dokploy-network:
external: true

volumes:
pgdata:
redisdata:
8 changes: 8 additions & 0 deletions docs/deploy/production-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ reports unconfigured features as `"disabled"` and still returns HTTP 200.
session cookie is host-only and admin redirect-loops. Leave it unset for
single-host or local dev.

**Networking / shared VPS:** the apps publish **no host ports** — Traefik
routes the domains to the containers over the external `dokploy-network`
(created by the Dokploy install) using the container port you set in each
service's Domain config (web 3001, marketing 3000, admin 3002). This is what
lets the stack share a VPS with other apps without port collisions. If your
Dokploy proxy network isn't named `dokploy-network`, rename it in the
`networks:` block of `docker-compose.prod.yml`.

## Required — app refuses to boot without these

| Variable | Used by | Notes |
Expand Down
Loading