Some checks failed
Build control-plane image / build-image (push) Has been cancelled
Restructure the deployment model: instead of bundling and owning its own Traefik + wg-easy, the control-plane now plugs into a Traefik and wg-easy the operator already runs (as sibling containers, or otherwise reachable). This avoids duplicating infra self-hosters commonly already have, and sidesteps having to run a second ACME/DNS setup entirely — the operator's own Traefik already has a working cert resolver. - New control_plane/wgeasy_v15.py: a wg-easy v15 REST client, verified live against a real running container (auth model, route shapes, and the new per-client PresharedKey all differ materially from v14's API). Threaded the preshared key through to the box side (furtka/wireguard.py in the furtka repo) so v15's handshake actually completes. - GATEWAY_CERT_RESOLVER is now a real env var instead of a GATEWAY_MODE- derived hardcoded "le", so it can mirror whatever resolver name (if any) the operator's own Traefik already has configured. - Root docker-compose.yaml/ops/deploy.sh: control-plane only now. deploy.sh asks how the operator's Traefik reaches it (same docker network, joined via `docker network connect`, or a separate host) instead of prompting for DNS-01 providers and port remaps single-parallel mode needed. - single-parallel mode is retired outright — nothing needs it once furtka-gateway doesn't own a second Traefik/wg-easy to remap ports for. - The old bundled stack (own Traefik+wg-easy, HTTP-01) moves to examples/starter-stack/ as the documented zero-infra on-ramp. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3jVwAqESRjPdW9P9nvfem
96 lines
4.8 KiB
Text
96 lines
4.8 KiB
Text
# Filling this file in by hand? Run `ops/deploy.sh` instead — it prompts
|
|
# for the values below, generates the tokens, and renders
|
|
# traefik/dynamic/control-plane.yml from its tracked template. Read the
|
|
# README's Prerequisites checklist first either way.
|
|
|
|
# Tenancy switch only — "single" (one operator, the common case) or
|
|
# "shared" (multi-tenant, out of scope for most deployments). Has no
|
|
# effect on ports, certs, or infrastructure — that's all your own
|
|
# Traefik/wg-easy now, configured below.
|
|
GATEWAY_MODE=single
|
|
|
|
# YOUR wg-easy's admin API — reachable at whatever host:port makes sense
|
|
# for your setup. If it's a sibling container that joined the same docker
|
|
# network as this control-plane (see GATEWAY_TRAEFIK_NETWORK below), this
|
|
# is usually http://<its-container-name>:51821.
|
|
WG_EASY_URL=http://wg-easy:51821
|
|
|
|
# "14" or "15" — these are genuinely different, incompatible wg-easy APIs
|
|
# (see control_plane/wgeasy.py vs wgeasy_v15.py's module docstrings, each
|
|
# independently verified against a real running container). Check your
|
|
# wg-easy image's actual tag.
|
|
WG_EASY_API_VERSION=14
|
|
|
|
# v15 only: the admin user's username. v14 has no username concept — see
|
|
# WG_EASY_ADMIN_PASSWORD below, used alone in that case.
|
|
WG_EASY_ADMIN_USERNAME=
|
|
|
|
# PLAINTEXT password for wg-easy's admin API — never a hash, on either
|
|
# version. v14 sends this as a bare `Authorization` header (no username,
|
|
# no session — confirmed by reading the actual pinned image's source,
|
|
# which differs from what wg-easy's current docs describe). v15 sends it
|
|
# as HTTP Basic auth alongside WG_EASY_ADMIN_USERNAME.
|
|
WG_EASY_ADMIN_PASSWORD=
|
|
|
|
# v15 only: restricts new WireGuard clients to this subnet instead of
|
|
# v15's full-tunnel default (0.0.0.0/0, ::/0) — see wgeasy_v15.py's
|
|
# restrict_default_allowed_ips(), applied on every control-plane startup.
|
|
# Should match your wg-easy's actual WireGuard peer subnet.
|
|
GATEWAY_WG_ALLOWED_IPS=10.8.0.0/24
|
|
|
|
# Host directory YOUR Traefik's file provider already watches (or a new
|
|
# one you add as an *additional* providers.file directory in its static
|
|
# config — additive, doesn't touch your existing dynamic config). This
|
|
# gets bind-mounted into the control-plane container.
|
|
GATEWAY_DYNAMIC_DIR_HOST=./dynamic
|
|
|
|
# Your Traefik's certResolver name — mirrored into every route
|
|
# furtka-gateway publishes. Blank means no explicit resolver (`tls: {}`),
|
|
# trusting your Traefik to apply its own default cert automatically (e.g.
|
|
# a wildcard defaultGeneratedCert). Set this if your Traefik doesn't have
|
|
# a default and needs an explicit resolver named per-route.
|
|
GATEWAY_CERT_RESOLVER=
|
|
|
|
# Hostname a Furtka box actually reaches the control-plane API on — needs
|
|
# its own A/AAAA record pointing at wherever your Traefik is reachable.
|
|
# Not read by docker-compose itself; it's what ops/deploy.sh substitutes
|
|
# into traefik/dynamic/control-plane.yml.
|
|
GATEWAY_CONTROL_PLANE_HOST=gw.example.com
|
|
|
|
# Where the control-plane's own API is bound (docker-compose.yaml's port
|
|
# publish) and where your Traefik reaches it, respectively. Same value
|
|
# for the recommended same-docker-network setup (ops/deploy.sh sets both
|
|
# to furtka-gateway-control-plane:8090 automatically, with the bind
|
|
# staying loopback-only — see docker-compose.yaml's comment on why this
|
|
# is more robust than the compose *service* name "control-plane" once the
|
|
# network is joined after the fact via `docker network connect`).
|
|
# Different values only for a separate-host setup, where
|
|
# GATEWAY_CONTROL_PLANE_BIND must be widened beyond 127.0.0.1 — put real
|
|
# access control around that bind address, this file carries a WireGuard
|
|
# private key in its registration responses.
|
|
GATEWAY_CONTROL_PLANE_BIND=127.0.0.1:8090
|
|
GATEWAY_CONTROL_PLANE_TARGET=furtka-gateway-control-plane:8090
|
|
|
|
# Same-docker-network setup only (the recommended path — see the README's
|
|
# Prerequisites checklist): your Traefik's docker network name
|
|
# (`docker network ls` / `docker inspect <your-traefik-container>`).
|
|
# ops/deploy.sh runs `docker network connect` with this after bringing the
|
|
# stack up. Leave blank for a separate-host setup.
|
|
GATEWAY_TRAEFIK_NETWORK=
|
|
|
|
# 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=
|
|
|
|
# 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=
|
|
|
|
# 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=
|