🪁PaaS

Self-Host OpenClaw on Fly.io

Deploy OpenClaw on Fly.io with persistent volumes, automatic TLS, and private networking. Beginner-friendly guide using flyctl with full configuration walkthrough.

Difficulty: beginnerTime: ~15 minCost: ~$10-15/mo

Self-Host OpenClaw on Fly.io

Fly.io is one of the simplest paths to self-hosting OpenClaw. It handles Docker builds, TLS certificates, volume persistence, and global networking out of the box. You configure a single fly.toml file, run fly deploy, and get a running instance with a public URL in minutes.

This guide walks through the full setup, from installing flyctl to accessing your running OpenClaw instance.

Quick Path

For users already familiar with Fly.io:

  1. Clone the OpenClaw repo and cd into it
  2. fly apps create openclaw (pick your preferred region)
  3. fly volumes create openclaw_data --size 1 --region your-region
  4. Create fly.toml with shared-cpu-2x, 2048 MB RAM, volume mount at /data
  5. fly secrets set OPENCLAW_GATEWAY_TOKEN=... ANTHROPIC_API_KEY=...
  6. fly deploy
  7. fly ssh console to create /data/openclaw.json config
  8. Access at https://openclaw.fly.dev

Prerequisites

Install and authenticate flyctl:

# macOS
brew install flyctl

# Linux
curl -L https://fly.io/install.sh | sh

# Authenticate
fly auth login

Step 1: Clone the OpenClaw Repository

git clone https://github.com/openclaw/openclaw.git
cd openclaw

Step 2: Create the Fly.io Application

Create a new application on Fly.io. The name must be globally unique:

fly apps create openclaw

If openclaw is taken, choose a different name (e.g., openclaw-yourname) and use that name throughout this guide.

Select a region when prompted. Choose one close to your location for the lowest latency. Common choices:

Region CodeLocation
iadVirginia, US
ordChicago, US
lhrLondon, UK
amsAmsterdam, NL
nrtTokyo, JP
sydSydney, AU

Step 3: Create a Persistent Volume

OpenClaw stores its state (sessions, configuration, workspace data) on disk. A Fly.io volume provides persistent storage that survives deployments and restarts:

fly volumes create openclaw_data \
  --size 1 \
  --region iad \
  --app openclaw

This creates a 1 GB volume. Adjust the size if you anticipate storing large codebases or many sessions. The volume must be in the same region as your app.

Verify the volume was created:

fly volumes list --app openclaw

Step 4: Configure fly.toml

Create the fly.toml configuration file in the root of the cloned repository:

app = "openclaw"
primary_region = "iad"

[build]
  dockerfile = "Dockerfile"

[env]
  NODE_ENV = "production"
  OPENCLAW_STATE_DIR = "/data"
  NODE_OPTIONS = "--max-old-space-size=1536"

[processes]
  app = "node server.js --bind lan --port 3000"

[[services]]
  protocol = "tcp"
  internal_port = 3000

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = false
  auto_start_machines = true
  min_machines_running = 1

[[vm]]
  size = "shared-cpu-2x"
  memory = 2048

[mounts]
  source = "openclaw_data"
  destination = "/data"

Key configuration details:

Step 5: Set Secrets

Fly.io secrets are encrypted environment variables injected at runtime. They never appear in logs or the dashboard:

fly secrets set \
  OPENCLAW_GATEWAY_TOKEN="your-secure-gateway-token" \
  ANTHROPIC_API_KEY="sk-ant-your-key-here" \
  --app openclaw

Generate a strong gateway token:

# Generate a random token
openssl rand -hex 32

Step 6: Deploy

fly deploy

Fly.io builds the Docker image remotely, pushes it to its registry, and starts a machine with your configuration. The first deploy takes 2-5 minutes as it builds the image from scratch. Subsequent deploys are faster due to layer caching.

Monitor the deployment:

fly status --app openclaw
fly logs --app openclaw

Wait until the status shows the machine as started and the health checks pass.

Step 7: Configure OpenClaw

Create the OpenClaw configuration file on the persistent volume:

fly ssh console --app openclaw

Once inside the container:

cat > /data/openclaw.json << 'EOF'
{
  "permissions": {
    "allowedTools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
    "allowedCommands": ["git", "npm", "node", "python3", "pip"]
  },
  "security": {
    "maxSessionDuration": "4h",
    "requireAuth": true
  }
}
EOF
exit

Restart the app to pick up the new configuration:

fly apps restart openclaw

Step 8: Access OpenClaw

Your instance is live at:

https://openclaw.fly.dev

Replace openclaw with your app name if you used a different one.

Private Deployment

If you prefer to keep OpenClaw completely off the public internet, remove the allocated IP addresses:

# List current IPs
fly ips list --app openclaw

# Release public IPs
fly ips release <ipv4-address> --app openclaw
fly ips release <ipv6-address> --app openclaw

With no public IPs, the app is only accessible through Fly.io's private WireGuard network. Use fly proxy to access it from your local machine:

fly proxy 18789:3000 --app openclaw

Then open http://localhost:18789 in your browser. The proxy creates a secure WireGuard tunnel between your machine and the Fly.io private network.

Scaling

Vertical Scaling

To increase the machine size, update fly.toml and redeploy:

[[vm]]
  size = "shared-cpu-4x"
  memory = 4096
fly deploy

Horizontal Scaling

OpenClaw is primarily a single-instance application due to its filesystem-based state. If you need multiple instances for different projects, create separate Fly apps with their own volumes.

Updating OpenClaw

When a new version is released:

cd openclaw
git pull origin main
fly deploy

Fly.io performs a rolling deployment: it starts a new machine with the updated image, waits for health checks to pass, then stops the old machine. Your volume data at /data is preserved.

Security Best Practices

Troubleshooting

Deploy fails with "no machines in group app"

This usually means the volume and machine are in different regions. Verify:

fly volumes list --app openclaw

Ensure the volume region matches primary_region in fly.toml.

Health checks failing

Check the logs for startup errors:

fly logs --app openclaw

Common causes:

Test the health endpoint manually:

fly ssh console --app openclaw -C "curl -s http://localhost:3000/health"

Out of memory

If the machine keeps restarting with OOM errors, increase the memory allocation in fly.toml:

[[vm]]
  size = "shared-cpu-2x"
  memory = 4096

Also increase the Node.js heap limit in the env section:

[env]
  NODE_OPTIONS = "--max-old-space-size=3072"

Then redeploy with fly deploy.

Volume is full

Check disk usage:

fly ssh console --app openclaw -C "df -h /data"

If the volume is full, extend it:

fly volumes extend <volume-id> --size 3 --app openclaw

Cannot connect after removing public IPs

Make sure you are using fly proxy, not trying to access the .fly.dev URL:

fly proxy 18789:3000 --app openclaw

If the proxy hangs, ensure WireGuard is configured:

fly wireguard create

Cost Breakdown

ResourceMonthly Cost
shared-cpu-2x (2 GB RAM)~$10.70
1 GB persistent volume~$0.15
Outbound bandwidth (first 100 GB)Included
TLS certificateIncluded
Total~$11

With auto_stop_machines = true, costs drop further since you only pay for time the machine is running. However, this adds 3-10 seconds of cold-start latency when the machine spins back up.

Backup

Create a backup of your OpenClaw data:

# SSH in and create a tarball
fly ssh console --app openclaw -C "tar czf /tmp/openclaw-backup.tar.gz -C /data ."

# Download it to your local machine
fly ssh sftp get /tmp/openclaw-backup.tar.gz ./openclaw-backup.tar.gz --app openclaw

Schedule periodic backups by combining this with a cron job on your local machine or a CI/CD pipeline.

Frequently Asked Questions

How much does OpenClaw on Fly.io cost?

With a shared-cpu-2x VM (2 shared vCPUs, 2 GB RAM) and a 1 GB persistent volume, expect roughly $10-15/month. Fly.io bills by the second, so you only pay for actual uptime. The included free allowance covers a small portion of compute each month.

Can I make my OpenClaw instance private so only I can access it?

Yes. Remove the public IPv4 and IPv6 addresses with 'fly ips release' and access the app through 'fly proxy 18789:3000' which creates a WireGuard tunnel to your private Fly network. This means no one on the internet can reach your instance.

How do I update OpenClaw on Fly.io?

Pull the latest source with 'git pull', then run 'fly deploy'. Fly.io builds the new image, performs a rolling deployment, and routes traffic to the new instance once healthy. Your persistent volume data is preserved across deployments.

What happens to my data if the Fly.io machine restarts?

Data stored on the persistent volume at /data survives machine restarts, redeployments, and even scaling events. The volume is attached to the machine and persists independently of the container lifecycle. Only explicitly deleting the volume removes the data.

Can I deploy OpenClaw to a specific region on Fly.io?

Yes. Set the primary_region in fly.toml to any Fly.io region code (e.g., 'lhr' for London, 'nrt' for Tokyo, 'iad' for Virginia). For the best experience, choose a region close to where you will be accessing OpenClaw from.

SuperBuilder

Prefer a managed experience?

SuperBuilder runs OpenClaw with zero setup — cloud execution, cost tracking, and team collaboration built in.

Try SuperBuilder Free