Skip to content

CI/CD to a HivePod

You can deploy to a HivePod from any CI system. The pattern is:

  1. CI signs in with a DockHive API key.
  2. It starts the deploy as a background job in the pod (hivepod exec --detach).
  3. It follows the job until it ends (hivepod job status --follow). The CI step passes or fails with the job’s exit code.

The pod pulls your code itself, with a deploy key that you keep in the pod.

Open a terminal in the pod (hivepod connect web1, or the console’s web terminal). Install git and the SSH client if your OS image doesn’t have them:

Terminal window
apt-get update && apt-get install -y git openssh-client # Ubuntu / Debian

Create a deploy key and trust GitHub’s host key:

Terminal window
ssh-keygen -t ed25519 -f ~/.ssh/github_deploy -N "" -C "dockhive-web1"
cat >> ~/.ssh/config <<'EOF'
Host github.com
IdentityFile ~/.ssh/github_deploy
IdentitiesOnly yes
EOF
ssh-keyscan github.com >> ~/.ssh/known_hosts
cat ~/.ssh/github_deploy.pub

On GitHub, open your repository’s Settings → Deploy keys → Add deploy key. Paste the public key and leave Allow write access off.

Clone the repository into the projects folder:

Terminal window
git clone [email protected]:you/app.git /home/hivepod/projects/app

In the console, go to Settings → API Keys → Create API Key and choose Full access. A read-only key can check jobs but can’t start them. Add the key to your CI’s secrets as DOCKHIVE_API_KEY. See API keys.

.github/workflows/deploy.yml:

name: Deploy to HivePod
on:
push:
branches: [main]
concurrency:
group: deploy-web1 # one deploy at a time
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install "hivepods-cli>=0.3"
- name: Deploy
env:
HIVEPODS_TOKEN: ${{ secrets.DOCKHIVE_API_KEY }}
run: |
JOB=$(hivepod exec --detach --timeout 1800 web1 '
set -e
command -v git >/dev/null || (apt-get update && apt-get install -y git openssh-client)
cd /home/hivepod/projects/app
git fetch origin main
git reset --hard origin/main
./deploy.sh
')
echo "Started job $JOB"
hivepod job status web1 "$JOB" --follow

hivepod exec --detach prints the job id and returns. hivepod job status --follow streams the job’s output into the CI log and polls less often while nothing is happening. It exits with the job’s exit code: 0 on success, the command’s own code on failure, 124 if the job hit its timeout and 130 if it was cancelled.

Replace ./deploy.sh with your own steps, for example npm ci && npm run build && pm2 reload app. To restart a server that runs as the pod’s startup command, finish with a restart from CI (hivepod restart web1). A restart ends any jobs still running in the pod, so do it after the job.

Anything that can run Python 3.9+ works the same way. Set HIVEPODS_TOKEN from a secret and run the same two commands. In GitLab CI, for example:

deploy:
image: python:3.12-slim
script:
- pip install "hivepods-cli>=0.3"
- JOB=$(hivepod exec --detach --timeout 1800 web1 "cd /home/hivepod/projects/app && git pull --ff-only && ./deploy.sh")
- hivepod job status web1 "$JOB" --follow
only: [main]
Command What it does
hivepod exec --detach [--timeout S] POD "CMD" Start a job and print its id.
hivepod exec --detach --follow POD "CMD" Start a job and stream it until it ends.
hivepod job status POD ID Status, exit code and the last lines of output.
hivepod job status POD ID --follow Stream the output until the job ends; exit with its code.
hivepod job status POD ID --wait Wait without printing the output.
hivepod jobs POD Recent jobs.
hivepod job cancel POD ID Stop a job and everything it started.
  • A job runs as root, from /home/hivepod/projects, with /bin/sh. Use bash -lc "..." if you need bash features or your login profile.
  • Default timeout: 1 hour. Maximum: 6 hours (--timeout 21600).
  • Up to 3 jobs run at once per pod. A pod keeps its 20 most recent jobs.
  • The pod must be running. Stopping, restarting or re-creating the pod ends its jobs.
  • Very chatty jobs keep only the last part of their output: about 2 MB once the log passes 10 MB.
  • Job ids accept a unique prefix, as shown by hivepod jobs.

The API behind these commands is POST /api/v1/hivepods/<pod>/jobs/, GET …/jobs/<id>/ and POST …/jobs/<id>/cancel/. AI assistants can use the MCP tools start_pod_job, pod_job_status and cancel_pod_job.

  • Temporary errors while DockHive deploys an update. The CLI retries status checks, and start/stop/restart, a couple of times by itself. If an error still gets through, its message includes the HTTP status and a request id. Quote both when you contact support.
  • pip install or npm ci fails with “Permission denied” in /tmp. /tmp is small and doesn’t allow running programs. Jobs, exec and terminals point TMPDIR at the data volume for you. If your build script sets its own temporary folder, use $TMPDIR or /home/hivepod/data/.tmp. See Files, limits and environment.
  • The pod is low on disk. hivepod status web1 shows disk used against the pod’s size.