Petrolyst server infrastructure: Traefik, Trino and Superset
Traefik as the server-wide edge (TLS via Let's Encrypt, dashboard on traefik.petrolyst.com behind oauth2-proxy and Keycloak). The fuel-monitoring stack: Superset on atoma.petrolyst.com with Keycloak login and Petrolyst branding, Trino reading the TimescaleDB fuel-db as catalog "fuel". Customization lives in petrolyst-insights/, deployment in the other folders. Deploys run server-side (deploy/deploy.sh) from a Gitea workflow or manually; releases are immutable, Superset metadata is backed up before migrations, and deploy/rollback.sh restores it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
24327f9462
commit
d3800ac9dd
34 files changed
+2117
No files matched your search
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# Server secrets and env files, run as root after bootstrap.sh.
|
||||
# secrets-init.sh generate every missing secret; never overwrites one
|
||||
# secrets-init.sh keycloak-secret store the client secret of Keycloak client
|
||||
# "petrolyst" (Clients > petrolyst > Credentials),
|
||||
# read from the terminal or stdin
|
||||
#
|
||||
# Layout: /opt/petrolyst/secrets/{shared,traefik,fuel-monitoring}/ are root:deploy
|
||||
# 0750, so only root and the deploy user can reach them; the files are 0444
|
||||
# because each container reads them under its own uid.
|
||||
set -euo pipefail
|
||||
|
||||
die() { echo "ERROR: $*" >&2; exit 1; }
|
||||
[ "$(id -u)" = 0 ] || die "run as root"
|
||||
getent group deploy >/dev/null || die "group deploy is missing: run host/bootstrap.sh first"
|
||||
|
||||
ROOT=/opt/petrolyst
|
||||
SECRETS=$ROOT/secrets
|
||||
umask 077
|
||||
install -d -o root -g deploy -m 0750 "$SECRETS" "$SECRETS/shared" "$SECRETS/traefik" "$SECRETS/fuel-monitoring" "$ROOT/env"
|
||||
|
||||
# write_secret <path> <value>: no trailing newline (oauth2-proxy reads the file
|
||||
# byte for byte), replaced atomically.
|
||||
write_secret() {
|
||||
printf '%s' "$2" >"$1.tmp"
|
||||
chown root:deploy "$1.tmp"
|
||||
chmod 0444 "$1.tmp"
|
||||
mv "$1.tmp" "$1"
|
||||
}
|
||||
|
||||
generate() {
|
||||
if [ -s "$1" ]; then
|
||||
echo "kept $1"
|
||||
else
|
||||
write_secret "$1" "$(openssl rand -hex "$2")"
|
||||
echo "generated $1"
|
||||
fi
|
||||
}
|
||||
|
||||
case ${1:-all} in
|
||||
keycloak-secret)
|
||||
if [ -t 0 ]; then
|
||||
printf 'Client secret of Keycloak client "petrolyst": ' >&2
|
||||
IFS= read -rs value
|
||||
echo >&2
|
||||
else
|
||||
IFS= read -r value
|
||||
fi
|
||||
value=$(printf '%s' "$value" | tr -d '[:space:]')
|
||||
[ -n "$value" ] || die "empty secret"
|
||||
write_secret "$SECRETS/shared/keycloak_petrolyst_client_secret" "$value"
|
||||
echo "stored $SECRETS/shared/keycloak_petrolyst_client_secret"
|
||||
exit 0
|
||||
;;
|
||||
all) ;;
|
||||
*) die "usage: secrets-init.sh [keycloak-secret]" ;;
|
||||
esac
|
||||
|
||||
# Hex only, so no value ever needs quoting in a URL or a properties file.
|
||||
generate "$SECRETS/fuel-monitoring/superset_secret_key" 32
|
||||
generate "$SECRETS/fuel-monitoring/superset_db_password" 32
|
||||
generate "$SECRETS/fuel-monitoring/fuel_db_password" 32
|
||||
generate "$SECRETS/fuel-monitoring/fuel_db_trino_password" 32
|
||||
# 32 hex characters = a 32-byte cookie key, as oauth2-proxy requires.
|
||||
generate "$SECRETS/traefik/oauth2_proxy_cookie_secret" 16
|
||||
|
||||
# Trino reads the catalog password from its environment (${ENV:...}); keep the
|
||||
# env file in step with the secret file that fuel-db's init script uses.
|
||||
env_file=$ROOT/env/fuel-monitoring.env
|
||||
line="FUEL_DB_TRINO_PASSWORD=$(cat "$SECRETS/fuel-monitoring/fuel_db_trino_password")"
|
||||
if ! grep -qxF "$line" "$env_file" 2>/dev/null; then
|
||||
printf '%s\n' "$line" >"$env_file.tmp"
|
||||
chown root:deploy "$env_file.tmp"
|
||||
chmod 0440 "$env_file.tmp"
|
||||
mv "$env_file.tmp" "$env_file"
|
||||
echo "wrote $env_file"
|
||||
fi
|
||||
|
||||
if [ ! -s "$SECRETS/shared/keycloak_petrolyst_client_secret" ]; then
|
||||
echo
|
||||
echo "Still missing: the Keycloak client secret. Copy it from Keycloak"
|
||||
echo "(realm thedigitalbridge > Clients > petrolyst > Credentials), then run:"
|
||||
echo " $0 keycloak-secret"
|
||||
exit 1
|
||||
fi
|
||||
echo "All secrets present."
|
||||
Reference in new issue
Block a user