Openclaw TUI

Migrating OpenClaw to Docker on Ubuntu 24.04 (CLI Only)

Moving a bare-metal OpenClaw instance to a Docker container is one of the best ways to isolate your AI agent’s environment, manage updates seamlessly, and prevent host file permission conflicts.

This guide provides a step-by-step walkthrough for migrating your OpenClaw setup from an old Ubuntu 24.04 Server (headless) to a fresh Ubuntu 24.04 Server running Docker without GUI desktop.

Architecture Overview

When running OpenClaw in Docker, we do not need to backup the entire application directory (like node_modules or binaries). We only need the “Big Three” state elements:

  • openclaw.json (System configuration and tokens)
  • workspace/ (Agent memories, MEMORY.md, and SOUL.md)
  • auth-profile/ (Persistent channel authentication tokens)

We will bind-mount these directories from the host VPS into the isolated container so that your agent’s memory remains persistent.

Step 1: Export Backup from the Old VPS

Log into your old VPS via SSH and archive only the core configuration and memory files.

# Navigate to the traditional OpenClaw directory
cd ~/.openclaw

# Create a compressed tarball of the essential state data
tar -czf ~/openclaw_core_backup.tar.gz openclaw.json workspace/ auth-profile/

Note: If auth-profile/ does not exist in your setup, you can omit it from the tar command.

Step 2: Install Docker & Compose on the New VPS

Log into your new, fresh Ubuntu 24.04 VPS. First, verify if Docker is installed. If your system used the default Ubuntu repository, you might have the core engine but miss the crucial compose plugin.

1. Install the Latest Docker Engine

sudo apt update
sudo apt install -y docker.io

2. Install Docker Compose V2 Plugin Manually

Since Ubuntu 24.04’s default package manager sometimes misses the unified plugin binary, install it directly from the official Docker GitHub release:

# Create CLI plugins directory
mkdir -p ~/.docker/cli-plugins/

# Download the latest stable Docker Compose binary
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

# Make the binary executable
chmod +x ~/.docker/cli-plugins/docker-compose

# Verify the installation
docker compose version

(Expected output: Docker Compose version v2.x.x)

Step 3: Set Up Target Directory Structure

We will create a structured home folder named openclaw-docker-1 to hold your configurations cleanly without overlapping paths.

# Create deployment directory
mkdir -p ~/openclaw-docker
mkdir -p ~/openclaw-docker-1/config ~/openclaw-docker-1/workspace ~/openclaw-docker-1/auth-profile

Step 4: Transfer and Restore the Backup

  1. Securely copy (scp) the backup file from your local machine or old server directly into the new VPS:
    scp openclaw_core_backup.tar.gz ubuntu@your-new-vps-ip:/tmp/
  2. Extract the archive components directly into their target paths inside ~/openclaw-docker-1/:
    # Extract to a temporary area
    mkdir -p /tmp/oc-restore && tar -xzf /tmp/openclaw_core_backup.tar.gz -C /tmp/oc-restore
    
    # Move components to their respective custom directories
    mv /tmp/oc-restore/openclaw.json ~/openclaw-docker-1/config/
    mv /tmp/oc-restore/workspace/* ~/openclaw-docker-1/workspace/
    mv /tmp/oc-restore/auth-profile/* ~/openclaw-docker-1/auth-profile/ 2>/dev/null
    
    # Clean up temporary files
    rm -rf /tmp/oc-restore /tmp/openclaw_core_backup.tar.gz

Step 5: Adjust Configurations for Docker

Because the application inside the container runs under a universal path structure, you must update the workspace destination path inside your configuration file.

  1. Open openclaw.json:
    nano ~/openclaw-docker-1/config/openclaw.json
  2. Locate the workspace property under the agent configurations and change it from your old local path (e.g., /home/ubuntu/...) to the explicit internal container path:
    {
      "agents": {
        "defaults": {
          "workspace": "/app/workspace"
        }
      }
    }
  3. Save and close (Ctrl+O, Enter, Ctrl+X).

Set Proper File Ownership

Docker containers execute their runtime processes using a non-root user (typically UID 1000). Grant this user explicit read/write privileges over your data folder:

sudo chown -R 1000:1000 ~/openclaw-docker-1
sudo chmod -R 775 ~/openclaw-docker-1

Step 6: Create the Docker Compose Stack

Navigate to your Docker project folder and create the deployment file:

cd ~/openclaw-docker
nano docker-compose.yml

Paste the following configurations:

services:
  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-gateway
    restart: unless-stopped
    ports:
      - "18789:18789"
    environment:
      - NODE_ENV=production
      - OPENCLAW_CONFIG_PATH=/app/config/openclaw.json
      - OPENCLAW_WORKSPACE_PATH=/app/workspace
    volumes:
      - ~/openclaw-docker-1/workspace:/app/workspace
      - ~/openclaw-docker-1/config:/app/config
      - ~/openclaw-docker-1/auth-profile:/app/auth-profile
      - /var/run/docker.sock:/var/run/docker.sock

Launch your containerized instance in detached mode:

docker compose up -d

Step 7: Running OpenClaw Commands in Docker

Since OpenClaw lives entirely within an isolated ecosystem, standard shell execution relies on passing instructions through the container stream.

1. General CLI Management Prefix

To run any traditional openclaw command, execute it via your host compose structure:

docker compose exec openclaw openclaw <command>

2. Common Utility Commands

  • Check System & Channel Status:
    docker compose exec openclaw openclaw status
  • Run Interactive Onboarding Wizard:
    docker compose exec openclaw openclaw onboard
  • Verify Memory Context Indexing:

    docker compose exec openclaw openclaw memory status

  • Check and trailing the logs:
docker compose logs -f openclaw
  • Openclaw update
docker compose down
docker compose pull
docker compose up -d
docker image prune -f

3. Launching the Interactive TUI Dashboard

To run the full text-based terminal user interface, pass the interactive -it execution flags to maintain input synchronization:

docker compose exec -it openclaw openclaw tui

Step 8: Terminal Convenience Shortcut (Optional)

To save typing the long Docker prefix every time you inspect your agent, append an alias to your user’s .bashrc profile:

echo "alias openclaw=\"docker compose -f ~/openclaw-docker/docker-compose.yml exec openclaw openclaw\"" >> ~/.bashrc
source ~/.bashrc

Now, typing a direct shorthand command like openclaw status or openclaw memory status from anywhere on your server translates automatically into your running container!

Troubleshooting & Operations Notes

1. Internal Management Service Warnings

Do not run openclaw gateway restart inside a container. Because the application runs as the root container foreground process, it does not rely on a systemd supervisor environment. To cycle your service properly after changing configuration attributes, issue standard life-cycle instructions via the host runtime:

cd ~/openclaw-docker-1 && docker compose restart openclaw

2. Lockfile Allocation & Path Mismatches

If you see Error: EACCES: permission denied, open '/app/config/openclaw.json.lock', it means the configuration file was mounted standalone instead of its containing folder, or file permissions are broken. Ensure your docker-compose.yml binds the entire directory ~/openclaw-docker-1/config:/app/config and that you have run sudo chown -R 1000:1000 ~/openclaw-docker-1 on your host.

3. Upstream Provider Endpoint Disconnects (OpenRouter 404 Guardrails)

If the system logs output 404 No endpoints available matching your guardrail restrictions and data policy, OpenRouter is blocking requests due to a strict privacy flag matching error with your chosen endpoint (e.g. using free public endpoints with a zero-data-retention profile). To resolve this, open your browser, navigate to https://openrouter.ai/settings/privacy, and adjust your data retention filters, or swap your model in openclaw.json to a trusted premium endpoint such as openrouter/stepfun/step-3.5-flash or openrouter/google/gemini-2.5-flash.