Skip to content

Commit 8269de6

Browse files
authored
fix(deploy): split host-specific config, sync templates from CI (#33)
* fix(deploy): sync compose.prod.yml to server before restart Server had stale compose.prod.yml with STATIC_DIR=/app/frontend/dist, but the current image serves static assets from /app/web/dist (renamed in #30). Prod served 404 on /. Deploy now checks out the repo and scps compose.prod.yml to the server so env config stays in lockstep with the image. * docs(deploy): sync graphhopper config too, document minimal server layout Extend the scp step to ship backend/graphhopper_config.yml alongside compose.prod.yml so every file compose.prod.yml references comes from CI. Add DEPLOY.md describing the authoritative server layout and the rule that anything not referenced by compose.prod.yml should be deleted from the server. * refactor(deploy): split host-specific config into server-side .env Previously compose.prod.yml entangled app config (STATIC_DIR, LISTEN_ADDR, PHOTON_URL — all image-bakable), orchestration (service wiring) and host identity (DB password, memory limits, host ports) in one file that CI overwrote on every deploy. This let image/compose drift break prod (the STATIC_DIR /app/frontend/dist vs /app/web/dist mismatch that served 404 on /) and kept secrets in git. New split: - Image defaults own app config (already the case in backend/src/config.rs and backend/Dockerfile; compose just stops overriding them). - compose.prod.yml is a pure orchestration template with ${VAR} refs, synced by CI. - Host-specific values live in ~/beebeebike/.env on the prod host: POSTGRES_PASSWORD, memory limits (DB_MEM_LIMIT, GRAPHHOPPER_MEM_LIMIT, TILES_MEM_LIMIT, BACKEND_MEM_LIMIT), Postgres tuning, GRAPHHOPPER_JAVA_OPTS, reverse-proxy-facing host ports. Never committed, never touched by CI. .env.example documents the schema. Deploy now pulls all images and recreates the whole stack (needed once because graphhopper's config mount moved to backend/graphhopper_config.yml and the tiles/db services pick up their memory limits from .env).
1 parent 7986e7b commit 8269de6

3 files changed

Lines changed: 64 additions & 17 deletions

File tree

.env.example

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Host-specific config for compose.prod.yml.
2+
# Copy to ~/beebeebike/.env on the prod host and edit. Never commit .env.
3+
# Docker Compose auto-loads .env from the same dir as the compose file.
4+
5+
# --- Database ---
6+
POSTGRES_DB=beebeebike
7+
POSTGRES_USER=beebeebike
8+
POSTGRES_PASSWORD=CHANGE_ME
9+
10+
# Postgres memory tuning (keep within DB_MEM_LIMIT)
11+
DB_SHARED_BUFFERS=64MB
12+
DB_WORK_MEM=4MB
13+
DB_EFFECTIVE_CACHE_SIZE=256MB
14+
15+
# --- Container memory limits ---
16+
DB_MEM_LIMIT=256m
17+
GRAPHHOPPER_MEM_LIMIT=512m
18+
TILES_MEM_LIMIT=128m
19+
BACKEND_MEM_LIMIT=128m
20+
21+
# --- Graphhopper JVM (must fit within GRAPHHOPPER_MEM_LIMIT) ---
22+
GRAPHHOPPER_JAVA_OPTS=-Xmx384m -Xms256m
23+
24+
# --- Reverse-proxy-facing host ports (bound to 127.0.0.1) ---
25+
BACKEND_HOST_PORT=3848
26+
TILES_HOST_PORT=3847

.github/workflows/ci.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ jobs:
119119
runs-on: ubuntu-latest
120120
if: vars.DEPLOY_HOST != ''
121121
steps:
122+
- uses: actions/checkout@v4
123+
124+
- name: Sync runtime config to server
125+
uses: appleboy/scp-action@v1
126+
with:
127+
host: ${{ vars.DEPLOY_HOST }}
128+
username: ${{ vars.DEPLOY_USER }}
129+
key: ${{ secrets.DEPLOY_SSH_KEY }}
130+
source: |
131+
compose.prod.yml
132+
backend/graphhopper_config.yml
133+
target: beebeebike/
134+
122135
- name: Deploy via SSH
123136
uses: appleboy/ssh-action@v1
124137
with:
@@ -127,5 +140,5 @@ jobs:
127140
key: ${{ secrets.DEPLOY_SSH_KEY }}
128141
script: |
129142
cd ~/beebeebike
130-
docker compose -f compose.prod.yml pull backend
131-
docker compose -f compose.prod.yml up -d backend
143+
docker compose -f compose.prod.yml pull
144+
docker compose -f compose.prod.yml up -d --remove-orphans

compose.prod.yml

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
1+
# Orchestration template for the prod host.
2+
# Host-specific values (secrets, memory limits, ports, tuning) come from
3+
# ~/beebeebike/.env on the server. See .env.example.
4+
15
services:
26
db:
37
image: postgis/postgis:16-3.4
48
container_name: beebeebike-db
59
environment:
6-
POSTGRES_DB: beebeebike
7-
POSTGRES_USER: beebeebike
8-
POSTGRES_PASSWORD: beebeebike
9-
command: postgres -c shared_buffers=64MB -c work_mem=4MB -c effective_cache_size=256MB
10+
POSTGRES_DB: ${POSTGRES_DB}
11+
POSTGRES_USER: ${POSTGRES_USER}
12+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
13+
command:
14+
- postgres
15+
- -c
16+
- shared_buffers=${DB_SHARED_BUFFERS}
17+
- -c
18+
- work_mem=${DB_WORK_MEM}
19+
- -c
20+
- effective_cache_size=${DB_EFFECTIVE_CACHE_SIZE}
1021
volumes:
1122
- pgdata:/var/lib/postgresql/data
12-
mem_limit: 256m
23+
mem_limit: ${DB_MEM_LIMIT}
1324
restart: unless-stopped
1425

1526
graphhopper:
@@ -26,36 +37,33 @@ services:
2637
- ./data/osm/berlin/berlin.osm.pbf:/data/berlin.osm.pbf:ro
2738
- ./data/osm/berlin/graphhopper:/data/graphhopper-cache
2839
environment:
29-
JAVA_OPTS: "-Xmx384m -Xms256m"
30-
mem_limit: 512m
40+
JAVA_OPTS: ${GRAPHHOPPER_JAVA_OPTS}
41+
mem_limit: ${GRAPHHOPPER_MEM_LIMIT}
3142
restart: unless-stopped
3243

3344
tiles:
3445
image: versatiles/versatiles-frontend:latest-alpine
3546
container_name: beebeebike-tiles
3647
ports:
37-
- "127.0.0.1:3847:8080"
48+
- "127.0.0.1:${TILES_HOST_PORT}:8080"
3849
volumes:
3950
- ./data/tiles/berlin.versatiles:/tiles/berlin.versatiles:ro
4051
command: ["/app/versatiles", "server", "-s", "/app/frontend-dev.br.tar", "[osm]/tiles/berlin.versatiles"]
41-
mem_limit: 128m
52+
mem_limit: ${TILES_MEM_LIMIT}
4253
restart: unless-stopped
4354

4455
backend:
4556
image: ghcr.io/cafca/beebeebike:latest
4657
container_name: beebeebike-backend
4758
ports:
48-
- "127.0.0.1:3848:3000"
59+
- "127.0.0.1:${BACKEND_HOST_PORT}:3000"
4960
environment:
50-
DATABASE_URL: postgres://beebeebike:beebeebike@db:5432/beebeebike
61+
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
5162
GRAPHHOPPER_URL: http://graphhopper:8989
52-
PHOTON_URL: https://photon.komoot.io
53-
LISTEN_ADDR: 0.0.0.0:3000
54-
STATIC_DIR: /app/web/dist
5563
depends_on:
5664
- db
5765
- graphhopper
58-
mem_limit: 128m
66+
mem_limit: ${BACKEND_MEM_LIMIT}
5967
restart: unless-stopped
6068

6169
volumes:

0 commit comments

Comments
 (0)