Files
c-relay-pg/deploy_lt.sh
T

204 lines
8.1 KiB
Bash
Executable File

#!/bin/bash
# C-Relay-PG PostgreSQL Deployment Script
# Deploys static relay binary and configures PostgreSQL 18 + systemd service on remote server.
set -euo pipefail
# Configuration
REMOTE_HOST="ubuntu@laantungir.net"
LOCAL_BINARY="build/c_relay_pg_static_x86_64"
LOCAL_CACHING_BINARY="build/caching_relay"
REMOTE_BINARY_DIR="/usr/local/bin/c_relay_pg"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
REMOTE_CACHING_BINARY_PATH="/opt/c-relay-pg/caching_relay"
SERVICE_NAME="c-relay-pg"
LOCAL_SERVICE_FILE="systemd/c-relay.service"
LOCAL_PG_SETUP_SCRIPT="systemd/setup_postgres_18.sh"
if [ ! -f "$LOCAL_BINARY" ]; then
echo "ERROR: Binary not found: $LOCAL_BINARY"
echo "Build it first (e.g. ./make_and_restart_relay.sh)"
exit 1
fi
if [ ! -f "$LOCAL_SERVICE_FILE" ]; then
echo "ERROR: Service file not found: $LOCAL_SERVICE_FILE"
exit 1
fi
if [ ! -f "$LOCAL_PG_SETUP_SCRIPT" ]; then
echo "ERROR: PostgreSQL setup script not found: $LOCAL_PG_SETUP_SCRIPT"
exit 1
fi
echo "==> Uploading artifacts to $REMOTE_HOST"
scp "$LOCAL_BINARY" "$REMOTE_HOST:/tmp/c_relay_pg.tmp"
scp "$LOCAL_SERVICE_FILE" "$REMOTE_HOST:/tmp/c-relay-pg.service"
scp "$LOCAL_PG_SETUP_SCRIPT" "$REMOTE_HOST:/tmp/setup_postgres_18.sh"
# Upload the caching_relay binary if it was built locally. The caching
# service is NOT started by this deploy (the systemd unit does not pass
# --start-caching), but the binary is placed in the relay's WorkingDirectory
# so it is ready for when caching is enabled via event-based config.
if [ -f "$LOCAL_CACHING_BINARY" ]; then
scp "$LOCAL_CACHING_BINARY" "$REMOTE_HOST:/tmp/caching_relay.tmp"
else
echo "WARNING: caching_relay binary not found locally ($LOCAL_CACHING_BINARY) — skipping caching binary upload"
fi
# Upload admin PHP files (tar to preserve directory structure, exclude
# cache logs and the dev-only serve.sh / php_server.log).
echo "==> Packaging admin files"
tar czf /tmp/admin_deploy.tar.gz \
--exclude='admin/serve.sh' \
--exclude='admin/php_server.log' \
--exclude='admin/cache' \
-C . admin/
scp /tmp/admin_deploy.tar.gz "$REMOTE_HOST:/tmp/admin_deploy.tar.gz"
echo "==> Running remote install/configuration"
ssh "$REMOTE_HOST" 'bash -s' <<'EOF'
set -euo pipefail
SERVICE_NAME="c-relay-pg"
RELAY_USER="c-relay-pg"
REMOTE_BINARY_DIR="/usr/local/bin/c_relay_pg"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
REMOTE_CACHING_BINARY_PATH="/opt/c-relay-pg/caching_relay"
echo "[remote] Ensuring service user exists"
if ! id "$RELAY_USER" >/dev/null 2>&1; then
sudo useradd --system --home-dir /opt/c-relay-pg --shell /usr/sbin/nologin "$RELAY_USER"
fi
echo "[remote] Ensuring required directories exist"
sudo mkdir -p "$REMOTE_BINARY_DIR" /opt/c-relay-pg /etc/c-relay-pg
sudo chown "$RELAY_USER:$RELAY_USER" /opt/c-relay-pg
echo "[remote] Installing PostgreSQL 18 (PGDG) if missing"
if ! dpkg -s postgresql-18 >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y curl ca-certificates lsb-release gnupg
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list >/dev/null
sudo apt-get update
sudo apt-get install -y postgresql-18
fi
sudo systemctl enable postgresql
sudo systemctl restart postgresql
echo "[remote] Configuring PostgreSQL role/database"
sudo chmod +x /tmp/setup_postgres_18.sh
sudo /tmp/setup_postgres_18.sh
echo "[remote] Installing relay binary"
if [ -f "$REMOTE_BINARY_PATH" ]; then
sudo cp "$REMOTE_BINARY_PATH" "${REMOTE_BINARY_PATH}.backup.$(date +%Y%m%d_%H%M%S)"
fi
sudo mv /tmp/c_relay_pg.tmp "$REMOTE_BINARY_PATH"
sudo chown "$RELAY_USER:$RELAY_USER" "$REMOTE_BINARY_PATH"
sudo chmod +x "$REMOTE_BINARY_PATH"
echo "[remote] Installing caching_relay binary (if uploaded)"
if [ -f /tmp/caching_relay.tmp ]; then
sudo mv /tmp/caching_relay.tmp "$REMOTE_CACHING_BINARY_PATH"
sudo chown "$RELAY_USER:$RELAY_USER" "$REMOTE_CACHING_BINARY_PATH"
sudo chmod +x "$REMOTE_CACHING_BINARY_PATH"
echo " -> caching_relay installed at $REMOTE_CACHING_BINARY_PATH (not started; enable via config when ready)"
else
echo " -> no caching_relay binary uploaded, skipping"
fi
echo "[remote] Installing admin PHP files"
# Back up existing config.php and .htpasswd so we don't lose production
# credentials (DB password, basic-auth) across deploys.
if [ -f /opt/c-relay-pg/admin/lib/config.php ]; then
sudo cp /opt/c-relay-pg/admin/lib/config.php /tmp/admin_config_backup
echo " -> backed up config.php"
fi
if [ -f /opt/c-relay-pg/admin/.htpasswd ]; then
sudo cp /opt/c-relay-pg/admin/.htpasswd /tmp/admin_htpasswd_backup
echo " -> backed up .htpasswd"
fi
# Extract the new admin files (overwrites old admin at /opt/c-relay-pg/admin/).
sudo mkdir -p /opt/c-relay-pg/admin
sudo tar xzf /tmp/admin_deploy.tar.gz -C /opt/c-relay-pg/
# Restore config.php and .htpasswd if they were backed up.
if [ -f /tmp/admin_config_backup ]; then
sudo cp /tmp/admin_config_backup /opt/c-relay-pg/admin/lib/config.php
echo " -> restored config.php"
fi
if [ -f /tmp/admin_htpasswd_backup ]; then
sudo cp /tmp/admin_htpasswd_backup /opt/c-relay-pg/admin/.htpasswd
echo " -> restored .htpasswd"
fi
# Set ownership: www-data (nginx/php-fpm) for web-served files,
# but keep .htpasswd readable by nginx.
sudo chown -R www-data:www-data /opt/c-relay-pg/admin/
sudo chmod 640 /opt/c-relay-pg/admin/.htpasswd 2>/dev/null || true
# Ensure the cache directory exists (for chart text files).
sudo mkdir -p /opt/c-relay-pg/admin/cache
sudo chown www-data:www-data /opt/c-relay-pg/admin/cache
echo " -> admin files installed at /opt/c-relay-pg/admin/"
# Also update admin2 if it exists (symlink or copy to keep it in sync).
if [ -d /opt/c-relay-pg/admin2 ]; then
sudo rm -rf /opt/c-relay-pg/admin2
sudo cp -a /opt/c-relay-pg/admin /opt/c-relay-pg/admin2
sudo chown -R www-data:www-data /opt/c-relay-pg/admin2/
echo " -> admin2 synced at /opt/c-relay-pg/admin2/"
fi
echo "[remote] Installing systemd unit"
sudo mv /tmp/c-relay-pg.service /etc/systemd/system/c-relay-pg.service
sudo chown root:root /etc/systemd/system/c-relay-pg.service
sudo chmod 644 /etc/systemd/system/c-relay-pg.service
echo "[remote] Killing stale caching_relay processes (safety)"
# The caching service is forked by the relay with setsid(), so it detaches
# from the relay's process group and survives when the relay is killed.
# Without this, every restart orphans the previous caching_relay child and
# a new relay forks another, leading to many stale processes with dead PG
# connections spamming errors. Kill them here so the new relay starts clean.
CACHING_PIDS=$(pgrep -f "caching_relay" || echo "")
if [ -n "$CACHING_PIDS" ]; then
echo " -> killing stale caching_relay PIDs: $CACHING_PIDS"
kill -9 $CACHING_PIDS 2>/dev/null || true
sleep 1
else
echo " -> no stale caching_relay processes found"
fi
echo "[remote] Reloading and restarting service"
sudo systemctl daemon-reload
sudo systemctl enable "$SERVICE_NAME"
sudo systemctl restart "$SERVICE_NAME"
echo "[remote] Health checks"
sudo systemctl --no-pager --full status "$SERVICE_NAME" | sed -n '1,25p'
sudo -u "$RELAY_USER" psql -d crelay -c "SELECT current_user, current_database();"
# Verify admin page is accessible (HTTP 200 or 401 = auth required, both are OK).
ADMIN_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1/admin/" 2>/dev/null || echo "000")
if [ "$ADMIN_CODE" = "200" ] || [ "$ADMIN_CODE" = "401" ]; then
echo " -> admin page accessible (HTTP $ADMIN_CODE)"
else
echo " -> WARNING: admin page returned HTTP $ADMIN_CODE (expected 200 or 401)"
fi
# Clean up temp files.
rm -f /tmp/admin_deploy.tar.gz
sudo rm -f /tmp/admin_htpasswd_backup /tmp/admin_config_backup
EOF
# Clean up local temp tarball.
rm -f /tmp/admin_deploy.tar.gz
echo "Deployment complete: $REMOTE_HOST"
echo ""
echo "Admin interface: https://laantungir.net/admin/"
echo "Caching is NOT auto-started. Enable it via the admin UI when ready."