summaryrefslogtreecommitdiff
path: root/docs/production-local.md
blob: c7c80fdfac566c53752734be869bbaadf0212ad3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
# Isolated local production candidate

Persistent unit `strategy-lab-production.service` uses copied release binary/frontend under `~/.local/share/strategy-lab-production/release`, listening only on http://127.0.0.1:8789. QA stays on8787. Public HTTPS entry is https://fin.somhairle.bid through the existing Cloudflare tunnel; only this hostname was appended before the existing 404 fallback. Existing dav/git/linkwarden routes and http2 were preserved.

Mode0600 files `runtime.env` and `admin.private.json` live in that mode0700 state directory. Owner retrieves credentials locally; never paste into logs/chat. Bootstrap credentials were supplied only to initial bootstrap process, absent from persistent runtime env. Clean DB has one admin and no QA data.

Explicit domain authorization is recorded in docs/domain-authorization-user.md and supersedes earlier domain blockers. Runtime ORIGIN=https://fin.somhairle.bid; production was restarted and secure-cookie/authentication/exact-origin rejection verified before exposure. Public browser form login, Secure/HttpOnly session cookies, foreign-origin403, first-party JS/CSS release hash equality and desktop/mobile rendering pass. DNS route exact tunnel readback and ingress validation pass. Evidence: artifacts/qa/supervisor-live/{public-verification.json,release-acceptance.json,qa_public.py}. External Cloudflare analytics script is recorded separately from first-party release files.

SQLite initial online backup passed independently reopened integrity/count checks. Populated QA database/object backup and isolated restore-service verification passed: exact object SHA-256 equality, SQLite integrity, populated entity counts, all ready dataset object references, restored login/draft/preview/run results. Runnable verifier and evidence: artifacts/qa/supervisor-live/{qa_backup_restore.py,backup-restore-checks.json}. Private snapshots remain under the mode0700 cache directory named in evidence, never in source control. Procedure: ensure no pending/running work, stop the exact source service, SQLite backup plus copy data/objects, restart source, copy snapshot to a separate directory, verify integrity/hashes before launching a loopback-only restore with DB_PATH/DATA_DIR pointing at that copy. Never overwrite live DB or mix QA into production. Production uses persistent systemctl start; QA uses a transient unit which disappears after stop and must be recreated via the exact launcher command in the verifier. Restored instance was terminated after checks; production was untouched. Do not restore over a running DB. Unit is enabled and loginctl confirms Linger=yes. Independently restarted the exact production unit: new PID, copied release executable confirmed, actual HTTP health ready in0.061s. A physical host reboot has not been performed.

Measured seven systemd cgroup samples over30.050s immediately after restart: memory2,416,640–12,435,456 bytes, settling to2,416,640 bytes; CPU0.06393% of one core over that interval. These are idle service measurements, exclude Docker job memory and do not predict backtest load. Runnable verifier and raw samples: artifacts/qa/supervisor-live/{qa_production_persistence.py,production-persistence-checks.json}.

Operations: systemctl --user status/restart strategy-lab-production. Limits: one backtest/one fetch,120s fetch/60s backtest deadlines. Trusted invited-user Docker POC, no hostile public sandbox claim. Evidence: artifacts/qa/supervisor-live/production-local-checks.json.