#!/usr/bin/env bash
set -euo pipefail
REPO_DIR=${REPO_DIR:-/opt/gluecron}
BARE_REPOS=${BARE_REPOS:-/data/repos}
PORT=${PORT:-3000}
SITE_DOMAIN=${SITE_DOMAIN:-gluecron.com}
SITE_ADMIN_USERNAME=${SITE_ADMIN_USERNAME:-ccantynz-alt}
cd "$REPO_DIR" || {
echo "ERROR: $REPO_DIR doesn't exist. Clone the repo first:"
echo " git clone https://github.com/ccantynz-alt/Gluecron.com.git $REPO_DIR"
exit 1
}
echo "==> Pulling latest source"
git pull --ff-only origin main
if [ -z "${DATABASE_URL:-}" ]; then
if [ -f /etc/gluecron.env ] && grep -q '^DATABASE_URL=' /etc/gluecron.env; then
DATABASE_URL=$(grep '^DATABASE_URL=' /etc/gluecron.env | cut -d= -f2-)
echo "==> Reusing existing DATABASE_URL from /etc/gluecron.env"
else
echo
echo "Paste the Neon DATABASE_URL (postgresql://... ?sslmode=require ...):"
read -r DATABASE_URL
fi
fi
APP_BASE_URL=${APP_BASE_URL:-https://${SITE_DOMAIN}}
if ! command -v bun >/dev/null && [ ! -x "$HOME/.bun/bin/bun" ]; then
echo "==> Installing Bun"
curl -fsSL https://bun.sh/install | bash
fi
export PATH="$HOME/.bun/bin:$PATH"
echo "==> bun: $(bun --version)"
echo "==> Installing project dependencies"
bun install --frozen-lockfile
mkdir -p "$BARE_REPOS"
chmod 755 "$BARE_REPOS"
echo "==> Writing /etc/gluecron.env"
umask 077
cat > /etc/gluecron.env <<EOF
DATABASE_URL=${DATABASE_URL}
APP_BASE_URL=${APP_BASE_URL}
SITE_ADMIN_USERNAME=${SITE_ADMIN_USERNAME}
GIT_REPOS_PATH=${BARE_REPOS}
PORT=${PORT}
DEMO_SEED_ON_BOOT=1
EMAIL_PROVIDER=log
EMAIL_FROM=gluecron <no-reply@${SITE_DOMAIN}>
NODE_ENV=production
EOF
chmod 600 /etc/gluecron.env
umask 022
echo "==> Running database migrations"
set -a; source /etc/gluecron.env; set +a
bun run src/db/migrate.ts || {
echo "WARNING: migration command failed — continuing (it may be idempotent already-applied)"
}
BUN_BIN="$(command -v bun)"
echo "==> Writing /etc/systemd/system/gluecron.service"
cat > /etc/systemd/system/gluecron.service <<EOF
[Unit]
Description=Gluecron — AI-native code intelligence platform
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=${REPO_DIR}
EnvironmentFile=/etc/gluecron.env
ExecStart=${BUN_BIN} run src/index.ts
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=gluecron
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
echo "==> Reloading systemd + (re)starting gluecron"
systemctl daemon-reload
systemctl enable gluecron >/dev/null 2>&1 || true
systemctl restart gluecron
CADDYFILE="/etc/caddy/Caddyfile"
if [ -f "$CADDYFILE" ]; then
if ! grep -q "^${SITE_DOMAIN} *{" "$CADDYFILE"; then
echo "==> Adding ${SITE_DOMAIN} to Caddyfile"
cat >> "$CADDYFILE" <<EOF
${SITE_DOMAIN} {
reverse_proxy localhost:${PORT}
}
www.${SITE_DOMAIN} {
redir https://${SITE_DOMAIN}{uri} permanent
}
EOF
if command -v caddy >/dev/null; then
caddy validate --config "$CADDYFILE" --adapter caddyfile && systemctl reload caddy
else
systemctl reload caddy || systemctl restart caddy || true
fi
else
echo "==> ${SITE_DOMAIN} already in Caddyfile (skipping)"
fi
else
echo "WARNING: $CADDYFILE not found — skipping Caddy config"
echo " You'll need to add a reverse_proxy to localhost:${PORT} manually"
fi
echo
echo "==> Waiting for /healthz to respond (up to 30s)"
for i in $(seq 1 10); do
if curl -sf "http://localhost:${PORT}/healthz" >/dev/null; then
echo "✓ gluecron is up at http://localhost:${PORT}"
echo
echo "============================================================"
echo "DONE. Next steps:"
echo " 1. DNS: ensure A record for ${SITE_DOMAIN} → this server's IP"
echo " 2. Visit: https://${SITE_DOMAIN}"
echo " 3. Register account '${SITE_ADMIN_USERNAME}' → instant site admin"
echo
echo "Useful commands:"
echo " systemctl status gluecron"
echo " journalctl -u gluecron -f"
echo " bash scripts/deploy-crontech.sh # re-deploy after git pull"
echo "============================================================"
exit 0
fi
sleep 3
done
echo
echo "✗ gluecron did not respond on /healthz after 30s"
echo "Diagnose with:"
echo " systemctl status gluecron"
echo " journalctl -u gluecron -n 100 --no-pager"
exit 1
|