rsocials-online/deploy/migrate-to-infisical.sh

214 lines
7.6 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# Migrate Postiz spaces from plaintext .env to Infisical secret injection
# =============================================================================
#
# Run this ON the Netcup server as root:
# ssh netcup-full
# bash /path/to/migrate-to-infisical.sh
#
# What it does:
# 1. Extracts POSTGRES_PASSWORD from each existing .env
# 2. Backs up old docker-compose.yml and .env
# 3. Copies new Infisical-wired compose files into place
# 4. Creates minimal .env (INFISICAL_CLIENT_ID/SECRET + POSTGRES_PASSWORD)
# 5. Restarts each space one at a time
# 6. Verifies containers come up healthy
# 7. Moves old .env to .env.removed (you delete after confirming)
#
# Prerequisites:
# - Machine identities created in Infisical for each project
# - /opt/infisical/entrypoint-wrapper.sh exists
# - This script is in the same directory as docker-compose.{cc,p2pf,bcrg}.yml
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
POSTIZ_BASE="/opt/postiz"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
log() { echo -e "${CYAN}[migrate]${NC} $*"; }
ok() { echo -e "${GREEN}[ OK ]${NC} $*"; }
warn() { echo -e "${YELLOW}[ WARN ]${NC} $*"; }
err() { echo -e "${RED}[ERROR ]${NC} $*"; }
# ── Preflight checks ──────────────────────────────────────────────────────────
log "Preflight checks..."
if [ "$(id -u)" -ne 0 ]; then
err "Must run as root (ssh netcup-full)"
exit 1
fi
if [ ! -f /opt/infisical/entrypoint-wrapper.sh ]; then
err "Infisical entrypoint wrapper not found at /opt/infisical/entrypoint-wrapper.sh"
exit 1
fi
for slug in cc p2pf bcrg; do
if [ ! -f "$SCRIPT_DIR/docker-compose.${slug}.yml" ]; then
err "Missing $SCRIPT_DIR/docker-compose.${slug}.yml"
exit 1
fi
done
ok "Preflight passed"
# ── Space definitions ─────────────────────────────────────────────────────────
declare -A SPACE_DIR
SPACE_DIR[cc]="crypto-commons"
SPACE_DIR[p2pf]="p2pfoundation"
SPACE_DIR[bcrg]="bondingcurve"
declare -A SPACE_INFISICAL_SLUG
SPACE_INFISICAL_SLUG[cc]="postiz-crypto-commons"
SPACE_INFISICAL_SLUG[p2pf]="postiz-p2pfoundation"
SPACE_INFISICAL_SLUG[bcrg]="postiz-bondingcurve"
# ── Collect Infisical credentials ─────────────────────────────────────────────
# You can either enter them interactively or set them as env vars before running:
# export INFISICAL_CC_CLIENT_ID=... INFISICAL_CC_CLIENT_SECRET=...
# export INFISICAL_P2PF_CLIENT_ID=... INFISICAL_P2PF_CLIENT_SECRET=...
# export INFISICAL_BCRG_CLIENT_ID=... INFISICAL_BCRG_CLIENT_SECRET=...
declare -A INF_CLIENT_ID
declare -A INF_CLIENT_SECRET
for slug in cc p2pf bcrg; do
upper=$(echo "$slug" | tr '[:lower:]' '[:upper:]')
id_var="INFISICAL_${upper}_CLIENT_ID"
secret_var="INFISICAL_${upper}_CLIENT_SECRET"
if [ -n "${!id_var:-}" ] && [ -n "${!secret_var:-}" ]; then
INF_CLIENT_ID[$slug]="${!id_var}"
INF_CLIENT_SECRET[$slug]="${!secret_var}"
ok "Using env var credentials for ${SPACE_DIR[$slug]}"
else
echo ""
log "Enter Infisical machine identity for ${SPACE_DIR[$slug]} (${SPACE_INFISICAL_SLUG[$slug]}):"
read -rp " Client ID: " INF_CLIENT_ID[$slug]
read -rp " Client Secret: " INF_CLIENT_SECRET[$slug]
if [ -z "${INF_CLIENT_ID[$slug]}" ] || [ -z "${INF_CLIENT_SECRET[$slug]}" ]; then
err "Missing credentials for ${SPACE_DIR[$slug]}"
exit 1
fi
fi
done
echo ""
log "Starting migration..."
echo ""
# ── Migrate each space ────────────────────────────────────────────────────────
for slug in cc p2pf bcrg; do
dir="${POSTIZ_BASE}/${SPACE_DIR[$slug]}"
log "━━━ Migrating ${SPACE_DIR[$slug]} (postiz-${slug}) ━━━"
# 1. Extract POSTGRES_PASSWORD from existing .env
if [ -f "$dir/.env" ]; then
PG_PASS=$(grep '^POSTGRES_PASSWORD=' "$dir/.env" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
if [ -z "$PG_PASS" ]; then
err "Could not extract POSTGRES_PASSWORD from $dir/.env"
err "Check the file manually and set it in the new .env"
exit 1
fi
ok "Extracted POSTGRES_PASSWORD from existing .env"
else
err "No .env found at $dir/.env"
exit 1
fi
# 2. Backup old files
log "Backing up old files..."
cp "$dir/docker-compose.yml" "$dir/docker-compose.yml.pre-infisical-${TIMESTAMP}"
cp "$dir/.env" "$dir/.env.pre-infisical-${TIMESTAMP}"
ok "Backed up to *.pre-infisical-${TIMESTAMP}"
# 3. Copy new compose file
log "Installing new Infisical-wired compose..."
cp "$SCRIPT_DIR/docker-compose.${slug}.yml" "$dir/docker-compose.yml"
ok "Installed new docker-compose.yml"
# 4. Create minimal .env
log "Creating minimal .env (3 values only)..."
cat > "$dir/.env" << ENVEOF
# Infisical machine identity (fetches all other secrets at container start)
INFISICAL_CLIENT_ID=${INF_CLIENT_ID[$slug]}
INFISICAL_CLIENT_SECRET=${INF_CLIENT_SECRET[$slug]}
# Postgres password (needed at compose interpolation time for DB containers)
POSTGRES_PASSWORD=${PG_PASS}
ENVEOF
chmod 600 "$dir/.env"
ok "Created minimal .env (600 perms)"
# 5. Restart containers
log "Restarting ${SPACE_DIR[$slug]}..."
cd "$dir"
docker compose down 2>&1 | sed 's/^/ /'
docker compose up -d 2>&1 | sed 's/^/ /'
# 6. Wait for health
log "Waiting for postiz-${slug} to be healthy (up to 90s)..."
healthy=false
for i in $(seq 1 18); do
sleep 5
state=$(docker inspect --format='{{.State.Running}}' "postiz-${slug}" 2>/dev/null || echo "false")
if [ "$state" = "true" ]; then
# Check if the entrypoint wrapper ran successfully by looking at logs
if docker logs "postiz-${slug}" 2>&1 | grep -q "\[infisical-wrapper\] Fetching secrets"; then
healthy=true
break
fi
fi
echo -n "."
done
echo ""
if $healthy; then
ok "postiz-${slug} is running with Infisical secrets"
else
warn "postiz-${slug} may not be healthy yet. Check logs:"
warn " docker logs postiz-${slug} 2>&1 | head -30"
warn "Continuing with next space..."
fi
# 7. Move old .env backup to .removed
mv "$dir/.env.pre-infisical-${TIMESTAMP}" "$dir/.env.REMOVED-${TIMESTAMP}"
ok "Old .env renamed to .env.REMOVED-${TIMESTAMP}"
echo ""
done
# ── Summary ───────────────────────────────────────────────────────────────────
echo ""
log "━━━ Migration Complete ━━━"
echo ""
log "Verify each space is working:"
echo " curl -s https://socials.crypto-commons.org | head -5"
echo " curl -s https://p2pf.rsocials.online | head -5"
echo " curl -s https://bondingcurve.rsocials.online | head -5"
echo ""
log "Check container logs:"
echo " docker logs postiz-cc 2>&1 | grep infisical"
echo " docker logs postiz-p2pf 2>&1 | grep infisical"
echo " docker logs postiz-bcrg 2>&1 | grep infisical"
echo ""
log "Once confirmed working, delete the old .env backups:"
echo " rm /opt/postiz/crypto-commons/.env.REMOVED-*"
echo " rm /opt/postiz/p2pfoundation/.env.REMOVED-*"
echo " rm /opt/postiz/bondingcurve/.env.REMOVED-*"
echo " rm /opt/postiz/*/docker-compose.yml.pre-infisical-*"
echo ""
ok "Done! Secrets are now managed by Infisical."