deploy
npx machina-cli add skill jikig-ai/soleur/deploy --openclawDeploy Skill
Deploy a containerized application to a remote server via Docker and SSH.
Environment Variables
| Variable | Required | Description | Example |
|---|---|---|---|
DEPLOY_HOST | Yes | SSH target (user@host) | root@203.0.113.10 |
DEPLOY_IMAGE | Yes | GHCR image path | ghcr.io/org/app |
DEPLOY_HEALTH_URL | No | Health check endpoint | http://203.0.113.10:3000/health |
DEPLOY_CONTAINER | No | Container name (default: image basename) | myapp |
DEPLOY_DOCKERFILE | No | Dockerfile path (default: ./Dockerfile) | ./docker/Dockerfile.prod |
For first-time server setup, see hetzner-setup.md.
Phase 0: Validate
Check prerequisites before starting the build.
Run these checks as separate Bash commands:
- Verify
DEPLOY_HOSTis set:printenv DEPLOY_HOST(must produce output) - Verify
DEPLOY_IMAGEis set:printenv DEPLOY_IMAGE(must produce output) - Verify Docker daemon:
docker info > /dev/null 2>&1 - Verify SSH connectivity:
ssh -o ConnectTimeout=5 -o BatchMode=yes <deploy-host> "echo OK"(replace<deploy-host>with the actual DEPLOY_HOST value) - Verify Dockerfile exists:
test -f ./Dockerfile(or the DEPLOY_DOCKERFILE path if set)
If any check fails, stop and report the error. Do not proceed to Phase 1.
Phase 1: Plan
Show the deployment summary and ask for confirmation.
Use the AskUserQuestion tool to present:
Question: "Deploy this configuration?"
Options:
- Deploy -- Proceed with build and deployment
- Cancel -- Abort deployment
Display before asking:
Deployment Plan
Image: <DEPLOY_IMAGE>:<git-short-sha>
Target: <DEPLOY_HOST>
Container: <DEPLOY_CONTAINER or image basename>
Dockerfile: <DEPLOY_DOCKERFILE or ./Dockerfile>
Health URL: <DEPLOY_HEALTH_URL or none>
Resolve <git-short-sha> by running git rev-parse --short HEAD.
If the user selects Cancel, stop execution.
Phase 2: Execute
Run deploy.sh to build, push, and deploy:
bash ./plugins/soleur/skills/deploy/scripts/deploy.sh
The script handles:
- Build Docker image tagged with git SHA and
:latest - Push both tags to GHCR
- SSH to remote host: pull image, stop old container, start new container
Phase 3: Verify
After deployment completes, verify the service is running.
If DEPLOY_HEALTH_URL is set:
The deploy script runs a health check (5 attempts, 3s apart).
If the health check fails:
Health check failed. Debug with:
ssh <DEPLOY_HOST> "docker logs <container-name> --tail 50"
If DEPLOY_HEALTH_URL is not set:
Report deployment as complete without health verification:
Deployed <git-short-sha> to <DEPLOY_HOST>
No health URL configured -- skipping verification.
Important Rules
- Never hardcode secrets in the deploy script. Use environment variables.
- Never deploy without user confirmation (Phase 1 gate).
- The script uses
set -euo pipefail-- any command failure aborts the deployment. - Container restart uses stop+pull+start, not
docker restart, to ensure the new image is used.
Source
git clone https://github.com/jikig-ai/soleur/blob/main/plugins/soleur/skills/deploy/SKILL.mdView on GitHub Overview
Automates container deployment to a remote host by building Docker images, pushing to GHCR, and deploying over SSH. It includes a validation gate, a plan phase for confirmation, and an optional health check to verify success.
How This Skill Works
Follows a four-phase workflow: Phase 0 validates prerequisites (host, image, Docker daemon, SSH access, Dockerfile). Phase 1 presents a deployment plan and requires user confirmation. Phase 2 executes deploy.sh to build, push to GHCR, and deploy on the remote host by pulling the new image and restarting the container. Phase 3 runs a health check if a health URL is configured; otherwise it reports completion.
When to Use It
- Releasing a new containerized app to a production remote server.
- Pushing updated images to GHCR and redeploying on the target host.
- Deploying to a staging or test server via SSH as part of CI/CD.
- Automating deployments triggered by CI pipelines to remote hosts.
- Performing a ship-to-remote deployment with health verification.
Quick Start
- Step 1: Configure env vars: DEPLOY_HOST, DEPLOY_IMAGE, and optional DEPLOY_HEALTH_URL, DEPLOY_CONTAINER, DEPLOY_DOCKERFILE.
- Step 2: Run Phase 0 prerequisites checks to validate inputs and Docker/SSH readiness.
- Step 3: Execute the deployment by running bash ./plugins/soleur/skills/deploy/scripts/deploy.sh.
Best Practices
- Validate DEPLOY_HOST and DEPLOY_IMAGE before starting; run Phase 0 checks separately.
- Never hardcode secrets; use environment variables for credentials and config.
- Require Phase 1 user confirmation to prevent accidental deployments.
- Prefer health checks via DEPLOY_HEALTH_URL to verify a healthy deploy; inspect logs if failed.
- Ensure the deploy script uses set -euo pipefail to abort on errors.
Example Use Cases
- Deploy a Node.js app to a Hetzner server by pushing the image to GHCR and deploying via SSH.
- Automate a production release where the target server pulls the latest image and restarts the container.
- Redeploy after a code merge with a health check to verify uptime.
- Push updated container images from CI and deploy to a staging server for QA.
- Coordinate ship-to-remote deployments across environments using the same workflow.