Skip to content

deploy: one-command deploy, tracked stack, no secrets in git - #2

Merged
Harrsn merged 4 commits into
mainfrom
faucet-deploy-script
Sep 16, 2026
Merged

Harrsn merged 4 commits into
mainfrom
faucet-deploy-script

Conversation

@Harrsn

@Harrsn Harrsn commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Turns the manual three-step deploy — git pull, docker build by hand, click
redeploy in Portainer — into one command, and gets the stack definition out of
Portainer's data dir and into git.

Changes

  • deploy/deploy.sh — fast-forward the checkout, rebuild faucet:local,
    compose up -d --force-recreate faucet, verify the container is running.
    Exits non-zero on failure so a broken deploy reports as broken.
  • deploy/stack.yml — the compose definition, with no secrets.
  • deploy/faucet.secrets.env.example — template for SESSION_SECRET.
  • deploy/README.md — install steps and the config layering.

Why the stack file shrank so much

config.py::_load_persisted() reads /config/faucet.env and writes its keys
into os.environ at import, so it overrides whatever the container was
started with. Every WIZARD_KEYS entry in the old inline environment: block
was therefore dead weight that looked authoritative — JACKETT_URL,
CLIENT_*, NOTIFY_*, UI_*, APP_TITLE, the path keys. Dropped. What
remains is the structural set the wizard deliberately excludes, plus
SESSION_SECRET via env_file.

The practical consequence, documented in the README: rotating a credential at
its source and updating compose is not enough while faucet.env still
defines it.

Two things that are load-bearing, not style

  • --force-recreate: the image tag never changes, so without it compose sees
    no reason to replace the container and the deploy silently no-ops.
  • Install deploy.sh to /usr/local/sbin/faucet-deploy, root-owned. The
    checkout belongs to the ops account, so a NOPASSWD sudoers rule pointing
    at the repo path would let that account rewrite the script and get root.

Note on Portainer: it still displays the stack, but its "Update the stack"
button now redeploys from its own stale copy. Use the script. Portainer can't
run this deploy itself — it mounts only the Docker socket and its data dir, so
neither a build: context at /opt/faucet nor a host-path env_file: would
resolve from inside it.

Replaces the manual three-step: git pull, docker build by hand, click
redeploy in Portainer. Fails loudly rather than half-deploying -- ff-only
merge so a diverged checkout stops instead of merging, and set -e throughout.

Install to /usr/local/sbin/faucet-deploy root-owned 755; see deploy/README.md
for why it must not be sudo'd from its repo path.
The live stack lived only in Portainer's data dir and carried the Jackett
key, Transmission password, Discord webhook and session secret inline --
unreadable without root and unsafe to paste anywhere.

Everything in config.py's WIZARD_KEYS is dropped: faucet.env is loaded *over*
process env, so those compose values were dead weight that only looked
authoritative. What remains is the structural set the wizard deliberately
excludes, plus SESSION_SECRET via env_file.
@Harrsn
Harrsn merged commit c279c00 into main Sep 16, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant