Kalheon API Deployment
Production deploys are driven by GitHub Actions in .github/workflows/deploy.yml.
Flow
- A commit is pushed to
main. - GitHub Actions opens an SSH session to
claude@157.180.103.168. - The remote repository at
/home/claude/projects/kalheon_agentsis fast-forwarded fromorigin/main. scripts/deploy-production.shruns on the server:- pulls
main; - runs
npm ci; - runs
npx prisma generate; - runs
npm run db:migrate:deploy; - runs
npm run build; - restarts
pm2appkalheon-api; - smoke-tests
https://api.kalheon.cloud/health; - smoke-tests
https://api.kalheon.cloud/docs/json.
- pulls
- GitHub Actions sends a Telegram success or failure notification when Telegram secrets are configured.
The deploy script uses /tmp/kalheon-api-deploy.lock so two deploys cannot run at the same time.
GitHub Secrets
Required:
DEPLOY_SSH_KEY: private key allowed to deploy on AX43.
Recommended:
DEPLOY_KNOWN_HOSTS: pinned SSH host key entry for157.180.103.168.
Optional overrides:
DEPLOY_HOST: defaults to157.180.103.168.DEPLOY_PORT: defaults to22.DEPLOY_USER: defaults toclaude.DEPLOY_REPO_DIR: defaults to/home/claude/projects/kalheon_agents.PM2_APP: defaults tokalheon-api.SMOKE_HEALTH_URL: defaults tohttps://api.kalheon.cloud/health.SMOKE_DOCS_URL: defaults tohttps://api.kalheon.cloud/docs/json.
Telegram notifications:
TG_BOT_TOKEN: Telegram bot token.TG_CHAT_ID: chat or channel id for deploy notifications.
If the Telegram secrets are missing, deploy still runs and logs that notification was skipped.
Server Bootstrap
Run this once on AX43 before enabling the restricted deploy key:
ssh claude@157.180.103.168
cd /home/claude/projects/kalheon_agents
git fetch origin main
git checkout main
git pull --ff-only origin main
chmod +x scripts/deploy-production.sh
scripts/deploy-production.sh
After the first successful bootstrap, add the deploy public key to
/home/claude/.ssh/authorized_keys.
Safer restricted form:
command="/home/claude/projects/kalheon_agents/scripts/deploy-production.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA... kalheon-deploy
With the forced command enabled, GitHub Actions can only trigger the deploy script for this key.
Manual Deploy
ssh claude@157.180.103.168
cd /home/claude/projects/kalheon_agents
DEPLOY_BRANCH=main PM2_APP=kalheon-api scripts/deploy-production.sh
Manual Rollback
Preferred rollback is a revert commit pushed to main; that keeps production and git history aligned and triggers the same pipeline:
git revert <bad_commit_sha>
git push origin main
Emergency server-side rollback when a revert cannot be pushed quickly:
ssh claude@157.180.103.168
cd /home/claude/projects/kalheon_agents
git fetch origin main
git checkout <last_good_sha>
npm ci
npx prisma generate
npm run db:migrate:deploy
npm run build
pm2 restart kalheon-api --update-env
curl -fsS https://api.kalheon.cloud/health > /dev/null
curl -fsS https://api.kalheon.cloud/docs/json > /dev/null
Database migrations are forward-only by default. If the bad deploy included a schema migration, rollback may also need an explicit corrective migration.
Smoke Endpoints
The public smoke endpoints are:
https://api.kalheon.cloud/healthhttps://api.kalheon.cloud/docs/json
The versioned health route remains available at https://api.kalheon.cloud/api/v1/health.