Post

Deploy OpenClaw Gateway with Docker, Traefik and Authentik

Run OpenClaw close to your infrastructure so it can help operate files, containers, and chat integrations.

Deploy OpenClaw Gateway with Docker, Traefik and Authentik

Run OpenClaw close to your infrastructure so it can help operate files, containers, and chat integrations.

This is a standalone service guide. It explains the service in isolation so you can deploy it without copying unrelated parts of another stack.

All domains, emails, usernames, IP addresses, passwords, and tokens in this post are placeholders. Replace them for your own server, but do not publish real secrets or private infrastructure details.


What this service does

Route or access pattern:

1
agent.example.com

Main components:

1
OpenClaw gateway, persistent .openclaw state, workspace mount, optional Telegram delivery, optional Docker CLI/socket mounts.

Network and port model:

1
Traefik routes HTTPS to gateway port 18789; optional Docker socket access is high-trust admin capability.

In a Docker homelab, the safest pattern is to keep the application private on Docker networks and let the reverse proxy handle HTTPS traffic.


Folder layout

Use a dedicated folder:

1
2
3
4
5
/home/ubuntu/openclaw/
├── docker-compose.yml
├── .env
├── data/              # or service-specific persistent data
└── backups/           # optional local backup destination

Keep .env private. Public documentation should show only placeholders.


Environment file

Example .env values:

OPENCLAW_GATEWAY_TOKEN=<gateway-token>
OPENCLAW_TZ=UTC
DOCKER_GID=<host-docker-group-id>

Rules:

  • generate long random passwords and tokens;
  • keep .env out of Git;
  • do not paste production values into public tutorials;
  • rotate exposed credentials immediately if they ever leak.

Compose pattern

A minimal Traefik-aware Compose pattern looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
services:
  openclaw:
    image: <service-image>:<version>
    container_name: openclaw
    restart: unless-stopped
    env_file:
      - .env
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.openclaw.entrypoints=https"
      - "traefik.http.routers.openclaw.rule=Host(`agent.example.com`)"
      - "traefik.http.routers.openclaw.tls=true"
      - "traefik.http.routers.openclaw.tls.certresolver=cloudflare"
      - "traefik.http.services.openclaw.loadbalancer.server.port=<internal-port>"

networks:
  proxy:
    external: true

Adapt image names, volumes, internal ports, and service-specific environment variables for the actual application.


Deployment steps

Create the directory:

1
2
mkdir -p /home/ubuntu/openclaw
cd /home/ubuntu/openclaw

Create the .env file with placeholder values replaced by your own secrets:

1
2
nano .env
chmod 600 .env

Create or edit docker-compose.yml, then start the service:

1
docker compose up -d

Check status:

1
2
docker compose ps
docker compose logs --tail=100

Verification checklist

Verify the container is running:

1
docker ps --filter name=openclaw

Verify Traefik can see the route:

1
docker logs traefik --tail=100

Verify the public route, if the service has one:

1
curl -I https://service.example.com

Expected results vary by service:

  • 200 means the app is reachable;
  • 302 can be correct when authentication redirects to an identity provider;
  • 401 can be correct for APIs that require authentication;
  • 404 usually means the Traefik router rule did not match.

Backup checklist

Back up at least:

1
2
3
/home/ubuntu/openclaw/docker-compose.yml
/home/ubuntu/openclaw/.env        # private backup only
/home/ubuntu/openclaw/data/       # or named Docker volumes

For database-backed services, prefer application-aware dumps in addition to copying files:

1
docker compose exec <database> <dump-command> > backup.sql

Never publish backup archives. They often contain tokens, password hashes, uploads, user data, or private keys.


Common problems

The domain returns 404

Check:

  • the container has traefik.enable=true;
  • the service is attached to the proxy network;
  • the router Host(...) rule matches the exact domain;
  • traefik.docker.network=proxy is set when the container has multiple networks.

The domain returns bad gateway

Traefik found the route but cannot reach the internal app port.

Check the application logs and confirm the internal port used by:

1
traefik.http.services.<service>.loadbalancer.server.port

The service starts but data disappears after restart

The persistent directory or Docker volume is missing. Add a named volume or a bind mount for the service data before using it seriously.

Authentication loops or redirects fail

Check the public URL, trusted proxy headers, cookie domain, and whether the app knows it is behind HTTPS.


Security notes

  • Keep admin dashboards behind authentication or private networks.
  • Do not expose databases, caches, or admin APIs directly to the internet.
  • Use least-privilege API tokens.
  • Prefer internal Docker networks for dependencies.
  • Keep public docs generic: use example.com, <token>, <password>, and documentation IP ranges.

Service documentation map

This post is part of the standalone homelab service documentation series. Use these guides together when building the full stack:

This post is licensed under CC BY 4.0 by the author.