Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
claude/adoring-hopper-5x74bqclaude/affectionate-feynman-ykrf1hclaude/architecture-audit-design-wxprenclaude/build-status-update-3MXsfclaude/charming-meitner-mllb5rclaude/compare-gate-gluecron-s4mFQclaude/confident-faraday-tikcwbclaude/continue-work-XMTlIclaude/crontech-gluecron-deploy-7MIECclaude/crontech-platform-setup-SeKfwclaude/design-2026claude/ecstatic-ptolemy-jMdigclaude/enhance-github-integration-QNHdGclaude/fix-aa-loop-issue-PonMQclaude/fix-actions-and-processclaude/fix-desktop-errors-XqoW8claude/fix-red-workflowsclaude/fix-website-access-6FKJNclaude/gatetest-integration-hardeningclaude/github-audit-improvements-bDFr9claude/gluecron-launch-status-FoMRlclaude/hopeful-lamport-olfCTclaude/issue-to-pr-and-protectionsclaude/jolly-heisenberg-2sg1Qclaude/launch-preparation-QmTb6claude/new-session-xk1l7claude/plan-platform-architecture-kkN4yclaude/platform-analysis-roadmap-1nUGLclaude/platform-launch-assessment-8dWV8claude/polish-platform-release-AeDrUclaude/resume-previous-work-KzyLwclaude/review-crontech-handoff-qYEVqclaude/review-project-completeness-lHhS2claude/review-readme-docs-ulqPKclaude/serene-edison-rj87weclaude/setup-multi-repo-dev-BCwNQclaude/ship-fixes-and-tests-Jvz1cclaude/site-audit-competitive-pctlwgclaude/site-migration-vercel-XstpKclaude/standalone-product-repos-XHFTDcopilot/feat-smart-empty-states-keyboard-first-enhancementcopilot/feat-smart-morning-digest-review-context-restorecopilot/fix-and-process-workflowscopilot/update-ai-powered-code-reviewfeat/debt-mapfeat/push-policy-codeowners-hardeningfeat/smart-digest-contextfeat/stage-impactfeat/t1-secret-migrationfeat/u-polishfeat/w-self-hostfeat/w2-claude-configfix/agent-journey-orphan-sweepgatetest/auto-fix-1776586424172gatetest/auto-fix-1776586534814gatetest/auto-fix-1776590685143gatetest/auto-fix-1776590808199mainops/redeploy-retriggerstyle/dxt-cta-themeworktree-agent-a3377aad30d55da26worktree-agent-a7ef607b7ee1d6c74
deploy-crontech.sh5.9 KB · 184 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env bash
# ============================================================================
# Gluecron deploy to Crontech bare-metal
# ============================================================================
# Idempotent. Run as root on the Crontech box (45.76.171.37). Re-runnable.
#
# Usage:
#   bash scripts/deploy-crontech.sh
#
# Environment (prompted if not set):
#   DATABASE_URL          Neon Postgres pooled connection string
#   SITE_ADMIN_USERNAME   GitHub-style username for the bootstrap admin
#                         (default: ccantynz-alt)
#   SITE_DOMAIN           Public domain for HTTPS (default: gluecron.com)
#
# What it does:
#   1. Installs Bun if missing
#   2. bun install (frozen lockfile)
#   3. Ensures /data/repos exists for bare git repos
#   4. Writes /etc/gluecron.env (chmod 600)
#   5. Runs DB migrations
#   6. Writes /etc/systemd/system/gluecron.service + enables it
#   7. Adds <domain> { reverse_proxy localhost:3000 } to Caddyfile + reloads
#   8. Smoke-tests localhost:3000/healthz
# ============================================================================

set -euo pipefail

REPO_DIR=${REPO_DIR:-/opt/gluecron}
BARE_REPOS=${BARE_REPOS:-/data/repos}
PORT=${PORT:-3010}
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

# ---- DATABASE_URL prompt -------------------------------------------------
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}}

# ---- Bun install ---------------------------------------------------------
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)"

# ---- Dependencies --------------------------------------------------------
echo "==> Installing project dependencies"
bun install --frozen-lockfile

# ---- Bare-repo dir -------------------------------------------------------
mkdir -p "$BARE_REPOS"
chmod 755 "$BARE_REPOS"

# ---- Env file ------------------------------------------------------------
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

# ---- Migrations ----------------------------------------------------------
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)"
}

# ---- systemd unit --------------------------------------------------------
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

# ---- Caddy ----------------------------------------------------------------
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

# ---- Smoke test ----------------------------------------------------------
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