-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker-compose.traefik.yml
More file actions
83 lines (78 loc) · 3.75 KB
/
Copy pathdocker-compose.traefik.yml
File metadata and controls
83 lines (78 loc) · 3.75 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
# ─────────────────────────────────────────────────────────────────────────────
# Placet — Traefik Reverse Proxy (Optional Override)
# ─────────────────────────────────────────────────────────────────────────────
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d
#
# Or set in .env:
# COMPOSE_FILE=docker-compose.yml:docker-compose.traefik.yml
#
# Required .env variables:
# DOMAIN=placet.example.com
# ACME_EMAIL=admin@example.com (for Let's Encrypt certificates)
#
# This adds a Traefik reverse proxy with:
# - Automatic HTTPS via Let's Encrypt
# - Frontend at https://${DOMAIN}
# - Backend API at https://${DOMAIN}/api/*
# - WebSocket upgrade support
# - HTTP → HTTPS redirect
#
# Note: The base docker-compose.yml still exposes direct ports (3000, 3001,
# 9000, 9001). In production, use a firewall (e.g. ufw, iptables, cloud
# security group) to block external access to those ports — only 80 and 443
# should be publicly reachable.
# ─────────────────────────────────────────────────────────────────────────────
services:
traefik:
container_name: placet-traefik
image: traefik:v3
restart: unless-stopped
command:
- --api.dashboard=false
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# HTTP → HTTPS redirect
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
# Let's Encrypt
- --certificatesresolvers.letsencrypt.acme.httpchallenge=true
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
ports:
- '80:80'
- '443:443'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./volumes/letsencrypt:/letsencrypt
frontend:
labels:
traefik.enable: 'true'
traefik.http.routers.frontend.rule: Host(`${DOMAIN}`)
traefik.http.routers.frontend.entrypoints: websecure
traefik.http.routers.frontend.tls.certresolver: letsencrypt
traefik.http.services.frontend.loadbalancer.server.port: 3000
backend:
labels:
traefik.enable: 'true'
# API routes
traefik.http.routers.backend.rule: Host(`${DOMAIN}`) && PathPrefix(`/api`)
traefik.http.routers.backend.entrypoints: websecure
traefik.http.routers.backend.tls.certresolver: letsencrypt
traefik.http.services.backend.loadbalancer.server.port: ${BACKEND_PORT:-3001}
# WebSocket (Socket.io)
traefik.http.routers.backend-ws.rule: Host(`${DOMAIN}`) && PathPrefix(`/socket.io`)
traefik.http.routers.backend-ws.entrypoints: websecure
traefik.http.routers.backend-ws.tls.certresolver: letsencrypt
traefik.http.services.backend-ws.loadbalancer.server.port: ${BACKEND_PORT:-3001}
mcp-server:
labels:
traefik.enable: 'true'
traefik.http.routers.mcp.rule: Host(`${DOMAIN}`) && PathPrefix(`/mcp`)
traefik.http.routers.mcp.entrypoints: websecure
traefik.http.routers.mcp.tls.certresolver: letsencrypt
traefik.http.services.mcp.loadbalancer.server.port: ${MCP_PORT:-3002}
volumes: {}