Repository navigation
Expand file tree
/
Copy pathdocker-compose.staging.yml
More file actions
205 lines (195 loc) · 7.23 KB
/
Copy pathdocker-compose.staging.yml
File metadata and controls
205 lines (195 loc) · 7.23 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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
services:
api:
image: ci/api
env_file:
- .env
volumes:
# See docker-compose.production.yml for why these two share a mount and
# why /repo is read-only.
- ${CI_IMPORT_WORK_DIR:-./import-work}:/var/lib/ci-import
- ${CI_REPO_DIR:-~/Downloads}:/repo:ro
environment:
CI_ROLE: web
DATABASE_HOST: database
CI_IMPORT_SCRATCH_DIR: ${CI_IMPORT_SCRATCH_DIR:-/var/lib/ci-import/scratch}
CI_IMPORT_ROOTS: ${CI_IMPORT_ROOTS:-["/repo"]}
CI_IMPORT_INBOX_HOST_DIR: ${CI_IMPORT_INBOX_HOST_DIR:-${CI_IMPORT_WORK_DIR:-./import-work}/inbox}
OBJECT_STORE_URL: http://object-store:9000
OLLAMA_HOST: http://host.docker.internal:11434
# OpenAI-compatible chat backend (Hub-injected on managed deploys). When
# unset, the API falls back to native Ollama on OLLAMA_HOST.
LLM_API_BASE: ${LLM_API_BASE:-}
LLM_API_KEY: ${LLM_API_KEY:-}
LLM_DEFAULT_CHAT_MODEL: ${LLM_DEFAULT_CHAT_MODEL:-}
# Embeddings stay on native Ollama even when chat runs on vLLM/Lemonade;
# falls back to OLLAMA_HOST when unset.
LLM_EMBEDDING_API_BASE: ${LLM_EMBEDDING_API_BASE:-}
OLLAMA_EMBED_HOST: ${OLLAMA_EMBED_HOST:-}
HBPE_HOST: http://hbpe-service:8002
# `api` exists only in the staging/production overrides — there is no base
# definition to inherit this from, and `env_file: .env` above does not
# help because the code reads SENTRY_DSN, not SENTRY_DSN_API. Without it
# staging reports from hbpe and summary but silently not from the API.
SENTRY_DSN: ${SENTRY_DSN_API:-}
SENTRY_ENV: ${SENTRY_ENV:-}
CI_TELEMETRY: ${CI_TELEMETRY:-}
CI_LOCAL_ONLY: ${CI_LOCAL_ONLY:-}
CI_SERVER_VERSION: ${CI_SERVER_VERSION:-}
networks:
- ci
extra_hosts:
- host.docker.internal:host-gateway
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3030/health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
depends_on:
migrate-database:
condition: service_completed_successfully
database:
condition: service_healthy
restart: unless-stopped
# api, worker and gateway have no definition in docker-compose.yml, so they
# cannot inherit its bounded-logging block — see the note on `database`
# there for why the json-file driver must not run uncapped.
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
profiles: [ "staging" ]
# The headless half of the api — see docker-compose.production.yml.
worker:
image: ci/api
env_file:
- .env
volumes:
- ${CI_IMPORT_WORK_DIR:-./import-work}:/var/lib/ci-import
environment:
CI_ROLE: worker
DATABASE_HOST: database
OBJECT_STORE_URL: http://object-store:9000
CI_IMPORT_SCRATCH_DIR: ${CI_IMPORT_SCRATCH_DIR:-/var/lib/ci-import/scratch}
SENTRY_DSN: ${SENTRY_DSN_API:-}
SENTRY_ENV: ${SENTRY_ENV:-}
networks:
- ci
depends_on:
migrate-database:
condition: service_completed_successfully
database:
condition: service_healthy
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
profiles: [ "staging" ]
database:
environment:
PASSWORD: ${DATABASE_ADMIN_PASSWORD}
# Loopback only, like docker-compose.local.yml. The superuser password and
# the object-store root keys below come from .env, which starts life as a
# copy of the committed .env.default, and Docker's own iptables rules skip
# ufw, so an all-interfaces bind handed both to anyone on the network.
# Reach them from another machine through an SSH tunnel instead.
ports:
- 127.0.0.1:5432:5432
gateway:
image: ci/gateway
ports:
- 8642:8642
volumes:
- ./infrastructure/gateway/nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- ci
depends_on:
api:
condition: service_healthy
object-store:
condition: service_healthy
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
profiles: [ "staging" ]
hbpe-service:
extra_hosts:
- host.docker.internal:host-gateway
environment:
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
API_URL: http://api:3030
SIDECAR_AUTH_SECRET: ${SIDECAR_AUTH_SECRET}
LLM_API_BASE: ${LLM_API_BASE:-http://host.docker.internal:11434/v1}
LLM_API_KEY: ${LLM_API_KEY:-ollama}
LLM_DEFAULT_CHAT_MODEL: ${LLM_DEFAULT_CHAT_MODEL:-}
# NO `devices:`/`group_add:` here on purpose — same reasoning as
# docker-compose.production.yml. These used to pass /dev/kfd + /dev/dri and
# group_add: [video] through unconditionally, so `make staging` refused to
# start on any host without AMD device nodes: a `devices:` entry that does
# not exist on the host is a hard start failure, not a graceful
# degradation. Passthrough belongs to the opt-in docker-compose.rocm.yml
# overlay, which carries the same device nodes plus the numeric
# AMD_RENDER_GID/AMD_VIDEO_GID groups and seccomp:unconfined:
#
# docker compose -f docker-compose.yml -f docker-compose.staging.yml \
# -f docker-compose.rocm.yml --profile staging up -d
object-store:
environment:
USERNAME: ${OBJECT_STORE_USERNAME}
PASSWORD: ${OBJECT_STORE_PASSWORD}
# Loopback only; see the note on `database` above.
ports:
- 127.0.0.1:9000:9000
summary-service:
# Pass the shared LLM config from .env explicitly (not via env_file) so
# host-oriented vars like DATABASE_HOST=localhost don't leak into the container.
environment:
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
# Function-run completion callbacks POST to the api service; the JWT
# secret must match AUTH_JWT_AUTHTOKENSECRET so the callback passes auth.
API_URL: http://api:3030
SIDECAR_AUTH_SECRET: ${SIDECAR_AUTH_SECRET}
LLM_API_BASE: ${LLM_API_BASE:-http://host.docker.internal:11434/v1}
LLM_API_KEY: ${LLM_API_KEY:-ollama}
# Unset by default: the summary service uses the Hub-injected model, or
# discovers a served model from LLM_API_BASE/models at startup.
LLM_DEFAULT_CHAT_MODEL: ${LLM_DEFAULT_CHAT_MODEL:-}
SUMMARY_OUTPUT_MODE: ${SUMMARY_OUTPUT_MODE:-native}
SUMMARY_OUTPUT_RETRIES: ${SUMMARY_OUTPUT_RETRIES:-3}
#############
# EPHEMERAL #
#############
migrate-database:
image: ci/api
env_file:
- .env
environment:
DATABASE_HOST: database
networks:
- ci
command: ["yarn", "migrate"]
restart: "no"
depends_on:
setup-database:
condition: service_completed_successfully
database:
condition: service_healthy
profiles: [ "staging" ]
setup-database:
environment:
ADMIN_PASSWORD: ${DATABASE_ADMIN_PASSWORD}
COMPANION_PASSWORD: ${DATABASE_PASSWORD}
# Unset means "skip the replication role", which leaves powersync unable to
# authenticate. See infrastructure/powersync/README.md.
POWERSYNC_PASSWORD: ${POWERSYNC_DATABASE_PASSWORD:-}
volumes:
db-data:
name: ${COMPOSE_PROJECT_NAME}-staging-db-data
object-data:
name: ${COMPOSE_PROJECT_NAME}-staging-object-data