Files
plm-lottery/.env.example
T
davideandClaude Sonnet 5.5 c1b192f6d1 Harden the container: non-root, pinned images and dependencies, the key in a file (B-91, SEC-51, SEC-52, SEC-53; closes B-71, B-72)
- app runs as uid 1000; a one-shot data-permissions service chowns ./data to it
  and closes it to others (works on an older root-owned install with no host sudo);
  files are created 0600 (umask 077)
- python:3.12-slim and caddy:2-alpine pinned by digest; dependencies installed from
  requirements.lock with --require-hashes
- the Fernet key is XPRV_ENCRYPTION_KEY_FILE (./secrets/xprv_encryption.key, a compose
  secret), out of every environment variable and of a ./data backup
- setup.md no longer presents a second way to run the server (B-72)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 00:54:23 +02:00

63 lines
3.2 KiB
Bash

ELECTRUM_HOST=santantonio.sytes.net
ELECTRUM_PORT=50002
ELECTRUM_USE_SSL=true
# Additional Electrum servers to fall back to, comma-separated. Each entry is
# `host:port` (TLS, the normal case), `host:port:notls`, or `host:port:pin=<sha256>`
# (TLS, and the server's DER certificate must hash to that SHA-256, in hex). The
# listener rotates over the primary above plus these, so one unreachable server costs
# a single reconnect attempt instead of an outage — every deposit credit, broadcast and
# confirmation goes through this one connection, which makes a single server the
# platform's biggest single point of failure. A typo here fails at startup rather
# than during the outage when the fallback is what you need.
#
# AT LEAST 2 are required (B-84): every decision that moves money is corroborated by
# the *other* servers and needs two independent answers, so with fewer than two
# fallbacks the server refuses to start (override: ALLOW_NO_QUORUM, development only).
# Configure three or more in production, so one being down does not stop the lottery.
#
# These are the mainnet bootstrap servers from the PalladiumWallet repo
# (src/Core/Chain/ChainProfiles.cs, ChainProfiles.Mainnet.BootstrapServers) — the
# same ones the reference wallet falls back to:
ELECTRUM_FALLBACK_SERVERS=173.212.224.67:50002,144.91.120.225:50002,66.94.115.80:50002,89.117.149.130:50002
# Optional: SHA-256 (hex) of the primary server's DER certificate. A connection that
# presents another certificate fails like an unreachable server. Empty = not pinned.
ELECTRUM_CERT_PIN=
# Development only: start with fewer than 2 fallback servers (corroboration then falls
# back to the weak rule: a single answer decides, or nothing is checked at all).
# NEVER true in production.
ALLOW_NO_QUORUM=false
# File holding the Fernet key that protects the master xprv at rest (B-91): in a file, not in
# an environment variable, so `docker inspect` cannot show it and a backup of ./data does not
# carry both. Inside the container docker-compose.yml mounts it as a secret and overrides
# this path. Create it once:
# mkdir -p secrets && chmod 700 secrets
# python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" > secrets/xprv_encryption.key
# chmod 600 secrets/xprv_encryption.key
XPRV_ENCRYPTION_KEY_FILE=./secrets/xprv_encryption.key
# Random secret for JWT session signing. Generate with:
# python -c "import secrets; print(secrets.token_urlsafe(32))"
JWT_SECRET=
# Bearer token required on the admin endpoints (X-Admin-Token header). Generate with:
# python -c "import secrets; print(secrets.token_urlsafe(32))"
ADMIN_TOKEN=
# Every business/round parameter (bet amount, round duration/cooldown, min
# amount, fee rate, RBF timeout, fee address) is configured live from the
# admin panel (/admin) instead of here — see docs/guida-admin.md.
# Swagger/ReDoc/the raw OpenAPI JSON expose the entire API surface — admin
# endpoints included — to anyone who requests them. Off by default; set to
# true only for local development, never in production.
ENABLE_API_DOCS=false
# Start with the lottery paused (as the operator's pause, audit-logged), e.g. after
# restoring a backup: nothing opens a round until you resume from /admin. See
# docs/operativita.md (OPS-27).
START_PAUSED=false