#!/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 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 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();" EOF echo "Deployment complete: $REMOTE_HOST"