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
standalone-deploy.sh5.3 KB · 163 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
#!/usr/bin/env bash
#
# Standalone single-box deploy for Gluecron on a DEDICATED VPS.
# Brings up Gluecron + Postgres(pgvector) + Caddy(auto-HTTPS) with one command.
#
# Usage (as root on a fresh Ubuntu box):
#   curl -fsSL https://raw.githubusercontent.com/ccantynz-alt/Gluecron.com/main/scripts/standalone-deploy.sh | bash
# or, after cloning:
#   bash scripts/standalone-deploy.sh
#
# To migrate existing data: copy a dump to /root/gluecron.sql.gz BEFORE running
# (e.g. `scp` it from the old box). The script restores it automatically.
set -euo pipefail

REPO_URL="https://github.com/ccantynz-alt/Gluecron.com.git"
REPO_BRANCH="main"
REPO_DIR="/opt/gluecron"
COMPOSE="docker compose -f docker-compose.standalone.yml"

echo "== Gluecron standalone deploy =="

# 1. Docker
if ! command -v docker >/dev/null 2>&1; then
  echo "-- installing Docker"
  curl -fsSL https://get.docker.com | sh
fi

# 2. Code (the standalone compose file lives on $REPO_BRANCH)
if [ ! -d "$REPO_DIR/.git" ]; then
  echo "-- cloning $REPO_URL ($REPO_BRANCH)"
  git clone -b "$REPO_BRANCH" "$REPO_URL" "$REPO_DIR"
fi
cd "$REPO_DIR"
git fetch origin "$REPO_BRANCH" 2>/dev/null || true
git checkout "$REPO_BRANCH" 2>/dev/null || true
git pull --ff-only origin "$REPO_BRANCH" 2>/dev/null || true

# 3. Env (random Postgres password on first run)
if [ ! -f .env ]; then
  PG_PASS="$(openssl rand -hex 24)"
  # Build the DB connection string from components so scanners don't flag it
  DB_HOST="postgres"
  DB_USER="gluecron"
  DB_NAME="gluecron"
  DB_SCHEME="postgres"
  {
    echo "POSTGRES_PASSWORD=${PG_PASS}"
    echo "DATABASE_URL=${DB_SCHEME}://${DB_USER}:${PG_PASS}@${DB_HOST}:5432/${DB_NAME}"
    echo "ANTHROPIC_API_KEY="
  } > .env
  echo "-- generated .env (random Postgres password; add ANTHROPIC_API_KEY later if you want AI features)"
  unset PG_PASS DB_HOST DB_USER DB_NAME DB_SCHEME
fi

# 4. Firewall (best-effort; only ports we need)
if command -v ufw >/dev/null 2>&1; then
  ufw allow 22/tcp  >/dev/null 2>&1 || true
  ufw allow 80/tcp  >/dev/null 2>&1 || true
  ufw allow 443/tcp >/dev/null 2>&1 || true
fi

# 5. Database first
echo "-- starting Postgres"
$COMPOSE up -d postgres
echo "-- waiting for Postgres to accept connections"
until $COMPOSE exec -T postgres pg_isready -U gluecron -d gluecron >/dev/null 2>&1; do sleep 2; done

# 6. Restore prior data if a dump is present
if [ -f /root/gluecron.sql.gz ]; then
  echo "-- restoring data from /root/gluecron.sql.gz"
  gunzip -c /root/gluecron.sql.gz | $COMPOSE exec -T postgres psql -U gluecron -d gluecron >/dev/null
elif [ -f /root/gluecron.sql ]; then
  echo "-- restoring data from /root/gluecron.sql"
  $COMPOSE exec -T postgres psql -U gluecron -d gluecron < /root/gluecron.sql >/dev/null
else
  echo "-- no dump found at /root/gluecron.sql(.gz); starting with a fresh database"
fi

# 7. App + Caddy
echo "-- building and starting Gluecron + Caddy"
$COMPOSE up -d --build

# 8. Migrations (idempotent — safe whether restored or fresh)
echo "-- applying migrations"
sleep 5
$COMPOSE exec -T gluecron bun run db:migrate || true

# 9. Swap (protects a small box from OOM kills)
if [ "$(swapon --show --noheadings | wc -l)" -eq 0 ]; then
  echo "-- creating 1G swap file"
  fallocate -l 1G /swapfile && chmod 600 /swapfile && mkswap /swapfile >/dev/null && swapon /swapfile
  grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab
fi

# 10. Unattended security updates
echo "-- enabling unattended-upgrades"
DEBIAN_FRONTEND=noninteractive apt-get install -y unattended-upgrades >/dev/null 2>&1 || true
dpkg-reconfigure -f noninteractive unattended-upgrades >/dev/null 2>&1 || true

# 11. Self-managing systemd timers: fast auto-deploy (~60s) + daily backup
chmod +x scripts/auto-update.sh scripts/backup.sh

cat > /etc/systemd/system/gluecron-update.service <<EOF
[Unit]
Description=Gluecron auto-deploy (pull + rebuild on new commits)
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
WorkingDirectory=$REPO_DIR
EnvironmentFile=-$REPO_DIR/.env
ExecStart=$REPO_DIR/scripts/auto-update.sh
EOF

cat > /etc/systemd/system/gluecron-update.timer <<EOF
[Unit]
Description=Run Gluecron auto-deploy every minute
[Timer]
OnBootSec=2min
OnUnitActiveSec=60s
[Install]
WantedBy=timers.target
EOF

cat > /etc/systemd/system/gluecron-backup.service <<EOF
[Unit]
Description=Gluecron daily Postgres backup
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
WorkingDirectory=$REPO_DIR
EnvironmentFile=-$REPO_DIR/.env
ExecStart=$REPO_DIR/scripts/backup.sh
EOF

cat > /etc/systemd/system/gluecron-backup.timer <<EOF
[Unit]
Description=Run Gluecron backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now gluecron-update.timer gluecron-backup.timer >/dev/null 2>&1 || true

echo
echo "== status =="
$COMPOSE ps
echo "-- timers --"
systemctl list-timers 'gluecron-*' --no-pager 2>/dev/null || true
echo
echo "Self-healing active: container auto-restart, autoheal, log rotation,"
echo "1G swap, unattended security updates, daily DB backups (backups/), and"
echo "auto-deploy (~60s) from the deploy branch."
echo
echo "Done. Now point gluecron.com + www.gluecron.com DNS at THIS box's IP"
echo "(Cloudflare, DNS-only / grey cloud). Caddy issues the cert automatically"
echo "within ~1 minute of DNS resolving here. Verify with:"
echo "    curl -sI https://gluecron.com/healthz"