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