-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
119 lines (114 loc) · 3.91 KB
/
Copy pathdocker-compose.yml
File metadata and controls
119 lines (114 loc) · 3.91 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
# ── Ons — production-grade Compose ────────────────────────────────────────────
#
# Usage (single command, any environment):
# docker compose --env-file .env.dev up --build -d
# docker compose --env-file .env.prod up --build -d
#
# All variables are read from the env file and forwarded explicitly via
# `environment:` — no separate env_file directive, no path resolution issues.
#
# Architecture:
# internet → nginx:80 ─┬─ /* → static SPA (frontend)
# └─ /api/* → api:3001 (internal only)
#
# The API is never exposed externally — all traffic enters through nginx.
# VITE_API_URL must be empty so the browser uses relative paths (same origin).
#
# Required: MONGODB_URI ENCRYPTION_KEY JWT_SECRET FORM_SECRET VITE_INVITE_KEY
# See api/.env.example for the full variable reference.
name: ons
services:
# ── API ─────────────────────────────────────────────────────────────────────
api:
build:
context: ./api
dockerfile: Dockerfile
image: ons-api:latest
container_name: ons-api
restart: unless-stopped
networks:
- ons-net
expose:
- "${PORT:-3001}"
environment:
NODE_ENV: ${NODE_ENV:-production}
PORT: ${PORT:-3001}
MONGODB_URI: ${MONGODB_URI:?MONGODB_URI must be set}
MONGODB_DB_NAME: ${MONGODB_DB_NAME:-ons}
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY must be set}
FORM_SECRET: ${FORM_SECRET:?FORM_SECRET must be set}
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET must be set}
JWT_EXPIRY: ${JWT_EXPIRY:-8h}
PUBLIC_URL: ${PUBLIC_URL:-}
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-}
EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-local}
EMBEDDING_MODEL: ${EMBEDDING_MODEL:-}
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
EMBEDDING_BASE_URL: ${EMBEDDING_BASE_URL:-}
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:${PORT:-3001}/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
reservations:
cpus: "0.25"
memory: 128M
security_opt:
- no-new-privileges:true
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
stop_grace_period: 15s
# ── Frontend (nginx) ─────────────────────────────────────────────────────────
# Serves the static SPA and reverse-proxies /api/* to the api service.
# VITE_API_URL is intentionally empty: relative paths hit nginx → api.
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
args:
VITE_API_URL: ${VITE_API_URL:-}
VITE_INVITE_KEY: ${VITE_INVITE_KEY:?VITE_INVITE_KEY must be set}
image: ons-frontend:latest
container_name: ons-frontend
restart: unless-stopped
networks:
- ons-net
ports:
- "${HTTP_PORT:-80}:80"
depends_on:
api:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost/ || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
deploy:
resources:
limits:
cpus: "0.5"
memory: 64M
reservations:
cpus: "0.1"
memory: 32M
security_opt:
- no-new-privileges:true
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
stop_grace_period: 5s
networks:
ons-net:
driver: bridge