mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 17:56:34 +00:00
refactor: use BSB container + mount sec-config at runtime
Dockerfile.server now uses betterweb/service-base:node as runtime base instead of node:24-trixie-slim + manual bsb-plugin-cli. BSB container handles entrypoint, user, plugin loading. sec-config.yaml removed from Docker image — must be bind-mounted at /app/sec-config.yaml. Both compose files updated with :ro mount. All BF_* env vars removed from compose server service. deploy/docker/sec-config.yaml deleted (was baked in, now mounted). version.ts path updated for new workdir /app. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
49d730cf7f
commit
34331c9d0e
5 changed files with 29 additions and 114 deletions
|
|
@ -1,11 +1,16 @@
|
||||||
# BetterFrame server image — Node 24 + native deps for argon2/sqlite.
|
# BetterFrame server — BSB container with built plugins.
|
||||||
# Trixie base (Debian 13, latest stable) — matches the host distro we
|
#
|
||||||
# recommend in deploy/README.md.
|
# sec-config.yaml is NOT baked in — mount it at runtime:
|
||||||
|
# volumes:
|
||||||
|
# - ./sec-config.yaml:/app/sec-config.yaml:ro
|
||||||
|
#
|
||||||
|
# Builder stage compiles TS + native deps (argon2).
|
||||||
|
# Runtime stage uses the official BSB container.
|
||||||
|
|
||||||
FROM node:24-trixie-slim AS builder
|
FROM node:24-trixie-slim AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Build deps for argon2 + bsb-plugin-cli
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
build-essential python3 \
|
build-essential python3 \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
@ -17,48 +22,40 @@ RUN npm ci && npm rebuild argon2
|
||||||
|
|
||||||
COPY server ./server
|
COPY server ./server
|
||||||
|
|
||||||
# Run BSB build — extracts schemas + compiles TS + generates plugin manifests
|
|
||||||
WORKDIR /app/server
|
WORKDIR /app/server
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# ---- Runtime image ----
|
# ---- Runtime ----
|
||||||
FROM node:24-trixie-slim
|
FROM betterweb/service-base:node
|
||||||
|
|
||||||
# Version baked at build time. Coolify doesn't include .git in build context
|
|
||||||
# so we can't derive from git inside Docker. Instead, compose passes it as a
|
|
||||||
# build arg from SOURCE_COMMIT / COOLIFY_GIT_COMMIT env vars that Coolify
|
|
||||||
# DOES inject into the build environment.
|
|
||||||
ARG BF_SERVER_VERSION=dev
|
ARG BF_SERVER_VERSION=dev
|
||||||
|
|
||||||
# ffmpeg for camera snapshot capture (optional but needed for /admin/entities/:id/snapshot)
|
USER root
|
||||||
|
|
||||||
|
# ffmpeg for camera snapshot capture
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
ca-certificates ffmpeg wget \
|
ffmpeg \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN useradd -m -d /var/lib/betterframe -s /bin/false betterframe
|
RUN mkdir -p /var/lib/betterframe && chown node:node /var/lib/betterframe
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy built plugin + deps
|
||||||
COPY --from=builder /app/node_modules ./node_modules
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
COPY --from=builder /app/server ./server
|
COPY --from=builder /app/server/lib ./lib
|
||||||
COPY --from=builder /app/tsconfig.base.json ./
|
COPY --from=builder /app/server/bsb-plugin.json ./bsb-plugin.json
|
||||||
COPY --from=builder /app/package.json ./
|
COPY --from=builder /app/server/package.json ./package.json
|
||||||
|
COPY --from=builder /app/tsconfig.base.json ./tsconfig.base.json
|
||||||
|
|
||||||
# Default sec-config baked into image. BF_* env vars in compose override at
|
# Static web assets served by admin-http
|
||||||
# runtime (see shared/env-overrides.ts). No host bind mount needed.
|
COPY --from=builder /app/server/lib/web-static ./lib/web-static
|
||||||
COPY deploy/docker/sec-config.yaml /app/server/sec-config.yaml
|
|
||||||
|
|
||||||
# Bake version into a file readable by version.ts at runtime.
|
# Bake version
|
||||||
RUN echo "$BF_SERVER_VERSION" > /app/server/.bf-version
|
RUN echo "$BF_SERVER_VERSION" > /app/.bf-version
|
||||||
|
|
||||||
RUN mkdir -p /var/lib/betterframe && chown betterframe:betterframe /var/lib/betterframe
|
|
||||||
VOLUME /var/lib/betterframe
|
VOLUME /var/lib/betterframe
|
||||||
|
|
||||||
EXPOSE 18080 18081 18082
|
EXPOSE 18080 18081 18082
|
||||||
|
|
||||||
USER betterframe
|
USER node
|
||||||
WORKDIR /app/server
|
|
||||||
|
|
||||||
ENV NODE_OPTIONS=--import=tsx
|
|
||||||
|
|
||||||
CMD ["node", "--import", "tsx", "/app/node_modules/@bsb/base/lib/scripts/bsb-plugin-cli.js", "start"]
|
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# BSB runtime configuration for the Docker compose stack.
|
|
||||||
# Backend services bind all interfaces inside the private compose network;
|
|
||||||
# Angie/nginx is the only published host port.
|
|
||||||
|
|
||||||
default:
|
|
||||||
observable:
|
|
||||||
observable-default:
|
|
||||||
plugin: observable-default
|
|
||||||
enabled: true
|
|
||||||
config: {}
|
|
||||||
events:
|
|
||||||
events-default:
|
|
||||||
plugin: events-default
|
|
||||||
enabled: true
|
|
||||||
services:
|
|
||||||
service-store:
|
|
||||||
plugin: service-store
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
sqlitePath: /var/lib/betterframe/betterframe.db
|
|
||||||
|
|
||||||
service-admin-http:
|
|
||||||
plugin: service-admin-http
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
host: 0.0.0.0
|
|
||||||
port: 18080
|
|
||||||
dataDir: /var/lib/betterframe
|
|
||||||
sessionIdleSeconds: 43200
|
|
||||||
sessionMaxSeconds: 2592000
|
|
||||||
loginLockoutThreshold: 8
|
|
||||||
loginLockoutSeconds: 900
|
|
||||||
argon2Memory: 65536
|
|
||||||
argon2TimeCost: 3
|
|
||||||
argon2Parallelism: 2
|
|
||||||
cookieName: betterframe_session
|
|
||||||
totpIssuer: BetterFrame
|
|
||||||
noderedUrl: http://nodered:1880
|
|
||||||
selfUrl: http://server:18080
|
|
||||||
|
|
||||||
service-api-http:
|
|
||||||
plugin: service-api-http
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
host: 0.0.0.0
|
|
||||||
port: 18081
|
|
||||||
codeTtlSeconds: 600
|
|
||||||
dataDir: /var/lib/betterframe
|
|
||||||
argon2Memory: 65536
|
|
||||||
argon2TimeCost: 3
|
|
||||||
argon2Parallelism: 2
|
|
||||||
noderedUrl: http://nodered:1880
|
|
||||||
|
|
||||||
service-coordinator-ws:
|
|
||||||
plugin: service-coordinator-ws
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
host: 0.0.0.0
|
|
||||||
port: 18082
|
|
||||||
noderedUrl: http://nodered:1880
|
|
||||||
dataDir: /var/lib/betterframe
|
|
||||||
cookieName: betterframe_session
|
|
||||||
argon2Memory: 65536
|
|
||||||
argon2TimeCost: 3
|
|
||||||
argon2Parallelism: 2
|
|
||||||
|
|
@ -25,6 +25,7 @@ services:
|
||||||
- TZ=UTC
|
- TZ=UTC
|
||||||
volumes:
|
volumes:
|
||||||
- betterframe-data:/var/lib/betterframe
|
- betterframe-data:/var/lib/betterframe
|
||||||
|
- ./sec-config.yaml:/app/sec-config.yaml:ro
|
||||||
expose:
|
expose:
|
||||||
- "18080"
|
- "18080"
|
||||||
- "18081"
|
- "18081"
|
||||||
|
|
|
||||||
|
|
@ -31,29 +31,11 @@ services:
|
||||||
BF_SERVER_VERSION: ${BF_SERVER_VERSION:-}
|
BF_SERVER_VERSION: ${BF_SERVER_VERSION:-}
|
||||||
container_name: betterframe-server
|
container_name: betterframe-server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Env overrides win over sec-config.yaml — Coolify / k8s inject these.
|
|
||||||
environment:
|
environment:
|
||||||
- TZ=UTC
|
- TZ=UTC
|
||||||
- BF_DATA_DIR=/var/lib/betterframe
|
|
||||||
- BF_SQLITE_PATH=/var/lib/betterframe/betterframe.db
|
|
||||||
- BF_NODERED_URL=http://nodered:1880
|
|
||||||
- BF_SELF_URL=http://server:18080
|
|
||||||
- BF_SERVER_VERSION=${BF_SERVER_VERSION:-}
|
|
||||||
- COOLIFY_GIT_COMMIT=${COOLIFY_GIT_COMMIT:-}
|
|
||||||
- SOURCE_COMMIT=${SOURCE_COMMIT:-}
|
|
||||||
# Optional: paste Ed25519 PEM private key here for firmware signing.
|
|
||||||
# - BF_FIRMWARE_SIGNING_KEY=
|
|
||||||
# Optional: single-purpose Bearer token for GitHub Actions firmware import.
|
|
||||||
# Set GitHub's BF_AUTOIMPORT_API_KEY secret to the same value.
|
|
||||||
# Generate with: openssl rand -base64 32
|
|
||||||
# - BF_FIRMWARE_IMPORT_API_KEY=
|
|
||||||
# Optional MQTT telemetry bridge (ThingsBoard / HA / Influx / etc).
|
|
||||||
# - BF_MQTT_URL=mqtt://broker:1883
|
|
||||||
# - BF_MQTT_USERNAME=
|
|
||||||
# - BF_MQTT_PASSWORD=
|
|
||||||
# - BF_MQTT_TOPIC_PREFIX=betterframe
|
|
||||||
volumes:
|
volumes:
|
||||||
- betterframe-data:/var/lib/betterframe
|
- betterframe-data:/var/lib/betterframe
|
||||||
|
- ./sec-config.yaml:/app/sec-config.yaml:ro
|
||||||
expose:
|
expose:
|
||||||
- "18080"
|
- "18080"
|
||||||
- "18081"
|
- "18081"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ let cached: string | null = null;
|
||||||
export function serverVersion(): string {
|
export function serverVersion(): string {
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
try {
|
try {
|
||||||
const v = readFileSync("/app/server/.bf-version", "utf8").trim();
|
const v = readFileSync("/app/.bf-version", "utf8").trim();
|
||||||
cached = v && v !== "dev" ? v : "dev";
|
cached = v && v !== "dev" ? v : "dev";
|
||||||
} catch {
|
} catch {
|
||||||
cached = "dev";
|
cached = "dev";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue