You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.6 KiB
102 lines
3.6 KiB
# CamMonitor — production / staging compose file
|
|
#
|
|
# Copy this file to the target server and run:
|
|
# docker compose -f docker-staging-prod.yaml up -d
|
|
#
|
|
# Mandatory values to change before first run (marked with CHANGE_ME):
|
|
# FOOTAGE_ROOT — absolute path to the camera footage directory on this host
|
|
# ADMIN_PASS — strong password for the bootstrap admin account
|
|
#
|
|
# The image is pulled from your local registry; make sure the host can reach
|
|
# 192.168.1.11:5000 and has it listed in /etc/docker/daemon.json:
|
|
# { "insecure-registries": ["192.168.1.11:5000"] }
|
|
|
|
services:
|
|
app:
|
|
image: 192.168.1.11:5000/cammonitor:latest
|
|
restart: unless-stopped
|
|
|
|
ports:
|
|
- "127.0.0.1:8080:8080" # Bind to loopback only — expose via reverse proxy.
|
|
# Change to "0.0.0.0:8080:8080" if you access
|
|
# the app directly without a proxy in front.
|
|
|
|
environment:
|
|
LISTEN_ADDR: ":8080"
|
|
|
|
# Absolute path on the HOST that contains the dated footage folders.
|
|
# Example: /mnt/cams → /mnt/cams/20260518/images/…
|
|
FOOTAGE_ROOT: /footage # CHANGE_ME — set to your real footage path
|
|
|
|
DB_PATH: /data/cammonitor.db
|
|
|
|
# Bootstrap admin created on first start only (no effect if DB already exists).
|
|
ADMIN_USER: admin
|
|
ADMIN_PASS: changeme # CHANGE_ME — use a strong password
|
|
|
|
SESSION_TTL: 24h # How long a login session lasts
|
|
SCAN_INTERVAL: 5m # How often the footage tree is re-scanned
|
|
|
|
volumes:
|
|
# Footage directory — mounted read-only so the app can never modify recordings.
|
|
- /path/to/footage:/footage:ro # CHANGE_ME — replace left side with real path
|
|
|
|
# Persistent data (SQLite database).
|
|
- cammonitor_data:/data
|
|
|
|
# Drop all Linux capabilities the Go binary does not need.
|
|
cap_drop:
|
|
- ALL
|
|
|
|
# The app only needs to bind a TCP port; no other privileges required.
|
|
cap_add:
|
|
- NET_BIND_SERVICE
|
|
|
|
# Read-only root filesystem — the only writable surface is the /data volume.
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp:size=64m,mode=1777 # Needed by the Go runtime for temp files
|
|
|
|
# Prevent the container from gaining new privileges via setuid/setgid binaries.
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
# CPU/memory limits — tuned for a 4-core Intel Atom running ffmpeg transcode.
|
|
# cpus limit: allow all 4 cores so the H.265→H.264 transcode can use
|
|
# multi-threaded decoding and encoding simultaneously.
|
|
# Lower this (e.g. "2.0") if other services share the host and you want
|
|
# to guarantee headroom for them.
|
|
# memory: 512M covers the Go process + one active ffmpeg transcode at 1080p.
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: "4.0"
|
|
memory: 512M
|
|
reservations:
|
|
cpus: "1.0"
|
|
memory: 128M
|
|
|
|
# Aggressive health-check so the orchestrator restarts a hung container fast.
|
|
healthcheck:
|
|
test: ["CMD", "cammonitor", "-health-check"]
|
|
# Fallback if the binary has no -health-check flag — use wget instead:
|
|
# test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/health || exit 1"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
volumes:
|
|
cammonitor_data:
|
|
driver: local
|
|
# Optional: pin the volume to a specific host path so backups are predictable.
|
|
# driver_opts:
|
|
# type: none
|
|
# o: bind
|
|
# device: /var/lib/cammonitor/data
|
|
|