"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.examplewith the same keys, different placeholder values. Treat that as your schema. - Committing secrets —
.envmust 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 —
.envshould 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.