From fa18c032e28d39e2a64c9657e22427c7dc2b2a33 Mon Sep 17 00:00:00 2001 From: BigBodyCobain <43977454+BigBodyCobain@users.noreply.github.com> Date: Sat, 2 May 2026 19:27:59 -0600 Subject: [PATCH] Fix Docker first-run startup data seeding Seed safe static backend data into fresh Docker volumes, tighten Docker build-context exclusions, avoid optional env warnings, and make the frontend healthcheck use the IPv4 loopback path that works inside the container. --- .dockerignore | 33 +++++++++++++++++++++++++++++++++ backend/Dockerfile | 8 ++++++++ backend/docker-entrypoint.sh | 17 +++++++++++++++++ docker-compose.yml | 12 ++++++------ 4 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 backend/docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore index 2b39f1f..0df18f6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,6 +8,18 @@ __pycache__/ venv/ .venv/ .ruff_cache/ +local-artifacts/ +release-secrets/ + +# Never send local configuration or credentials into Docker builds +.env +.env.* +**/.env +**/.env.* +*.pem +*.key +*.p12 +*.pfx # privacy-core build caches (source is needed, artifacts are not) privacy-core/target/ @@ -21,3 +33,24 @@ privacy-core/.codex-tmp/ *.log extra/ prototype/ + +# Runtime state generated by local backend runs +backend/.pytest_cache/ +backend/.ruff_cache/ +backend/backend.egg-info/ +backend/build/ +backend/node_modules/ +backend/timemachine/ +backend/venv/ +backend/data/*cache*.json +backend/data/**/*cache*.json +backend/data/wormhole*.json +backend/data/**/wormhole*.json +backend/data/dm_*.json +backend/data/**/dm_*.json +backend/data/**/peer_store.json +backend/data/**/node.json +backend/data/*.log +backend/data/**/*.log +backend/data/*.key +backend/data/**/*.key diff --git a/backend/Dockerfile b/backend/Dockerfile index 421dc32..fdc0735 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -49,6 +49,13 @@ RUN cd /workspace/backend && uv sync --frozen --no-dev \ # Copy backend source code COPY backend/ . +# Preserve safe static data outside /app/data. The compose named volume mounted +# at /app/data hides image-baked files on first run, so the entrypoint seeds +# missing static JSON into fresh volumes before the backend starts. +RUN mkdir -p /app/image-data \ + && if [ -d /app/data ]; then cp -a /app/data/. /app/image-data/; fi \ + && chmod +x /app/docker-entrypoint.sh + # Install Node.js dependencies (ws module for AIS WebSocket proxy) COPY backend/package*.json ./ RUN npm ci --omit=dev @@ -75,4 +82,5 @@ USER backenduser EXPOSE 8000 # Start FastAPI server +ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--timeout-keep-alive", "120"] diff --git a/backend/docker-entrypoint.sh b/backend/docker-entrypoint.sh new file mode 100644 index 0000000..5ceea6f --- /dev/null +++ b/backend/docker-entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh +set -eu + +# Docker named volumes hide files that were baked into /app/data at image build +# time. Seed safe, static data into a fresh volume so first-run Docker installs +# behave like source installs without bundling local runtime secrets. +if [ -d /app/image-data ]; then + mkdir -p /app/data + find /app/image-data -mindepth 1 -maxdepth 1 -type f | while IFS= read -r src; do + dest="/app/data/$(basename "$src")" + if [ ! -e "$dest" ]; then + cp "$src" "$dest" || true + fi + done +fi + +exec "$@" diff --git a/docker-compose.yml b/docker-compose.yml index 1c604a9..3ca23be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,10 +13,10 @@ services: ports: - "${BIND:-127.0.0.1}:8000:8000" environment: - - AIS_API_KEY=${AIS_API_KEY} - - OPENSKY_CLIENT_ID=${OPENSKY_CLIENT_ID} - - OPENSKY_CLIENT_SECRET=${OPENSKY_CLIENT_SECRET} - - LTA_ACCOUNT_KEY=${LTA_ACCOUNT_KEY} + - AIS_API_KEY=${AIS_API_KEY:-} + - OPENSKY_CLIENT_ID=${OPENSKY_CLIENT_ID:-} + - OPENSKY_CLIENT_SECRET=${OPENSKY_CLIENT_SECRET:-} + - LTA_ACCOUNT_KEY=${LTA_ACCOUNT_KEY:-} - ADMIN_KEY=${ADMIN_KEY:-} - FINNHUB_API_KEY=${FINNHUB_API_KEY:-} # Override allowed CORS origins (comma-separated). Auto-detects LAN IPs if empty. @@ -26,7 +26,7 @@ services: # Operator-trusted sync/push peers. Leave empty unless you control the peer secret on both sides. - MESH_RELAY_PEERS=${MESH_RELAY_PEERS:-} # Shared transport auth for operator peer push. Must be set to a unique secret per deployment. - - MESH_PEER_PUSH_SECRET=${MESH_PEER_PUSH_SECRET} + - MESH_PEER_PUSH_SECRET=${MESH_PEER_PUSH_SECRET:-} volumes: - backend_data:/app/data restart: unless-stopped @@ -56,7 +56,7 @@ services: condition: service_healthy restart: unless-stopped healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/"] + test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/"] interval: 30s timeout: 10s retries: 3