main docker-compose.prod.yml
Eric Bower  ·  2026-09-12
  1services:
  2  postgres:
  3    env_file:
  4      - .env.prod
  5    volumes:
  6      - ./data/postgres-data:/var/lib/postgresql/data
  7    ports:
  8      - "5432:5432"
  9    command: -N 1024 -B 4096MB
 10  valkey:
 11    image: valkey/valkey:9.0-alpine3.24
 12    restart: always
 13    env_file:
 14      - .env.prod
 15    volumes:
 16      - ./data/valkey-data:/data
 17    ports:
 18      - "6379:6379"
 19    command: valkey-server --appendonly yes --requirepass "${VALKEY_PASSWORD}"
 20    networks:
 21      - default
 22      - pgs
 23  pipemgr:
 24    env_file:
 25      - .env.prod
 26    volumes:
 27      - ./data/pipemgr/data/term_info_ed25519:/key:ro
 28      - ./data/pipemgr/data/term_info_ed25519-cert.pub:/key-cert.pub:ro
 29    logging:
 30      driver: "json-file"
 31      options:
 32        max-file: "3"
 33        max-size: "1024m"
 34  imgproxy:
 35    env_file:
 36      - .env.prod
 37    volumes:
 38      - ./data/storage:/storage
 39    networks:
 40      prose:
 41      pgs:
 42  auth-web:
 43    logging:
 44      driver: "json-file"
 45      options:
 46        max-file: "3"
 47        max-size: "1024m"
 48  pastes-caddy:
 49    image: ghcr.io/picosh/pico/caddy:latest
 50    restart: always
 51    networks:
 52      - pastes
 53    env_file:
 54      - .env.prod
 55    environment:
 56      APP_DOMAIN: ${PASTES_DOMAIN:-pastes.sh}
 57      APP_EMAIL: ${PASTES_EMAIL:-hello@pico.sh}
 58    volumes:
 59      - ${PASTES_CADDYFILE}:/etc/caddy/Caddyfile
 60      - ./data/pastes-caddy/data:/data
 61      - ./data/pastes-caddy/config:/config
 62    ports:
 63      - "${PASTES_HTTPS_V4:-443}:443"
 64      - "${PASTES_HTTP_V4:-80}:80"
 65      - "${PASTES_HTTPS_V6:-[::1]:443}:443"
 66      - "${PASTES_HTTP_V6:-[::1]:80}:80"
 67    profiles:
 68      - pastes
 69      - caddy
 70      - all
 71    logging:
 72      driver: "json-file"
 73      options:
 74        max-file: "3"
 75        max-size: "1024m"
 76  pastes-web:
 77    dns: 1.1.1.1
 78    networks:
 79      pastes:
 80        aliases:
 81          - web
 82    env_file:
 83      - .env.prod
 84    volumes:
 85      - ./data/pastes-ssh/data:/app/ssh_data
 86  pastes-ssh:
 87    networks:
 88      pastes:
 89        aliases:
 90          - ssh
 91    env_file:
 92      - .env.prod
 93    volumes:
 94      - ./data/pastes-ssh/data:/app/ssh_data
 95    ports:
 96      - "${PASTES_SSH_V4:-22}:2222"
 97      - "${PASTES_SSH_V6:-[::1]:22}:2222"
 98  pipe-caddy:
 99    image: ghcr.io/picosh/pico/caddy:latest
100    restart: always
101    networks:
102      - pipe
103    env_file:
104      - .env.prod
105    environment:
106      APP_DOMAIN: ${PIPE_DOMAIN:-pipe.pico.sh}
107      APP_EMAIL: ${PIPE_EMAIL:-hello@pico.sh}
108    volumes:
109      - ${PIPE_CADDYFILE}:/etc/caddy/Caddyfile
110      - ./data/pipe-caddy/data:/data
111      - ./data/pipe-caddy/config:/config
112    ports:
113      - "${PIPE_HTTPS_V4:-443}:443"
114      - "${PIPE_HTTP_V4:-80}:80"
115      - "${PIPE_HTTPS_V6:-[::1]:443}:443"
116      - "${PIPE_HTTP_V6:-[::1]:80}:80"
117    profiles:
118      - pipe
119      - caddy
120      - all
121  pipe-web:
122    networks:
123      pipe:
124        aliases:
125          - web
126    env_file:
127      - .env.prod
128    volumes:
129      - ./data/pipe-ssh/data:/app/ssh_data
130  pipe-ssh:
131    networks:
132      pipe:
133        aliases:
134          - ssh
135    env_file:
136      - .env.prod
137    volumes:
138      - ./data/pipe-ssh/data:/app/ssh_data
139    ports:
140      - "${PIPE_SSH_V4:-22}:2222"
141      - "${PIPE_SSH_V6:-[::1]:22}:2222"
142  prose-caddy:
143    image: ghcr.io/picosh/pico/caddy:latest
144    restart: always
145    networks:
146      - prose
147    env_file:
148      - .env.prod
149    environment:
150      APP_DOMAIN: ${PROSE_DOMAIN:-prose.sh}
151      APP_EMAIL: ${PROSE_EMAIL:-hello@pico.sh}
152    volumes:
153      - ${PROSE_CADDYFILE}:/etc/caddy/Caddyfile
154      - ./data/prose-caddy/data:/data
155      - ./data/prose-caddy/config:/config
156    labels:
157      pipemgr.enable: true
158      pipemgr.filter: "http.log.access"
159    depends_on:
160      pipemgr:
161        condition: service_healthy
162    ports:
163      - "${PROSE_HTTPS_V4:-443}:443"
164      - "${PROSE_HTTP_V4:-80}:80"
165      - "${PROSE_HTTPS_V6:-[::1]:443}:443"
166      - "${PROSE_HTTP_V6:-[::1]:80}:80"
167    profiles:
168      - prose
169      - caddy
170      - all
171    logging:
172      driver: "json-file"
173      options:
174        max-file: "3"
175        max-size: "1024m"
176  prose-web:
177    dns: 1.1.1.1
178    networks:
179      prose:
180        aliases:
181          - web
182    env_file:
183      - .env.prod
184    volumes:
185      - ./data/prose-ssh/data:/app/ssh_data
186      - ./data/storage:/storage
187  prose-ssh:
188    networks:
189      prose:
190        aliases:
191          - ssh
192    env_file:
193      - .env.prod
194    volumes:
195      - ./data/prose-ssh/data:/app/ssh_data
196      - ./data/storage:/storage
197    ports:
198      - "${PROSE_SSH_V4:-22}:2222"
199      - "${PROSE_SSH_V6:-[::1]:22}:2222"
200  pgs-caddy:
201    image: ghcr.io/picosh/pico/caddy:latest
202    restart: always
203    networks:
204      - pgs
205    env_file:
206      - .env.prod
207    environment:
208      APP_DOMAIN: ${PGS_DOMAIN:-pgs.sh}
209      APP_EMAIL: ${PGS_EMAIL:-hello@pico.sh}
210      VALKEY_ADDR: ${VALKEY_ADDR:-valkey:6379}
211      VALKEY_PASSWORD: ${VALKEY_PASSWORD}
212    volumes:
213      - ${PGS_CADDYFILE}:/etc/caddy/Caddyfile
214      - ./data/pgs-caddy/data:/data
215      - ./data/pgs-caddy/config:/config
216    ports:
217      - "${PGS_HTTPS_V4:-443}:443"
218      - "${PGS_HTTP_V4:-80}:80"
219      - "${PGS_HTTPS_V6:-[::1]:443}:443"
220      - "${PGS_HTTP_V6:-[::1]:80}:80"
221    labels:
222      pipemgr.enable: true
223      pipemgr.filter: "http.log.access"
224    depends_on:
225      pipemgr:
226        condition: service_healthy
227    profiles:
228      - pgs
229      - pgs-cdn
230      - caddy
231      - all
232    logging:
233      driver: "json-file"
234      options:
235        max-file: "3"
236        max-size: "1024m"
237  pgs-web:
238    dns: 1.1.1.1
239    networks:
240      pgs:
241        aliases:
242          - web
243    env_file:
244      - .env.prod
245    volumes:
246      - ./data/storage:/storage
247      - ./data/pgs-ssh/data:/app/ssh_data
248    deploy:
249      resources:
250        limits:
251          memory: 3g
252    logging:
253      driver: "json-file"
254      options:
255        max-file: "3"
256        max-size: "1024m"
257  pgs-cdn:
258    dns: 1.1.1.1
259    networks:
260      pgs:
261        aliases:
262          - web
263    env_file:
264      - .env.prod
265    volumes:
266      - ./data/pgs-ssh/data:/app/ssh_data
267    deploy:
268      resources:
269        limits:
270          memory: 3g
271    logging:
272      driver: "json-file"
273      options:
274        max-file: "3"
275        max-size: "1024m"
276  pgs-ssh:
277    networks:
278      pgs:
279        aliases:
280          - ssh
281    env_file:
282      - .env.prod
283    volumes:
284      - ./data/storage:/storage
285      - ./data/pgs-ssh/data:/app/ssh_data
286      - ./data/tmp:/tmp
287    ports:
288      - "${PGS_SSH_V4:-22}:2222"
289      - "${PGS_SSH_V6:-[::1]:22}:2222"
290    deploy:
291      resources:
292        limits:
293          memory: 3g
294    logging:
295      driver: "json-file"
296      options:
297        max-file: "3"
298        max-size: "1024m"
299  feeds-caddy:
300    image: ghcr.io/picosh/pico/caddy:latest
301    restart: always
302    networks:
303      - feeds
304    env_file:
305      - .env.prod
306    environment:
307      APP_DOMAIN: ${FEEDS_DOMAIN:-feeds.pico.sh}
308      APP_EMAIL: ${FEEDS_EMAIL:-hello@pico.sh}
309    volumes:
310      - ${FEEDS_CADDYFILE}:/etc/caddy/Caddyfile
311      - ./data/feeds-caddy/data:/data
312      - ./data/feeds-caddy/config:/config
313    ports:
314      - "${FEEDS_HTTPS_V4:-443}:443"
315      - "${FEEDS_HTTP_V4:-80}:80"
316      - "${FEEDS_HTTPS_V6:-[::1]:443}:443"
317      - "${FEEDS_HTTP_V6:-[::1]:80}:80"
318    profiles:
319      - feeds
320      - caddy
321      - all
322  feeds-web:
323    networks:
324      feeds:
325        aliases:
326          - web
327    env_file:
328      - .env.prod
329    volumes:
330      - ./data/feeds-ssh/data:/app/ssh_data
331    logging:
332      driver: "json-file"
333      options:
334        max-file: "3"
335        max-size: "1024m"
336  feeds-ssh:
337    networks:
338      feeds:
339        aliases:
340          - ssh
341    env_file:
342      - .env.prod
343    volumes:
344      - ./data/feeds-ssh/data:/app/ssh_data
345    ports:
346      - "${FEEDS_SSH_V4:-22}:2222"
347      - "${FEEDS_SSH_V6:-[::1]:22}:2222"
348    logging:
349      driver: "json-file"
350      options:
351        max-file: "3"
352        max-size: "1024m"
353  pico-caddy:
354    image: ghcr.io/picosh/pico/caddy:latest
355    restart: always
356    networks:
357      - pico
358    env_file:
359      - .env.prod
360    environment:
361      APP_DOMAIN: ${PICO_DOMAIN:-pico.sh}
362      APP_EMAIL: ${PICO_EMAIL:-hello@pico.sh}
363    volumes:
364      - ${PICO_CADDYFILE}:/etc/caddy/Caddyfile
365      - ./data/pico-caddy/data:/data
366      - ./data/pico-caddy/config:/config
367    ports:
368      - "${PICO_HTTPS_V4:-443}:443"
369      - "${PICO_HTTP_V4:-80}:80"
370      - "${PICO_HTTPS_V6:-[::1]:443}:443"
371      - "${PICO_HTTP_V6:-[::1]:80}:80"
372    profiles:
373      - pico
374      - caddy
375      - all
376    logging:
377      driver: "json-file"
378      options:
379        max-file: "3"
380        max-size: "1024m"
381  pico-ssh:
382    networks:
383      pico:
384        aliases:
385          - ssh
386    env_file:
387      - .env.prod
388    volumes:
389      - ./data/pico-ssh/data:/app/ssh_data
390    ports:
391      - "${PICO_SSH_V4:-22}:2222"
392      - "${PICO_SSH_V6:-[::1]:22}:2222"
393
394networks:
395  default:
396    enable_ipv6: true
397    ipam:
398      driver: default
399      config:
400        - subnet: "172.101.0.0/24"
401        - subnet: fd00:dead:beef:101::/112
402  prose:
403    enable_ipv6: true
404    driver_opts:
405      com.docker.network.bridge.name: prose
406    ipam:
407      config:
408        - subnet: 172.30.0.0/16
409        - subnet: fd00:dead:beef:18::/112
410  pastes:
411    enable_ipv6: true
412    driver_opts:
413      com.docker.network.bridge.name: pastes
414    ipam:
415      config:
416        - subnet: 172.19.0.0/16
417        - subnet: fd00:dead:beef:19::/112
418  feeds:
419    enable_ipv6: true
420    driver_opts:
421      com.docker.network.bridge.name: feeds
422    ipam:
423      config:
424        - subnet: 172.22.0.0/16
425        - subnet: fd00:dead:beef:22::/112
426  pgs:
427    enable_ipv6: true
428    driver_opts:
429      com.docker.network.bridge.name: pgs
430    ipam:
431      config:
432        - subnet: 172.23.0.0/16
433        - subnet: fd00:dead:beef:23::/112
434  pico:
435    enable_ipv6: true
436    driver_opts:
437      com.docker.network.bridge.name: pico
438    ipam:
439      config:
440        - subnet: 172.25.0.0/16
441        - subnet: fd00:dead:beef:25::/112
442  pipe:
443    enable_ipv6: true
444    driver_opts:
445      com.docker.network.bridge.name: pipe
446    ipam:
447      config:
448        - subnet: 172.27.0.0/16
449        - subnet: fd00:dead:beef:27::/112