mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 16:56:33 +00:00
refactor: build-time sec-config from template + Coolify build args
sec-config.yaml is now generated at Docker build time from
sec-config.template.yaml via envsubst. Secrets come from Coolify
build args (set in UI, never in git). Template uses ${VAR:-default}
placeholders — safe to commit to public repo.
- sec-config.yaml removed from git, added to .gitignore
- sec-config.template.yaml added (public, no secrets)
- Dockerfile.server: ARGs for all config, envsubst generates config
at build time, result is chmod 444 (read-only)
- Coolify compose: removed sec-config volume mount (baked in now)
- For native installs: copy template to sec-config.yaml, fill values
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aab2e928c5
commit
88526095e2
4 changed files with 71 additions and 51 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -47,3 +47,5 @@ rauc-signing/
|
|||
old-python/
|
||||
/Hik-Connect-Docs.pdf
|
||||
/Hik-Connect-Docs.md
|
||||
# sec-config.yaml is generated from template — never commit real config
|
||||
/sec-config.yaml
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
# BetterFrame server — BSB container with built plugins.
|
||||
#
|
||||
# sec-config.yaml is NOT baked in — mount it at runtime:
|
||||
# volumes:
|
||||
# - ./sec-config.yaml:/app/sec-config.yaml:ro
|
||||
# sec-config.yaml is generated at build time from sec-config.template.yaml
|
||||
# via envsubst. Secrets come from Coolify build args (set in UI, not in git).
|
||||
#
|
||||
# Builder stage compiles TS + native deps (argon2).
|
||||
# Runtime stage uses the official BSB container.
|
||||
# Build args (set in Coolify UI as secrets):
|
||||
# BF_PG_PASSWORD postgres password
|
||||
# BF_FIRMWARE_SIGNING_KEY Ed25519 PEM for firmware signing
|
||||
# BF_FIRMWARE_IMPORT_API_KEY CI bearer token
|
||||
# BF_OTA_IMPORT_API_KEY CI bearer token
|
||||
# BF_MQTT_URL mqtt://broker:1883 (optional)
|
||||
# BF_MQTT_USERNAME (optional)
|
||||
# BF_MQTT_PASSWORD (optional)
|
||||
#
|
||||
# Non-secret build args (defaults work for standard compose):
|
||||
# BF_DB_DRIVER postgres|sqlite (default: postgres)
|
||||
# BF_PG_HOST (default: postgres)
|
||||
# BF_PG_PORT (default: 5432)
|
||||
# BF_PG_DATABASE (default: betterframe)
|
||||
# BF_PG_USER (default: betterframe)
|
||||
# BF_NODERED_URL (default: http://nodered:1880)
|
||||
# BF_SELF_URL (default: http://server:18080)
|
||||
# BF_SERVER_VERSION (default: dev)
|
||||
|
||||
FROM node:24-trixie-slim AS builder
|
||||
|
||||
|
|
@ -28,13 +43,30 @@ RUN npm run build
|
|||
# ---- Runtime ----
|
||||
FROM betterweb/service-base:node
|
||||
|
||||
# All config build args — secrets set in Coolify UI, not in git
|
||||
ARG BF_SERVER_VERSION=dev
|
||||
ARG BF_DB_DRIVER=postgres
|
||||
ARG BF_PG_HOST=postgres
|
||||
ARG BF_PG_PORT=5432
|
||||
ARG BF_PG_DATABASE=betterframe
|
||||
ARG BF_PG_USER=betterframe
|
||||
ARG BF_PG_PASSWORD=betterframe
|
||||
ARG BF_PG_POOL_MAX=10
|
||||
ARG BF_NODERED_URL=http://nodered:1880
|
||||
ARG BF_SELF_URL=http://server:18080
|
||||
ARG BF_FIRMWARE_SIGNING_KEY=
|
||||
ARG BF_FIRMWARE_IMPORT_API_KEY=
|
||||
ARG BF_OTA_IMPORT_API_KEY=
|
||||
ARG BF_MQTT_URL=
|
||||
ARG BF_MQTT_USERNAME=
|
||||
ARG BF_MQTT_PASSWORD=
|
||||
ARG BF_MQTT_TOPIC_PREFIX=betterframe
|
||||
|
||||
USER root
|
||||
|
||||
# ffmpeg for camera snapshot capture
|
||||
# envsubst + ffmpeg
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ffmpeg \
|
||||
gettext-base ffmpeg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p /var/lib/betterframe && chown node:node /var/lib/betterframe
|
||||
|
|
@ -48,8 +80,11 @@ COPY --from=builder /app/server/bsb-plugin.json ./bsb-plugin.json
|
|||
COPY --from=builder /app/server/package.json ./package.json
|
||||
COPY --from=builder /app/tsconfig.base.json ./tsconfig.base.json
|
||||
|
||||
# Static web assets served by admin-http
|
||||
COPY --from=builder /app/server/lib/web-static ./lib/web-static
|
||||
# Generate sec-config.yaml from template + build args
|
||||
COPY sec-config.template.yaml /tmp/sec-config.template.yaml
|
||||
RUN envsubst < /tmp/sec-config.template.yaml > /home/bsb/sec-config.yaml \
|
||||
&& chmod 444 /home/bsb/sec-config.yaml \
|
||||
&& rm /tmp/sec-config.template.yaml
|
||||
|
||||
# Bake version
|
||||
RUN echo "$BF_SERVER_VERSION" > /home/bsb/.bf-version
|
||||
|
|
|
|||
|
|
@ -4,11 +4,8 @@
|
|||
#
|
||||
# Point Coolify resource at this file instead of docker-compose.yml.
|
||||
#
|
||||
# Volume name overrides:
|
||||
# BF_DATA_VOLUME_NAME default "betterframe-data"
|
||||
# NODERED_DATA_VOLUME_NAME default "nodered-data"
|
||||
#
|
||||
# Server config comes from sec-config.yaml, not env vars.
|
||||
# Server config is baked into the image at build time from
|
||||
# sec-config.template.yaml + Coolify build args (secrets).
|
||||
|
||||
version: "3.8"
|
||||
|
||||
|
|
@ -23,8 +20,6 @@ services:
|
|||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=UTC
|
||||
volumes:
|
||||
- ./sec-config.yaml:/home/bsb/sec-config.yaml:ro
|
||||
expose:
|
||||
- "18080"
|
||||
- "18081"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# BSB runtime configuration for BetterFrame server.
|
||||
# BSB runtime configuration — template for Docker builds.
|
||||
#
|
||||
# This file is bind-mounted into the container at /home/bsb/sec-config.yaml.
|
||||
# All server config lives here — no env vars in the application code.
|
||||
# Placeholders (${VAR}) are replaced by envsubst during docker build.
|
||||
# Set values via Coolify build args or docker build --build-arg.
|
||||
#
|
||||
# For native (non-Docker) installs, adjust hostnames to 127.0.0.1 and
|
||||
# set driver: sqlite if not using PostgreSQL.
|
||||
# For native (non-Docker) installs, copy to sec-config.yaml and
|
||||
# replace placeholders with actual values.
|
||||
|
||||
default:
|
||||
observable:
|
||||
|
|
@ -17,23 +17,19 @@ default:
|
|||
plugin: events-default
|
||||
enabled: true
|
||||
services:
|
||||
# ----- Data layer -----
|
||||
service-store:
|
||||
plugin: service-store
|
||||
enabled: true
|
||||
config:
|
||||
driver: postgres
|
||||
# SQLite (native installs)
|
||||
driver: ${BF_DB_DRIVER:-postgres}
|
||||
sqlitePath: /var/lib/betterframe/betterframe.db
|
||||
# PostgreSQL (Docker / production)
|
||||
pgHost: postgres
|
||||
pgPort: 5432
|
||||
pgDatabase: betterframe
|
||||
pgUser: betterframe
|
||||
pgPassword: betterframe
|
||||
pgPoolMax: 10
|
||||
pgHost: ${BF_PG_HOST:-postgres}
|
||||
pgPort: ${BF_PG_PORT:-5432}
|
||||
pgDatabase: ${BF_PG_DATABASE:-betterframe}
|
||||
pgUser: ${BF_PG_USER:-betterframe}
|
||||
pgPassword: ${BF_PG_PASSWORD:-betterframe}
|
||||
pgPoolMax: ${BF_PG_POOL_MAX:-10}
|
||||
|
||||
# ----- Admin UI + API -----
|
||||
service-admin-http:
|
||||
plugin: service-admin-http
|
||||
enabled: true
|
||||
|
|
@ -41,7 +37,6 @@ default:
|
|||
host: 0.0.0.0
|
||||
port: 18080
|
||||
dataDir: /var/lib/betterframe
|
||||
# Auth
|
||||
sessionIdleSeconds: 43200
|
||||
sessionMaxSeconds: 2592000
|
||||
loginLockoutThreshold: 8
|
||||
|
|
@ -51,18 +46,13 @@ default:
|
|||
argon2Parallelism: 2
|
||||
cookieName: betterframe_session
|
||||
totpIssuer: BetterFrame
|
||||
# Inter-service URLs (Docker container names)
|
||||
noderedUrl: http://nodered:1880
|
||||
selfUrl: http://server:18080
|
||||
# Systemd credentials directory (native installs only)
|
||||
noderedUrl: ${BF_NODERED_URL:-http://nodered:1880}
|
||||
selfUrl: ${BF_SELF_URL:-http://server:18080}
|
||||
systemdCredsDir: ""
|
||||
# Firmware signing key (PEM). Leave empty to auto-generate on disk.
|
||||
firmwareSigningKey: ""
|
||||
# Bearer tokens for CI import endpoints. Generate with: openssl rand -base64 32
|
||||
firmwareImportApiKey: ""
|
||||
otaImportApiKey: ""
|
||||
firmwareSigningKey: "${BF_FIRMWARE_SIGNING_KEY:-}"
|
||||
firmwareImportApiKey: "${BF_FIRMWARE_IMPORT_API_KEY:-}"
|
||||
otaImportApiKey: "${BF_OTA_IMPORT_API_KEY:-}"
|
||||
|
||||
# ----- Kiosk-facing REST API -----
|
||||
service-api-http:
|
||||
plugin: service-api-http
|
||||
enabled: true
|
||||
|
|
@ -76,14 +66,12 @@ default:
|
|||
argon2Parallelism: 2
|
||||
cookieName: betterframe_session
|
||||
totpIssuer: BetterFrame
|
||||
noderedUrl: http://nodered:1880
|
||||
# MQTT telemetry bridge (optional)
|
||||
mqttUrl: ""
|
||||
mqttUsername: ""
|
||||
mqttPassword: ""
|
||||
mqttTopicPrefix: betterframe
|
||||
noderedUrl: ${BF_NODERED_URL:-http://nodered:1880}
|
||||
mqttUrl: "${BF_MQTT_URL:-}"
|
||||
mqttUsername: "${BF_MQTT_USERNAME:-}"
|
||||
mqttPassword: "${BF_MQTT_PASSWORD:-}"
|
||||
mqttTopicPrefix: ${BF_MQTT_TOPIC_PREFIX:-betterframe}
|
||||
|
||||
# ----- Live kiosk WebSocket channel -----
|
||||
service-coordinator-ws:
|
||||
plugin: service-coordinator-ws
|
||||
enabled: true
|
||||
|
|
@ -96,4 +84,4 @@ default:
|
|||
argon2Parallelism: 2
|
||||
cookieName: betterframe_session
|
||||
totpIssuer: BetterFrame
|
||||
noderedUrl: http://nodered:1880
|
||||
noderedUrl: ${BF_NODERED_URL:-http://nodered:1880}
|
||||
Loading…
Reference in a new issue