|
|
|
@@ -50,6 +50,8 @@ set -euo pipefail
|
|
|
|
|
: "${POCKETID_DOMAIN:=}"
|
|
|
|
|
: "${OIDC_CLIENT_ID:=}"
|
|
|
|
|
: "${OIDC_CLIENT_SECRET:=}"
|
|
|
|
|
: "${HEADPLANE_OIDC_CLIENT_ID:=}" # optional: headplane UI OIDC login
|
|
|
|
|
: "${HEADPLANE_OIDC_CLIENT_SECRET:=}"
|
|
|
|
|
|
|
|
|
|
log() { printf '\033[1;32m[+]\033[0m %s\n' "$*"; }
|
|
|
|
|
warn() { printf '\033[1;33m[!]\033[0m %s\n' "$*" >&2; }
|
|
|
|
@@ -110,6 +112,35 @@ open_web_ports() {
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Write headplane's config to $STACK_DIR/headplane.yaml from the current .env
|
|
|
|
|
# values. OIDC is enabled only when a client id + secret are present; otherwise
|
|
|
|
|
# headplane falls back to API-key login. Mode is API-only (no Docker socket).
|
|
|
|
|
render_headplane_config() {
|
|
|
|
|
local oidc_enabled=false
|
|
|
|
|
[[ -n "${HEADPLANE_OIDC_CLIENT_ID:-}" && -n "${HEADPLANE_OIDC_CLIENT_SECRET:-}" ]] && oidc_enabled=true
|
|
|
|
|
( umask 077
|
|
|
|
|
cat > "$STACK_DIR/headplane.yaml" <<EOF
|
|
|
|
|
# Generated by deploy.sh -- do not edit by hand (regenerated each run from .env).
|
|
|
|
|
server:
|
|
|
|
|
host: "0.0.0.0"
|
|
|
|
|
port: 3000
|
|
|
|
|
base_url: "https://${HEADSCALE_DOMAIN}"
|
|
|
|
|
cookie_secret: "${HEADPLANE_COOKIE_SECRET}"
|
|
|
|
|
cookie_secure: true
|
|
|
|
|
headscale:
|
|
|
|
|
url: "http://headscale:8080"
|
|
|
|
|
api_key: "${HEADPLANE_HS_API_KEY:-}"
|
|
|
|
|
oidc:
|
|
|
|
|
enabled: ${oidc_enabled}
|
|
|
|
|
issuer: "https://${POCKETID_DOMAIN}"
|
|
|
|
|
client_id: "${HEADPLANE_OIDC_CLIENT_ID:-}"
|
|
|
|
|
client_secret: "${HEADPLANE_OIDC_CLIENT_SECRET:-}"
|
|
|
|
|
use_pkce: true
|
|
|
|
|
EOF
|
|
|
|
|
)
|
|
|
|
|
chmod 600 "$STACK_DIR/headplane.yaml"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
# Extract embedded archive
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
@@ -189,6 +220,9 @@ if [[ ! -f "$ENV_FILE" ]]; then
|
|
|
|
|
-e "s|^POCKETID_DOMAIN=.*|POCKETID_DOMAIN=${POCKETID_DOMAIN}|" \
|
|
|
|
|
-e "s|^OIDC_CLIENT_ID=.*|OIDC_CLIENT_ID=${OIDC_CLIENT_ID}|" \
|
|
|
|
|
-e "s|^OIDC_CLIENT_SECRET=.*|OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}|" \
|
|
|
|
|
-e "s|^HEADPLANE_COOKIE_SECRET=.*|HEADPLANE_COOKIE_SECRET=$(openssl rand -hex 16)|" \
|
|
|
|
|
-e "s|^HEADPLANE_OIDC_CLIENT_ID=.*|HEADPLANE_OIDC_CLIENT_ID=${HEADPLANE_OIDC_CLIENT_ID}|" \
|
|
|
|
|
-e "s|^HEADPLANE_OIDC_CLIENT_SECRET=.*|HEADPLANE_OIDC_CLIENT_SECRET=${HEADPLANE_OIDC_CLIENT_SECRET}|" \
|
|
|
|
|
"$ENV_FILE"
|
|
|
|
|
else
|
|
|
|
|
log ".env exists; leaving it alone."
|
|
|
|
@@ -223,6 +257,10 @@ else
|
|
|
|
|
log "ACL policy exists; leaving $STACK_DIR/policy.hujson alone."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Render headplane.yaml now so the bind mount exists (api_key may still be
|
|
|
|
|
# empty on first run; it's re-rendered after the key is minted below).
|
|
|
|
|
render_headplane_config
|
|
|
|
|
|
|
|
|
|
# Escape replacement values for sed (handle slashes/&). Headscale URLs and
|
|
|
|
|
# OIDC secrets can contain those.
|
|
|
|
|
sed_escape() { printf '%s' "$1" | sed -e 's/[\/&]/\\&/g'; }
|
|
|
|
@@ -266,7 +304,40 @@ cd "$STACK_DIR"
|
|
|
|
|
log "Pulling images..."
|
|
|
|
|
docker compose pull
|
|
|
|
|
|
|
|
|
|
log "Starting stack..."
|
|
|
|
|
# Start headscale + caddy first; headplane needs a headscale API key, which we
|
|
|
|
|
# can only mint once headscale is up.
|
|
|
|
|
log "Starting headscale + caddy..."
|
|
|
|
|
docker compose up -d --remove-orphans headscale caddy
|
|
|
|
|
|
|
|
|
|
log "Waiting for headscale to become healthy (up to 120s)..."
|
|
|
|
|
deadline=$(( $(date +%s) + 120 ))
|
|
|
|
|
while (( $(date +%s) < deadline )); do
|
|
|
|
|
h=$(docker compose ps --format '{{.Service}} {{.Health}}' 2>/dev/null | awk '$1=="headscale"{print $2}')
|
|
|
|
|
[[ "$h" == "healthy" ]] && { log "headscale healthy."; break; }
|
|
|
|
|
sleep 5
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
# Headplane: mint a headscale API key on first deploy (idempotent -- stored in
|
|
|
|
|
# .env), render its config, then bring the UI up.
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
|
if ! grep -qE '^HEADPLANE_HS_API_KEY=.+' "$ENV_FILE"; then
|
|
|
|
|
log "Creating a headscale API key for headplane..."
|
|
|
|
|
HP_KEY=$(docker compose exec -T headscale headscale apikeys create --expiration 999d 2>/dev/null \
|
|
|
|
|
| tr -d '\r' | tail -n1)
|
|
|
|
|
if [[ -n "$HP_KEY" ]]; then
|
|
|
|
|
sed -i "s|^HEADPLANE_HS_API_KEY=.*|HEADPLANE_HS_API_KEY=${HP_KEY}|" "$ENV_FILE"
|
|
|
|
|
log "Stored headplane API key in .env."
|
|
|
|
|
else
|
|
|
|
|
warn "Could not mint a headscale API key; set HEADPLANE_HS_API_KEY in $ENV_FILE and re-run."
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Re-read .env (now with the API key) and render headplane's config.
|
|
|
|
|
set -a; . "$ENV_FILE"; set +a
|
|
|
|
|
render_headplane_config
|
|
|
|
|
|
|
|
|
|
log "Starting headplane + remaining services..."
|
|
|
|
|
docker compose up -d --remove-orphans
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
@@ -304,12 +375,14 @@ cat <<EOF
|
|
|
|
|
DEPLOYED
|
|
|
|
|
|
|
|
|
|
Headscale: https://${HEADSCALE_DOMAIN}
|
|
|
|
|
Headplane: https://${HEADSCALE_DOMAIN}/admin (web UI)
|
|
|
|
|
Tailnet: ${TAILNET_DOMAIN} (MagicDNS suffix)
|
|
|
|
|
OIDC: https://${POCKETID_DOMAIN}
|
|
|
|
|
Stack dir: ${STACK_DIR}
|
|
|
|
|
|
|
|
|
|
OIDC redirect/callback URI -- register THIS in your pocket-id client:
|
|
|
|
|
https://${HEADSCALE_DOMAIN}/oidc/callback
|
|
|
|
|
OIDC redirect/callback URIs -- register THESE in pocket-id:
|
|
|
|
|
headscale: https://${HEADSCALE_DOMAIN}/oidc/callback
|
|
|
|
|
headplane: https://${HEADSCALE_DOMAIN}/admin/oidc/callback (2nd OIDC client)
|
|
|
|
|
|
|
|
|
|
ACL policy: ${STACK_DIR}/policy.hujson
|
|
|
|
|
headscale policy check # validate after editing
|
|
|
|
@@ -341,75 +414,82 @@ EOF
|
|
|
|
|
# __ARCHIVE_BELOW__ marker is the embedded tar.gz payload (base64).
|
|
|
|
|
exit 0
|
|
|
|
|
__ARCHIVE_BELOW__
|
|
|
|
|
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
|
|
|
|
|
ea3kewBQAAA=
|
|
|
|
|
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
|
|
|
|
|