-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.prod.yml
More file actions
187 lines (177 loc) · 5.1 KB
/
Copy pathdocker-compose.prod.yml
File metadata and controls
187 lines (177 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# Production stack for Dokploy / VPS deploy.
# Includes apps + Postgres + Redis + nightly R2 backup.
# Dev should use docker-compose.yml (infra only).
# NEXT_PUBLIC_* are inlined into the client bundle at build time, so they must
# be passed as build args (env_file only reaches runtime). Interpolated from
# the deploy env (Dokploy Environment tab / .env). Shared across all 3 apps.
x-public-build-args: &public-build-args
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL}
NEXT_PUBLIC_WEB_APP_URL: ${NEXT_PUBLIC_WEB_APP_URL:-}
NEXT_PUBLIC_MARKETING_URL: ${NEXT_PUBLIC_MARKETING_URL:-}
NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL:-}
NEXT_PUBLIC_POSTHOG_KEY: ${NEXT_PUBLIC_POSTHOG_KEY:-}
NEXT_PUBLIC_POSTHOG_HOST: ${NEXT_PUBLIC_POSTHOG_HOST:-}
NEXT_PUBLIC_GA_ID: ${NEXT_PUBLIC_GA_ID:-}
NEXT_PUBLIC_SENTRY_DSN: ${NEXT_PUBLIC_SENTRY_DSN:-}
NEXT_PUBLIC_BRAND_NAME: ${NEXT_PUBLIC_BRAND_NAME:-vibestack}
NEXT_PUBLIC_SUPPORT_EMAIL: ${NEXT_PUBLIC_SUPPORT_EMAIL:-}
services:
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-vibestack}
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redisdata:/data
networks:
- internal
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# Applies committed Drizzle migrations (packages/db/src/migrations), then
# idles so it stays a healthy long-running container. web/admin wait on its
# healthcheck. Generate migrations with `pnpm db:generate` and commit them.
migrate:
build:
context: .
dockerfile: docker/Dockerfile.migrate
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
env_file: .env
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "test -f /tmp/migrated"]
interval: 5s
timeout: 3s
retries: 30
start_period: 5s
web:
build:
context: .
dockerfile: docker/Dockerfile.next
args:
<<: *public-build-args
APP_NAME: web
APP_PORT: 3001
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
migrate:
condition: service_healthy
env_file: .env
# 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
timeout: 5s
retries: 3
start_period: 20s
marketing:
build:
context: .
dockerfile: docker/Dockerfile.next
args:
<<: *public-build-args
APP_NAME: marketing
APP_PORT: 3000
restart: unless-stopped
env_file: .env
expose:
- "3000"
networks:
- internal
- dokploy-network
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/api/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
admin:
build:
context: .
dockerfile: docker/Dockerfile.next
args:
<<: *public-build-args
APP_NAME: admin
APP_PORT: 3002
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
migrate:
condition: service_healthy
env_file: .env
expose:
- "3002"
networks:
- internal
- dokploy-network
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3002/api/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
backup:
image: alpine:3.20
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
env_file: .env
networks:
- internal
volumes:
- ./scripts/backup-r2.sh:/usr/local/bin/backup-r2.sh:ro
entrypoint:
- /bin/sh
- -c
- |
apk add --no-cache postgresql17-client aws-cli bash curl ca-certificates
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: