"Boring env files lead to boring deployments. If your .env differs between servers, you already have drift."

Required variables (start here)

These must be present for OpenClaw to start. Use this as a baseline template:

# Listen on localhost only; reverse proxy will expose publicly
GATEWAY_LISTEN=127.0.0.1:8080
APP_PORT=8080

# Secrets — generate strong random values
JWT_SECRET=$(openssl rand -hex 32)
SESSION_SECRET=$(openssl rand -hex 32)

# Database (example SQLite for small deployments)
DATABASE_URL=sqlite:/var/lib/openclaw/openclaw.db
# For Postgres: DATABASE_URL=postgresql://user:pass@localhost:5432/openclaw

# Logging
LOG_LEVEL=info
LOG_FILE=/var/log/openclaw/openclaw.log

# Optional: Admin credentials if using auth
ADMIN_USER=admin
ADMIN_PASSWORD=change-me-immediately

# Optional: S3-compatible storage for uploads
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_BUCKET=my-openclaw-uploads
S3_ACCESS_KEY=...
S3_SECRET_KEY=...

# Optional: SMTP for notifications
SMTP_HOST=smtp.example.com
SMTP_PORT=587
[email protected]
SMTP_PASS=...

Networking & exposure

Bind to localhost

Never bind OpenClaw directly to 0.0.0.0 in production. Keep it local and use a reverse proxy (nginx, Caddy) to handle TLS and public exposure.

# Correct
GATEWAY_LISTEN=127.0.0.1:8080

# Avoid in production
# GATEWAY_LISTEN=0.0.0.0:8080

Ports

Pick a port that's not already used. 8080, 3000, and 4567 are common defaults. Avoid 80/443 on the gateway; let the proxy handle those.

Security settings

JWT and session secrets

These must be cryptographically random and at least 32 bytes. Never reuse them across environments. Use openssl rand -hex 32 to generate.

JWT_SECRET=$(openssl rand -hex 32)
SESSION_SECRET=$(openssl rand -hex 32)

Admin credentials

If the ADMIN_USER/ADMIN_PASSWORD variables are set, change the password immediately from the default. Consider using an external auth provider instead.

Rate limiting (if available)

Some OpenClaw builds support rate limiting. Enable it if you're internet-facing:

RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX=100 per IP per minute

Database & storage

SQLite vs Postgres

SQLite is fine for single-node, low-to-moderate write workloads. If you anticipate higher concurrency or want easier backups, use Postgres.

# SQLite
DATABASE_URL=sqlite:/var/lib/openclaw/openclaw.db

# Postgres
DATABASE_URL=postgresql://openclaw:strongpass@localhost:5432/openclaw

Storage for uploads

For anything beyond trivial uploads, use S3-compatible storage. Configure:

S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_BUCKET=my-openclaw-uploads
S3_REGION=us-east-1
S3_ACCESS_KEY=AKIA...
S3_SECRET_KEY=...
S3_PATH_STYLE=true  # if using non-AWS S3-compatible service

External integrations

Any webhook or external service (SMTP, Slack, webhook endpoints) needs its own credentials here. Keep them out of version control by using a template and real values only on the server.

SMTP_HOST=smtp.example.com
SMTP_PORT=587
[email protected]
SMTP_PASS=...

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...

Verify before you start

Before you systemctl start openclaw, source the env file to catch syntax errors and check required variables:

# Quick syntax check
set -a
source .env
set +a
echo "Env loaded OK"

Also verify types:

# Confirm numeric ports
echo "APP_PORT=$APP_PORT"
# Confirm required secrets are present and long enough
[ ${#JWT_SECRET} -ge 32 ] || { echo "JWT_SECRET too short"; exit 1; }
[ ${#SESSION_SECRET} -ge 32 ] || { echo "SESSION_SECRET too short"; exit 1; }

Common pitfalls

  • Different .env across servers — dev has A, prod has B. Keep a .env.example with the same keys, different placeholder values. Treat that as your schema.
  • Committing secrets.env must be in .gitignore. If you accidentally commit, rotate the secrets and scrub from git history.
  • Missing APP_PORT — OpenClaw might default to an unexpected port. Always set explicitly.
  • Binding to 0.0.0.0 — exposes gateway directly. Use a reverse proxy and bind to 127.0.0.1.
  • Copy-pasting old values — never reuse JWT_SECRET from another project. Generate fresh.
  • File permission mistakes.env should be 600 (read/write owner only).

Next practical step

Take your current OpenClaw server and extract its .env into a git-ignored file. Compare against the checklist above. Fill any gaps, fix permissions (chmod 600 .env), and reload. If your gateway is behind a reverse proxy, ensure GATEWAY_LISTEN=127.0.0.1:8080 and that the proxy forwards to that port.

Need a reliable VPS to practice this? Hostinger's plans give you full root access to set up OpenClaw correctly.