furtka-gateway/.env.example
Robert Syrnicki 8eebae8e1e ci: publish control-plane image for Swarm deploys
Swarm ignores docker-compose.yaml's build: key, so docker stack deploy
previously needed an operator to build and tag the control-plane image
by hand. CI now publishes it to this instance's container registry on
every push to master (or a tag), and docker-compose.yaml's image: key
(overridable via GATEWAY_CONTROL_PLANE_IMAGE) lets Swarm pull it directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0142mP6EqCkQKmR1xCp7zfmZ
2026-08-26 12:20:16 +02:00

56 lines
2.8 KiB
Text

# Which cert/tenancy strategy to run: "single" or "shared".
# See traefik/static/traefik.single.yml vs traefik.shared.yml.
GATEWAY_MODE=single
# The hostname (or IP, for a first local smoke test) wg-easy advertises to
# peers as the WireGuard endpoint. Must be reachable on udp/51820.
GATEWAY_PUBLIC_HOST=vpn.example.com
# bcrypt hash of the wg-easy admin password. Generate with:
# docker run --rm ghcr.io/wg-easy/wg-easy:14 node -e \
# "console.log(require('bcryptjs').hashSync(process.argv[1], 10))" 'your-password'
#
# IMPORTANT: bcrypt hashes contain literal `$` characters (e.g.
# "$2a$10$..."), and Docker Compose's own .env-file parser treats `$word`
# as a variable reference to substitute — confirmed by actually hitting
# this: an unescaped hash silently got truncated to "$2a$10" with
# everything after dropped. Every `$` in the value below MUST be doubled
# as `$$`, e.g. WG_EASY_PASSWORD_HASH=$$2a$$10$$abc123...
WG_EASY_PASSWORD_HASH=
# PLAINTEXT password matching the hash above. wg-easy's admin API (this
# specific pinned image, ghcr.io/wg-easy/wg-easy:14 — confirmed by reading
# its actual source, which turned out to differ from what wg-easy's current
# docs describe) has no login call or session cookie at all: every request
# just carries this password as a plain `Authorization` header, checked
# with bcrypt against WG_EASY_PASSWORD_HASH. No username concept exists.
WG_EASY_ADMIN_PASSWORD=
# GATEWAY_MODE=single only: the one box token a single-tenant deployment
# accepts at /v1/boxes/register, skipping full account/registration-token
# issuance. Generate with: openssl rand -hex 32
GATEWAY_BOX_TOKEN=
# Hostname a Furtka box actually reaches the control-plane API on — needs
# its own A/AAAA record pointing at this VPS. Not read by docker-compose
# itself; it's a reminder of what to substitute into
# traefik/dynamic/control-plane.yml (copied from the .example file — see
# that file for why this route has to exist at all).
GATEWAY_CONTROL_PLANE_HOST=gw.example.com
# Bearer token required to create accounts via POST /v1/accounts.
# Only meaningful once account endpoints exist (Phase 2+); harmless to set
# now. Generate with: openssl rand -hex 32
GATEWAY_ADMIN_TOKEN=
# GATEWAY_MODE=shared only: base domain subdomains are issued under, and the
# DNS provider Traefik's DNS-01 challenge should use for the wildcard cert.
# See traefik/static/traefik.shared.yml.
GATEWAY_BASE_DOMAIN=boxes.example.com
# Optional: override the control-plane image `docker stack deploy` pulls
# (Swarm ignores docker-compose.yaml's `build:` key — see README's Swarm
# caveats). Defaults to the `latest` tag CI publishes on every push to
# master; pin to a specific commit-sha tag for a reproducible deploy.
# Not read by plain `docker compose up`, which always builds locally.
GATEWAY_CONTROL_PLANE_IMAGE=