Docker configuration and application setup for OpenClaw. Companion repository to openclaw-terraform-hetzner.
Note: This is a minimal, generic configuration with only essential skills activated. You're encouraged to customize it by adding ClawHub skills or creating your own custom skills (see Working with Skills).
┌──────────────┐ ┌──────────────────────┐
│ Laptop │──── git push ─────────▶│ GitHub │
│ (develop) │ │ (openclaw-config) │
│ │ └──────────────────────┘
│ │
│ │ build-and-push.sh ┌──────────────────────┐
│ │───────────────────────▶│ GHCR │
│ │ │ :latest :abc1234 │
│ │ └──────────────────────┘
│ │
│ │ make push-config ┌──────────────────────┐
│ │ make push-env │ Hetzner VPS │
│ │──── (infra repo) ─────▶│ ┌────────────────┐ │
│ │ make deploy │ │ Docker │ │
└──────────────┘ │ │ openclaw-gw │ │
│ └────────────────┘ │
│ :18789 (loopback) │
└──────────────────────┘
ssh openclaw@VPS_IP)openclaw-terraform-hetzner) set up with config/inputs.sh pointing CONFIG_DIR to this repodocker/.env.example for the full list; secrets live in the infra repo's secrets/openclaw.env)This repo is not cloned on the VPS. Instead, the infra repo's scripts copy specific files from your local checkout to the VPS:
| What | Pushed by | Lands at (VPS) |
|---|---|---|
docker/docker-compose.yml | make bootstrap (once) | ~/openclaw/docker-compose.yml |
config/* (openclaw.json, etc.) | make push-config | ~/.openclaw/ |
| Docker image | make deploy (pulls from GHCR) | Docker image cache |
| Secrets | make push-env | ~/openclaw/.env |
Provisioning and bootstrap are handled by the infra repo. See its README.
CONFIG_DIR in config/inputs.sh to point to this repo's directoryecho "$GHCR_TOKEN" | docker login ghcr.io -u $GHCR_USERNAME --password-stdin
bash scripts/build-and-push.sh
make bootstrap from the infra repo — copies docker-compose.yml, config, and secrets to VPSmake deploy from the infra repo — pulls the Docker image from GHCR and starts the container/startThere are two types of changes, and they have different workflows:
Config files are pushed to the VPS via SCP — no image rebuild needed.
edit → validate → commit → push → make push-config (infra repo)
config/, skills/, or hooks/bash scripts/validate-config.shmake push-config (SCPs config to VPS and restarts)Image changes require a rebuild and push to GHCR.
edit → commit → push → build-and-push.sh → make deploy (infra repo)
docker/Dockerfile (e.g. bump OPENCLAW_VERSION, add a binary)bash scripts/build-and-push.shmake deploy (pulls new image from GHCR and restarts)This repository includes a minimal set of generic skills in config/skills-manifest.txt. You can extend OpenClaw by adding ClawHub skills or creating custom skills.
ClawHub is the community skill registry for OpenClaw. To add a ClawHub skill:
pdf, ms-office-suite, jira)config/skills-manifest.txt and add the skill name
# PDF processing
pdf
bash scripts/build-and-push.sh
# Then from infra repo:
make deploy
The entrypoint.sh script auto-installs skills from the manifest on container startup via clawhub install.
Custom skills are user-defined commands or workflows. To create one:
Create the skill directory:
mkdir -p skills/my-skill
Write the skill manifest (skills/my-skill/skill.json):
{
"name": "my-skill",
"version": "1.0.0",
"description": "My custom skill",
"commands": {
"my-command": {
"handler": "my-command.sh"
}
}
}
Write the handler (skills/my-skill/my-command.sh):
#!/bin/bash
# Your custom logic here
echo "Hello from my-skill!"
Make it executable:
chmod +x skills/my-skill/my-command.sh
Push to VPS:
# From the infra repo:
make push-config
Custom skills in skills/ are copied to ~/.openclaw/workspace/skills/ on the VPS.
Use in OpenClaw:
/my-commandOpenClaw skills can include:
/command-nameFor detailed skill development documentation, see the OpenClaw Skill Development Guide.
The default configuration includes these generic ClawHub skills:
| Skill | Description | Use Case |
|---|---|---|
yt | YouTube transcript fetching and video search | "Get transcript for youtube.com/watch?v=..." |
agent-browser | Headless browser for JavaScript-heavy/paywalled pages | Access dynamic content |
system-monitor | CPU/RAM/GPU status check | "What's my server's CPU usage?" |
conventional-commits | Format commit messages per convention | Standardized commit messages |
These are intentionally minimal — add your own skills based on your workflows.
Back up your ~/.openclaw/workspace directory to a private git remote automatically. Runs as a Docker sidecar container with built-in cron, pushing to a configurable branch (default: auto). You can then manually merge auto into main via PR whenever you want.
Supports GitHub, GitLab, Bitbucket, and any git remote that accepts HTTPS push with inline authentication.
Choose one of the two options below — do not set both.
your-username/openclaw-workspace)repo scope.env (or infra repo's secrets/openclaw.env):
GIT_WORKSPACE_REPO=your-username/openclaw-workspace
GIT_WORKSPACE_TOKEN=ghp_your_personal_access_token
The token is passed to git via GIT_ASKPASS at runtime and is not embedded in the remote URL or persisted to .git/config.
https://user:token@gitlab.com/username/repo.githttps://x-token-auth:token@bitbucket.org/username/repo.git.env (or infra repo's secrets/openclaw.env):
GIT_WORKSPACE_REMOTE=https://user:token@gitlab.com/username/openclaw-workspace.git
Note: With this option, the URL (including credentials) is stored in
.git/configinside the workspace volume. The token is already present in the.envfile on the VPS, so this does not increase the attack surface.
GIT_WORKSPACE_BRANCH=auto
GIT_WORKSPACE_SYNC_SCHEDULE=0 4 * * *
Deploy — the sidecar auto-enables when either GIT_WORKSPACE_REPO or GIT_WORKSPACE_REMOTE is set:
# From infra repo:
make push-env && make deploy
The sidecar runs an initial sync on startup, then syncs on the configured cron schedule (default: daily at 4 AM UTC).
# From infra repo:
make workspace-sync
Remove or clear GIT_WORKSPACE_REPO / GIT_WORKSPACE_REMOTE from your .env and redeploy.
The gateway binds to loopback only (127.0.0.1:18789). Access it via SSH tunnel:
ssh -N -L 18789:127.0.0.1:18789 openclaw@VPS_IP
Then open http://localhost:18789 in your browser.
Secrets (API keys, tokens) are managed by the infra repo, not this repo.
This repo only contains docker/.env.example as documentation of what
variables are required.
In the infra repo:
secrets/openclaw.envmake push-env to push to VPS and restartImages are built locally and pushed to GHCR via scripts/build-and-push.sh:
ghcr.io/YOUR_USERNAME/openclaw-docker-config/openclaw-gateway:latest — main gateway imageghcr.io/YOUR_USERNAME/openclaw-docker-config/workspace-sync:latest — workspace git sync sidecar:<sha> tag pinned to the git commitOne-time GHCR login (laptop):
# Create a PAT at github.com/settings/tokens with write:packages scope
echo "$GH_TOKEN" | docker login ghcr.io -u $GHCR_USERNAME --password-stdin
Rollback to a previous version:
# On the VPS, in ~/openclaw/:
# Edit docker-compose.yml, change :latest to the SHA tag (e.g. :abc1234)
docker compose pull && docker compose up -d
Upgrade OpenClaw itself: bump OPENCLAW_VERSION in docker/Dockerfile, commit, push, then run scripts/build-and-push.sh followed by make deploy from the infra repo.
# From the infra repo:
make logs
# Or SSH in:
cd ~/openclaw && docker compose logs openclaw-gateway
Check for missing environment variables or invalid config JSON.
Ensure the host directories exist and are owned by the correct user:
sudo mkdir -p /home/openclaw/.openclaw/workspace
sudo chown -R 1000:1000 /home/openclaw/.openclaw
make push-env from infra repo to re-pushmake deploy from infra repobash scripts/validate-config.sh
Common causes:
openclaw.json# From the infra repo:
make status
To activate the pre-commit validation hook:
git config core.hooksPath .githooks
Shell
83.7%
Dockerfile
16.3%
Docker configuration and application setup for OpenClaw. Companion repository to openclaw-terraform-hetzner.
Note: This is a minimal, generic configuration with only essential skills activated. You're encouraged to customize it by adding ClawHub skills or creating your own custom skills (see Working with Skills).
┌──────────────┐ ┌──────────────────────┐
│ Laptop │──── git push ─────────▶│ GitHub │
│ (develop) │ │ (openclaw-config) │
│ │ └──────────────────────┘
│ │
│ │ build-and-push.sh ┌──────────────────────┐
│ │───────────────────────▶│ GHCR │
│ │ │ :latest :abc1234 │
│ │ └──────────────────────┘
│ │
│ │ make push-config ┌──────────────────────┐
│ │ make push-env │ Hetzner VPS │
│ │──── (infra repo) ─────▶│ ┌────────────────┐ │
│ │ make deploy │ │ Docker │ │
└──────────────┘ │ │ openclaw-gw │ │
│ └────────────────┘ │
│ :18789 (loopback) │
└──────────────────────┘
ssh openclaw@VPS_IP)openclaw-terraform-hetzner) set up with config/inputs.sh pointing CONFIG_DIR to this repodocker/.env.example for the full list; secrets live in the infra repo's secrets/openclaw.env)This repo is not cloned on the VPS. Instead, the infra repo's scripts copy specific files from your local checkout to the VPS:
| What | Pushed by | Lands at (VPS) |
|---|---|---|
docker/docker-compose.yml | make bootstrap (once) | ~/openclaw/docker-compose.yml |
config/* (openclaw.json, etc.) | make push-config | ~/.openclaw/ |
| Docker image | make deploy (pulls from GHCR) | Docker image cache |
| Secrets | make push-env | ~/openclaw/.env |
Provisioning and bootstrap are handled by the infra repo. See its README.
CONFIG_DIR in config/inputs.sh to point to this repo's directoryecho "$GHCR_TOKEN" | docker login ghcr.io -u $GHCR_USERNAME --password-stdin
bash scripts/build-and-push.sh
make bootstrap from the infra repo — copies docker-compose.yml, config, and secrets to VPSmake deploy from the infra repo — pulls the Docker image from GHCR and starts the container/startThere are two types of changes, and they have different workflows:
Config files are pushed to the VPS via SCP — no image rebuild needed.
edit → validate → commit → push → make push-config (infra repo)
config/, skills/, or hooks/bash scripts/validate-config.shmake push-config (SCPs config to VPS and restarts)Image changes require a rebuild and push to GHCR.
edit → commit → push → build-and-push.sh → make deploy (infra repo)
docker/Dockerfile (e.g. bump OPENCLAW_VERSION, add a binary)bash scripts/build-and-push.shmake deploy (pulls new image from GHCR and restarts)This repository includes a minimal set of generic skills in config/skills-manifest.txt. You can extend OpenClaw by adding ClawHub skills or creating custom skills.
ClawHub is the community skill registry for OpenClaw. To add a ClawHub skill:
pdf, ms-office-suite, jira)config/skills-manifest.txt and add the skill name
# PDF processing
pdf
bash scripts/build-and-push.sh
# Then from infra repo:
make deploy
The entrypoint.sh script auto-installs skills from the manifest on container startup via clawhub install.
Custom skills are user-defined commands or workflows. To create one:
Create the skill directory:
mkdir -p skills/my-skill
Write the skill manifest (skills/my-skill/skill.json):
{
"name": "my-skill",
"version": "1.0.0",
"description": "My custom skill",
"commands": {
"my-command": {
"handler": "my-command.sh"
}
}
}
Write the handler (skills/my-skill/my-command.sh):
#!/bin/bash
# Your custom logic here
echo "Hello from my-skill!"
Make it executable:
chmod +x skills/my-skill/my-command.sh
Push to VPS:
# From the infra repo:
make push-config
Custom skills in skills/ are copied to ~/.openclaw/workspace/skills/ on the VPS.
Use in OpenClaw:
/my-commandOpenClaw skills can include:
/command-nameFor detailed skill development documentation, see the OpenClaw Skill Development Guide.
The default configuration includes these generic ClawHub skills:
| Skill | Description | Use Case |
|---|---|---|
yt | YouTube transcript fetching and video search | "Get transcript for youtube.com/watch?v=..." |
agent-browser | Headless browser for JavaScript-heavy/paywalled pages | Access dynamic content |
system-monitor | CPU/RAM/GPU status check | "What's my server's CPU usage?" |
conventional-commits | Format commit messages per convention | Standardized commit messages |
These are intentionally minimal — add your own skills based on your workflows.
Back up your ~/.openclaw/workspace directory to a private git remote automatically. Runs as a Docker sidecar container with built-in cron, pushing to a configurable branch (default: auto). You can then manually merge auto into main via PR whenever you want.
Supports GitHub, GitLab, Bitbucket, and any git remote that accepts HTTPS push with inline authentication.
Choose one of the two options below — do not set both.
your-username/openclaw-workspace)repo scope.env (or infra repo's secrets/openclaw.env):
GIT_WORKSPACE_REPO=your-username/openclaw-workspace
GIT_WORKSPACE_TOKEN=ghp_your_personal_access_token
The token is passed to git via GIT_ASKPASS at runtime and is not embedded in the remote URL or persisted to .git/config.
https://user:token@gitlab.com/username/repo.githttps://x-token-auth:token@bitbucket.org/username/repo.git.env (or infra repo's secrets/openclaw.env):
GIT_WORKSPACE_REMOTE=https://user:token@gitlab.com/username/openclaw-workspace.git
Note: With this option, the URL (including credentials) is stored in
.git/configinside the workspace volume. The token is already present in the.envfile on the VPS, so this does not increase the attack surface.
GIT_WORKSPACE_BRANCH=auto
GIT_WORKSPACE_SYNC_SCHEDULE=0 4 * * *
Deploy — the sidecar auto-enables when either GIT_WORKSPACE_REPO or GIT_WORKSPACE_REMOTE is set:
# From infra repo:
make push-env && make deploy
The sidecar runs an initial sync on startup, then syncs on the configured cron schedule (default: daily at 4 AM UTC).
# From infra repo:
make workspace-sync
Remove or clear GIT_WORKSPACE_REPO / GIT_WORKSPACE_REMOTE from your .env and redeploy.
The gateway binds to loopback only (127.0.0.1:18789). Access it via SSH tunnel:
ssh -N -L 18789:127.0.0.1:18789 openclaw@VPS_IP
Then open http://localhost:18789 in your browser.
Secrets (API keys, tokens) are managed by the infra repo, not this repo.
This repo only contains docker/.env.example as documentation of what
variables are required.
In the infra repo:
secrets/openclaw.envmake push-env to push to VPS and restartImages are built locally and pushed to GHCR via scripts/build-and-push.sh:
ghcr.io/YOUR_USERNAME/openclaw-docker-config/openclaw-gateway:latest — main gateway imageghcr.io/YOUR_USERNAME/openclaw-docker-config/workspace-sync:latest — workspace git sync sidecar:<sha> tag pinned to the git commitOne-time GHCR login (laptop):
# Create a PAT at github.com/settings/tokens with write:packages scope
echo "$GH_TOKEN" | docker login ghcr.io -u $GHCR_USERNAME --password-stdin
Rollback to a previous version:
# On the VPS, in ~/openclaw/:
# Edit docker-compose.yml, change :latest to the SHA tag (e.g. :abc1234)
docker compose pull && docker compose up -d
Upgrade OpenClaw itself: bump OPENCLAW_VERSION in docker/Dockerfile, commit, push, then run scripts/build-and-push.sh followed by make deploy from the infra repo.
# From the infra repo:
make logs
# Or SSH in:
cd ~/openclaw && docker compose logs openclaw-gateway
Check for missing environment variables or invalid config JSON.
Ensure the host directories exist and are owned by the correct user:
sudo mkdir -p /home/openclaw/.openclaw/workspace
sudo chown -R 1000:1000 /home/openclaw/.openclaw
make push-env from infra repo to re-pushmake deploy from infra repobash scripts/validate-config.sh
Common causes:
openclaw.json# From the infra repo:
make status
To activate the pre-commit validation hook:
git config core.hooksPath .githooks
Shell
83.7%
Dockerfile
16.3%