Skip to main content

Cài đặt OpenClaw bằng Portainer

Mục tiêu

CàiTài lạiliệu này hướng dẫn cài OpenClaw từ đầu bằng Portainer đểvới stackStack trên trạngWeb thái Full control, thay vì bị Limited control do được tạo bằng docker compose bên ngoài Portainer.editor.

Hướng dẫn phù hợp cho 2 kiểu triển khai:

Kiểu 1: Docker host + NAS

  • Docker chạy trên một máy Ubuntu
  • Config/workspace lưu trên NAS mount vào Docker host

Kiểu 2: Một máy duy nhất

  • Docker, config, workspace đều lưu trên cùng một máy

Sau khi hoàn tất:tất

  • OpenClaw chạy bằng Portainer Stack Container:container: openclaw-gateway
  • Port: 18789
  • Domain Domain:ví dụ: https://oclaw.thanhdv.example.com
  • WebSocket URL: wss://oclaw.thanhdv.example.com
  • Quản lý stack: Portainer Full Control

Mô hình truy cập qua domain

Client Browser
    ↓ HTTPS / WSS
Nginx Proxy Manager
    ↓ HTTP / WebSocket
Docker Host
    ↓
OpenClaw Gateway Container

Tóm tắt nhanh

Các bước chính:

  1. Chọn kiểu lưu dữ liệu: NAS hoặc một máy
  2. Tạo thư mục dữ liệu
  3. Tạo Gateway Token
  4. Tạo Portainer Stack bằng Web editor
  5. Nhập biến môi trường cho đúng đường dẫn lưu trữ
  6. Deploy OpenClaw Gateway
  7. Compose tự tạo config ban đầu trước khi start gateway
  8. Cấu hình NPM reverse proxy + WebSocket
  9. Truy cập domain HTTPS
  10. Approve device pairing nếu cần
  11. Quản lý stack bằng Portainer để giữ Full Control

Chuẩn bị thông tin môi trường

Trước khi làm, cần xác định các giá trị sau.

Ví dụ trong bài:

  • Docker Host IP: 192.168.1.103
  • Nginx Proxy Manager IP: 192.168.1.102
  • Domain OpenClaw: oclaw.example.com
  • OpenClaw port: 18789

Thay lại theo môi trường thực tế của bạn.

Chọn kiểu lưu dữ liệu

Kiểu A — Docker host + NAS

Dùng khi Docker chạy trên một máy Ubuntu, còn dữ liệu lớn hoặc workspace lưu trên NAS.

Ví dụ:

Config:    /mnt/dsm/docker/OpenClaw/config → Lưu file cấu hình OpenClaw
Workspace: /mnt/dsm/docker/OpenClaw/workspace Auth secret:Lưu workspace, file làm việc, memory, context
Auth:      /opt/appdata/openclaw/auth → Lưu auth secret local trên Docker host

Kiểu B — Cài toàn bộ trên một máy

Dùng khi không có NAS, mọi thứ lưu trên chính Docker host. Kiểu này đơn giản hơn, phù hợp với VPS, mini PC, hoặc homelab một máy.

Ví dụ:

Config:    /opt/appdata/openclaw/config → Lưu file cấu hình OpenClaw
Workspace: /opt/appdata/openclaw/workspace → Lưu workspace, file làm việc, memory, context
Auth:      /opt/appdata/openclaw/auth → Lưu auth secret local trên Docker host

Tạo thư mục dữ liệu

Nếu dùng NAS

sudo mkdir -p /mnt/dsm/docker/OpenClaw/config
sudo mkdir -p /mnt/dsm/docker/OpenClaw/workspace
sudo mkdir -p /opt/appdata/openclaw/auth

sudo chown -R 1000:1000 /mnt/dsm/docker/OpenClaw
sudo chown -R 1000:1000 /opt/appdata/openclaw

Các đường dẫn dùng trong Portainer:

OPENCLAW_CONFIG_HOST_DIR=/mnt/dsm/docker/OpenClaw/config
OPENCLAW_WORKSPACE_HOST_DIR=/mnt/dsm/docker/OpenClaw/workspace
OPENCLAW_AUTH_HOST_DIR=/opt/appdata/openclaw/auth

Nếu cài toàn bộ trên một máy

sudo mkdir -p /opt/appdata/openclaw/config
sudo mkdir -p /opt/appdata/openclaw/workspace
sudo mkdir -p /opt/appdata/openclaw/auth

sudo chown -R 1000:1000 /opt/appdata/openclaw

Các đường dẫn dùng trong Portainer:

OPENCLAW_CONFIG_HOST_DIR=/opt/appdata/openclaw/config
OPENCLAW_WORKSPACE_HOST_DIR=/opt/appdata/openclaw/workspace
OPENCLAW_AUTH_HOST_DIR=/opt/appdata/openclaw/auth

Tạo Gateway Token

Chạy trên Docker host:

openssl rand -hex 32

Ví dụ output:

aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899

Copy token này lại. Lát nữa sẽ nhập vào Portainer với biến:

OPENCLAW_GATEWAY_TOKEN

Token này dùng để đăng nhập OpenClaw Control UI.

Tạo OpenClaw Stack trong Portainer

Vào Portainer > Stacks > Add stack

Thiết lập:

  • Name: openclaw
  • Build method: Web editor

Dán compose sau vào Web editor:

Dán compose sau vào Web editor:

services:
  openclaw-gateway:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-gateway
    restart: unless-stopped
    init: true

    environment:
      TZ: Asia/Bangkok
      HOME: /home/node

      OPENCLAW_STATE_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
      OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
      OPENCLAW_AUTH_PROFILE_SECRET_DIR: /home/node/.config/openclaw

      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
      OPENCLAW_DISABLE_BONJOUR: "1"

      OPENCLAW_DOMAIN: ${OPENCLAW_DOMAIN}
      OPENCLAW_TRUSTED_PROXY_IP: ${OPENCLAW_TRUSTED_PROXY_IP}

    volumes:
      - ${OPENCLAW_CONFIG_HOST_DIR}:/home/node/.openclaw
      - ${OPENCLAW_WORKSPACE_HOST_DIR}:/home/node/.openclaw/workspace
      - ${OPENCLAW_AUTH_HOST_DIR}:/home/node/.config/openclaw

    ports:
      - "18789:18789"

    extra_hosts:
      - "host.docker.internal:host-gateway"

    cap_drop:
      - NET_RAW
      - NET_ADMIN

    security_opt:
      - no-new-privileges:true

    command:
      - sh
      - -lc
      - |
        node dist/index.js config set --batch-json "[
          {\"path\":\"gateway.mode\",\"value\":\"local\"},
          {\"path\":\"gateway.bind\",\"value\":\"lan\"},
          {\"path\":\"gateway.controlUi.allowInsecureAuth\",\"value\":false},
          {\"path\":\"gateway.controlUi.allowedOrigins\",\"value\":[
            \"https://${OPENCLAW_DOMAIN}\",
            \"http://127.0.0.1:18789\",
            \"http://localhost:18789\"
          ]},
          {\"path\":\"gateway.trustedProxies\",\"value\":[\"${OPENCLAW_TRUSTED_PROXY_IP}\"]}
        ]"

        exec node dist/index.js gateway --bind lan --port 18789

    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://127.0.0.1:18789/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
        ]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s

Điểm quan trọng của compose này:

  • Trước khi start gateway, container tự chạy: node dist/index.js config set ...
  • Sau đó mới chạy: node dist/index.js gateway --bind lan --port 18789

Nhờ vậy, cài mới sẽ không bị lỗi Missing config do thư mục config trống.

Thêm biến môi trường trong Portainer

Trong phần Environment variables của Portainer, thêm các biến dưới đây rồi nhấn Deploy the stack

Nếu dùng NAS

OPENCLAW_GATEWAY_TOKEN=token_vừa_tạo → Token dùng để đăng nhập Control UI
OPENCLAW_DOMAIN=oclaw.example.com → Domain dùng để truy cập OpenClaw, không có https:// phía trước
OPENCLAW_TRUSTED_PROXY_IP=192.168.1.102 → IP của Nginx Proxy Manager nhìn từ OpenClaw Gateway

OPENCLAW_CONFIG_HOST_DIR=/mnt/dsm/docker/OpenClaw/config
OPENCLAW_WORKSPACE_HOST_DIR=/mnt/dsm/docker/OpenClaw/workspace
OPENCLAW_AUTH_HOST_DIR=/opt/appdata/openclaw/auth

Nếu cài toàn bộ trên một máy

OPENCLAW_GATEWAY_TOKEN=token_vừa_tạo
OPENCLAW_DOMAIN=oclaw.example.com
OPENCLAW_TRUSTED_PROXY_IP=192.168.1.102

OPENCLAW_CONFIG_HOST_DIR=/opt/appdata/openclaw/config
OPENCLAW_WORKSPACE_HOST_DIR=/opt/appdata/openclaw/workspace
OPENCLAW_AUTH_HOST_DIR=/opt/appdata/openclaw/auth

Kiểm tra trạng thái Gateway

Chạy trên Docker host:

docker logs --tail 80 openclaw-gateway

Nếu thấy:

[gateway] ready

là OpenClaw Gateway đã chạy thành công.

Kiểm tra health:

curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz

Nếu lệnh trả về OK hoặc JSON hợp lệ thì gateway đã sẵn sàng.

Xem log realtime:

docker logs -f openclaw-gateway

Hoặc các bạn cũng có thể kiểm tra log và trạng thái trên Portainer nếu đã quen sử dụng.

Cấu hình Nginx Proxy Manager

Trong Nginx Proxy Manager, tạo hoặc sửa Proxy Host:

Domain Names: oclaw.example.com
Scheme: http
Forward Hostname / IP: 192.168.1.103 → IP của Docker host chạy OpenClaw
Forward Port: 18789
Websockets Support: ON
Block Common Exploits: ON

Tab SSL:

Request a new SSL Certificate hoặc chọn certificate đã có
Force SSL: ON
HTTP/2 Support: ON

Truy cập OpenClaw qua domain

Mở trình duyệt https://oclaw.example.com

Điền:

  • WebSocket URL: wss://oclaw.example.com 
  • Gateway Token: token đã tạo ở bước 6 
  • Password: bỏ trống

Sau đó bấm Connect

Nếu thiết bị hoặc trình duyệt này chưa từng được approve, OpenClaw có thể yêu cầu device pairing.

Approve thiết bị mới

Bạn có thể truy cập Portainer > Containers > openclaw (container mà bạn đã cài) > Console

Tại đây bạn chạy các lệnh 

// Lấy danh sách thiệt bị Paired và thiết bị Pending
openclaw devices list

// Thay 0883e383-3e7d-4abb-af40-65a52296a04c bằng request thực tế mà bạn thấy
openclaw devices approve 0883e383-3e7d-4abb-af40-65a52296a04c

Sau đó quay lại browser và bấm Connect lại.

Phụ lục

Ghi chú bảo mật

OpenClaw là agent gateway, có thể kết nối tool, browser, file, memory và automation. Không nên public rộng rãi nếu chưa có lớp bảo vệ phù hợp.

Khuyến nghị tối thiểu:

  • Luôn dùng HTTPS
  •  Không bật allowInsecureAuth khi dùng domain 
  • Giữ Gateway Token 
  • Giữ Device Pairing 
  • Bật WebSocket qua NPM 
  • Dùng NPM Access List nếu chỉ muốn truy cập nội bộ 

Với domain HTTPS: https://oclaw.example.com

WebSocket URL phải là: wss://oclaw.example.com

Không dùng ws://oclaw.example.com vì domain đang chạy qua HTTPS.

Lỗi Missing config

Hiện tượng

Container OpenClaw restart liên tục. Log có dạng:

[gateway] loading configuration…
[gateway] resolving authentication…
Missing config. Run `openclaw setup` or set gateway.mode=local (or pass --allow-unconfigured).
Nguyên nhân

Lỗi này xảy ra khi thư mục config của OpenClaw đang trống, chưa có openclaw.json hợp lệ.

Thường gặp khi:

  • Xóa sạchthư mục config cũ 
  • Mount sai thư mục config 
  • Container start gateway trước khi tạo config
Cách tránh lỗi

Dùng compose trong tài liệu này.

Compose đã cấu hình để container tự chạy:

node dist/index.js config set --batch-json ...

trước khi chạy gateway.

Cách sửa nếu vẫn gặp lỗi

Kiểm tra mount config:

Nếu dùng NAS:

ls -lah /mnt/dsm/docker/OpenClaw/config

Nếu cài toàn bộ trên một máy:

ls -lah /opt/appdata/openclaw/config

Kiểm tra log:

docker logs --tail 80 openclaw-gateway

Nếu vẫn thiếu config, vào Portainer kiểm tra lại các biến:

OPENCLAW_CONFIG_HOST_DIR
OPENCLAW_WORKSPACE_HOST_DIR
OPENCLAW_AUTH_HOST_DIR
OPENCLAW_DOMAIN
OPENCLAW_TRUSTED_PROXY_IP
OPENCLAW_GATEWAY_TOKEN

Sau khi sửa biến, re-deploy stack trong Portainer.

Xóa OpenClaw cũ

SSHnếu vàođã Ubuntutừng VMcài rồi

Xóa chạy:docker container
# Dừng stack cũ nếu trước đó cài bằng Docker Compose CLI
cd /opt/stacks/openclaw 2>/dev/null && docker compose down -v --remove-orphans || true

# Xóa mọi container có tên openclaw
docker ps -aq --filter "name=openclaw" | xargs -r docker rm -f

# Xóa network openclaw cũ nếu còn
docker network ls --format '{{.Name}}' | grep -E '^openclaw' | xargs -r docker network rm || true

# Xóa toànimage bộcũ để lần sau pull lại mới
docker image rm ghcr.io/openclaw/openclaw:latest 2>/dev/null || true
Xóa dữ liệu OpenClaw

Với kiểu NAS:

sudo rm -rf /opt/stacks/openclaw
sudo rm -rf /opt/appdata/openclaw
sudo rm -rf /mnt/dsm/docker/OpenClaw
#

Với Xóakiểu imagemột máy:

để Portainer pull lại sạch docker image
sudo rm ghcr.io/openclaw/openclaw:latest-rf 2>/dev/nullopt/stacks/openclaw
||sudo truerm -rf /opt/appdata/openclaw

Kiểm tra lại:

docker ps -a | grep -i openclaw || echo "OK: no openclaw containers"
docker network ls | grep -i openclaw || echo "OK: no openclaw networks"
ls -ld /opt/stacks/openclaw /opt/appdata/openclaw /mnt/dsm/docker/OpenClaw 2>/dev/null || echo "OK: data removed"

2. Tạo lại thư mục sạch

sudo mkdir -p /mnt/dsm/docker/OpenClaw/config
sudo mkdir -p /mnt/dsm/docker/OpenClaw/workspace
sudo mkdir -p /opt/appdata/openclaw/auth

sudo chown -R 1000:1000 /mnt/dsm/docker/OpenClaw
sudo chown -R 1000:1000 /opt/appdata/openclaw

Tạo gateway token mới:

openssl rand -hex 32

Copy token này lại. Lát nữa nhập vào Portainer với biến:

OPENCLAW_GATEWAY_TOKEN

3. Tạo stack OpenClaw trong Portainer

Vào Portainer:

Stacks → Add stack

Thiết lập:

Name: openclaw
Build method: Web editor

Dán compose sau:

services:
  openclaw-gateway:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-gateway
    restart: unless-stopped
    init: true

    environment:
      TZ: Asia/Bangkok
      HOME: /home/node

      OPENCLAW_STATE_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
      OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
      OPENCLAW_AUTH_PROFILE_SECRET_DIR: /home/node/.config/openclaw

      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
      OPENCLAW_DISABLE_BONJOUR: "1"

    volumes:
      - /mnt/dsm/docker/OpenClaw/config:/home/node/.openclaw
      - /mnt/dsm/docker/OpenClaw/workspace:/home/node/.openclaw/workspace
      - /opt/appdata/openclaw/auth:/home/node/.config/openclaw

    ports:
      - "18789:18789"

    extra_hosts:
      - "host.docker.internal:host-gateway"

    cap_drop:
      - NET_RAW
      - NET_ADMIN

    security_opt:
      - no-new-privileges:true

    command:
      - node
      - dist/index.js
      - gateway
      - --bind
      - lan
      - --port
      - "18789"

    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://127.0.0.1:18789/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
        ]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s

Trong phần Environment variables, thêm:

OPENCLAW_GATEWAY_TOKEN = token vừa tạo

Sau đó bấm:

Deploy the stack

Vì stack được tạo trực tiếp bằng Portainer Web editor, Portainer sẽ có quyền quản lý đầy đủ stack này.


4. Sửa lỗi Missing config sau khi cài mới

Sau khi deploy, container có thể restart liên tục với lỗi:

Missing config. Run `openclaw setup` or set gateway.mode=local

Nguyên nhân là thư mục config mới đang trống, chưa có openclaw.json.

Tạo config thủ công bằng cách chạy trên Ubuntu:

TOKEN="$(docker inspect openclaw-gateway --format '{{range .Config.Env}}{{println .}}{{end}}' | sed -n 's/^OPENCLAW_GATEWAY_TOKEN=//p')"

echo "$TOKEN"

Nếu token hiện ra, chạy tiếp:

docker run --rm -it \
  --user 1000:1000 \
  -e TZ=Asia/Bangkok \
  -e HOME=/home/node \
  -e OPENCLAW_STATE_DIR=/home/node/.openclaw \
  -e OPENCLAW_CONFIG_DIR=/home/node/.openclaw \
  -e OPENCLAW_CONFIG_PATH=/home/node/.openclaw/openclaw.json \
  -e OPENCLAW_WORKSPACE_DIR=/home/node/.openclaw/workspace \
  -e OPENCLAW_AUTH_PROFILE_SECRET_DIR=/home/node/.config/openclaw \
  -e OPENCLAW_GATEWAY_TOKEN="$TOKEN" \
  -e OPENCLAW_DISABLE_BONJOUR=1 \
  -v /mnt/dsm/docker/OpenClaw/config:/home/node/.openclaw \
  -v /mnt/dsm/docker/OpenClaw/workspace:/home/node/.openclaw/workspace \
  -v /opt/appdata/openclaw/auth:/home/node/.config/openclaw \
  ghcr.io/openclaw/openclaw:latest \
  node dist/index.js config set --batch-json '[
    {"path":"gateway.mode","value":"local"},
    {"path":"gateway.bind","value":"lan"},
    {"path":"gateway.controlUi.allowInsecureAuth","value":false},
    {"path":"gateway.controlUi.allowedOrigins","value":[
      "https://oclaw.thanhdv.com",
      "http://127.0.0.1:18789",
      "http://localhost:18789"
    ]},
    {"path":"gateway.trustedProxies","value":["192.168.1.102"]}
  ]'

Trong đó:

192.168.1.102 = IP của Nginx Proxy Manager
192.168.1.103 = IP của Ubuntu VM chạy OpenClaw

Nếu IP NPM khác thì thay lại cho đúng.

Restart container:

docker restart openclaw-gateway

Kiểm tra log:

docker logs --tail 80 openclaw-gateway

Nếu thấy:

[gateway] ready

là OpenClaw Gateway đã chạy thành công.


5. Kiểm tra health

Chạy:

curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz

Nếu trả về trạng thái OK hoặc JSON hợp lệ thì gateway đã sẵn sàng.


6. Cấu hình Nginx Proxy Manager

Trong NPM, tạo hoặc sửa proxy host:

Domain Names: oclaw.thanhdv.com
Scheme: http
Forward Hostname / IP: 192.168.1.103
Forward Port: 18789
Websockets Support: ON
Block Common Exploits: ON

Tab SSL:

Request / chọn SSL certificate
Force SSL: ON
HTTP/2 Support: ON

Tab Advanced:

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;

OpenClaw Control UI dùng WebSocket nên bắt buộc bật Websockets Support.


7. Truy cập OpenClaw qua domain

Mở trình duyệt:

https://oclaw.thanhdv.com

Điền:

WebSocket URL: wss://oclaw.thanhdv.com
Gateway Token: token mới đã tạo
Password: bỏ trống

Thiết bị hoặc trình duyệt mới có thể cần approve device pairing một lần.


8. Approve thiết bị mới

Nếu đăng nhập bằng thiết bị mới và bị báo pairing, chạy:

docker exec -it openclaw-gateway sh -lc \
'node dist/index.js devices list --url ws://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"'

Tìm requestId, sau đó approve:

docker exec -it openclaw-gateway sh -lc \
'node dist/index.js devices approve <REQUEST_ID> --url ws://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"'

Sau đó quay lại browser và bấm Connect lại.

Lưu ý: mỗi thiết bị hoặc browser mới thường cần approve một lần. Thiết bị đã approve thì lần sau không cần, trừ khi xóa cookie/site data, dùng incognito, đổi domain, hoặc reset config/token.


9. Xác nhận Portainer Full Control

Vào:

Portainer → Stacks → openclaw

Stack nên có tab Editor và không còn trạng thái Limited.

Từ thời điểm này, quản lý OpenClaw bằng Portainer:

Portainer → Stacks → openclaw → Editor / Update the stack

Không dùng lại cách cũ:

cd /opt/stacks/openclaw
docker compose up -d

Vì nếu tạo hoặc redeploy ngoài Portainer, stack có thể quay lại trạng thái Limited control.


Ghi chú bảo mật

OpenClaw là agent gateway có thể kết nối tool, file, browser, memory và automation. Không nên public rộng rãi nếu chưa có lớp bảo vệ phù hợp.

Khuyến nghị tối thiểu:

HTTPS bắt buộc
Gateway token bật
Device pairing bật
NPM Access List nếu chỉ dùng nội bộ
Không bật allowInsecureAuth khi dùng domain HTTPS

Với domain https://oclaw.thanhdv.com, WebSocket URL nên luôn là:

wss://oclaw.thanhdv.com