Back to .md Directory

WAMR Deployment Guide

Walks through Docker-based production deployment of a combined frontend/backend container, including security setup, environment configuration, and backup procedures.

May 2, 2026
0 downloads
2 views
ai rag
View source

What this file does

Walks through Docker-based production deployment of a combined frontend/backend container, including security setup, environment configuration, and backup procedures.

When to use it

  • Deploying WAMR to a production server with Docker
  • Setting up HTTPS via reverse proxy for WAMR
  • Automating backups of WAMR's SQLite database and WhatsApp session
  • Troubleshooting port conflicts or database issues in WAMR

Assumes this stack

DockerDocker ComposeNode.jsSQLiteWhatsApp Web (Baileys)

WAMR Deployment Guide

This guide covers production deployment using Docker and development using Turborepo.

Prerequisites

  • Node.js >= 20.0.0
  • npm >= 10.0.0
  • Docker & Docker Compose (for production)

Quick Start (Development)

For development setup, see the main README.md.

For environment variable details, see ENVIRONMENT.md.

Production Deployment (Docker)

WAMR uses a single combined container that serves both frontend and backend for simplified deployment.

Using docker-compose.prod.yml

This is the recommended method for production deployments with data stored in the current directory.

Quick Start (Using Defaults):

# Pull and start with default settings
docker compose -f docker-compose.prod.yml up -d

# Access: http://localhost:9002
# Complete the setup wizard to create your admin account

⚠️ For production, you MUST customize the security settings!

1. Customize Environment Variables (Recommended for Production)

Create a .env.prod file to override defaults:

# Copy example file
cp .env.example .env.prod

Edit .env.prod with your custom values:

# Host port mapping (default: 9002)
HOST_PORT=9002

# Security - REQUIRED! Change these values for production!
JWT_SECRET=$(openssl rand -base64 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)

# Optional: Pre-configure admin credentials (skips setup wizard)
# ADMIN_USERNAME=admin
# ADMIN_PASSWORD=your-secure-password

# Optional: Customize paths
DATA_PATH=./data
BAILEYS_PATH=./.baileys_auth

# Optional: Adjust settings (these have sensible defaults)
# NODE_ENV=production
# PORT=9000
# CORS_ORIGIN=*
# RATE_LIMIT_WINDOW_MS=900000
# RATE_LIMIT_MAX_REQUESTS=100
# LOGIN_RATE_LIMIT_MAX=5
# MEDIA_MONITORING_INTERVAL_MS=300000
# LOG_LEVEL=info
# LOG_PRETTY=false

2. Run the Container

# Pull the latest image and start
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

# View logs
docker compose -f docker-compose.prod.yml logs -f

# Stop the container
docker compose -f docker-compose.prod.yml down

3. Access the Application

  • Local network (HTTP): http://YOUR_SERVER_IP:9002 (or your custom HOST_PORT)
  • Localhost: http://localhost:9002
  • Via reverse proxy (HTTPS): https://wamr.yourdomain.com

4. First-Time Setup

On first access, you'll be guided through a setup wizard:

  1. Create your admin account (username and password)
  2. Save your 5 backup codes for account recovery
  3. Access the dashboard

Note: If you pre-configure ADMIN_USERNAME and ADMIN_PASSWORD in .env.prod, the setup wizard will be skipped and the admin user will be created automatically.

5. Backup Codes

After setup, you'll receive 5 backup codes. These are single-use codes that can be used to reset your password if you get locked out. You can view and regenerate backup codes in Settings > Backup Codes.

5. Data Storage

Data is stored in the current directory (customizable via .env.prod):

  • ./data/ - SQLite database (customize with DATA_PATH)
  • ./.baileys_auth/ - WhatsApp session data (customize with BAILEYS_PATH)

These folders will be created automatically if they don't exist.

Environment Variable Reference

The docker-compose.prod.yml file uses environment variables with sensible defaults. You can override any of these by creating a .env.prod file:

VariableDefaultDescription
HOST_PORT9002Host port to expose the application
NODE_ENVproductionNode environment
PORT9000Container internal port
DATABASE_PATH/app/data/wamr.dbDatabase path inside container
JWT_SECRET(default provided)⚠️ Change for production!
ENCRYPTION_KEY(default provided)⚠️ Change for production!
ADMIN_USERNAME(optional)Pre-configure admin (skips setup wizard)
ADMIN_PASSWORD(optional)Pre-configure admin password
CORS_ORIGIN*Allowed CORS origins
WHATSAPP_SESSION_PATH/app/.baileys_authWhatsApp session path
RATE_LIMIT_WINDOW_MS900000Rate limit window (15 min)
RATE_LIMIT_MAX_REQUESTS100Max requests per window
LOGIN_RATE_LIMIT_MAX5Max login attempts
MEDIA_MONITORING_INTERVAL_MS300000Monitoring interval (5 min)
LOG_LEVELinfoLogging level
LOG_PRETTYfalsePretty print logs
DATA_PATH./dataHost path for database
BAILEYS_PATH./.baileys_authHost path for WhatsApp session

Build from Source

If you want to build the image yourself:

# Clone the repository
git clone https://github.com/techieanant/wamr.git
cd wamr

# Setup environment
cp .env.example .env.prod
# Edit .env.prod with your settings

# Build and run
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d

Network Access Configuration

WAMR can work on both local network (HTTP) and reverse proxy (HTTPS) simultaneously:

For Local Network Access:

  • Set CORS_ORIGIN=* in environment variables
  • Access via http://YOUR_SERVER_IP:9002

For Reverse Proxy (HTTPS) Access:

  • Set CORS_ORIGIN=* or specify your domain: CORS_ORIGIN=https://wamr.yourdomain.com
  • Configure your reverse proxy (Nginx Proxy Manager, Caddy, Traefik) to forward to port 9002
  • The backend has trust proxy enabled to handle X-Forwarded-Proto headers

Both at the same time:

  • Use CORS_ORIGIN=* to allow access from any origin
  • Access locally via HTTP and remotely via HTTPS reverse proxy

Alternative Deployment (Using docker-compose.yml)

If you prefer using the legacy method with docker-compose.yml and a single .env file:

1. Setup Environment Variables

cp .env.example .env

Edit .env and configure:

# Port for the application (default: 4000)
PORT=9000

# Security - REQUIRED! Change these values!
JWT_SECRET=$(openssl rand -base64 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
ADMIN_PASSWORD=your-secure-password

# Optional settings
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
LOGIN_RATE_LIMIT_MAX=5
MEDIA_MONITORING_INTERVAL_MS=300000
LOG_LEVEL=info
LOG_PRETTY=false

Important: No need to configure VITE_API_URL - the frontend uses relative paths (/api) since it's served from the same origin. Configure CORS_ORIGIN=* if accessing via reverse proxy or local network.

2. Build and Run

# Build the Docker image
npm run docker:build

# Start the container (uses docker-compose.yml)
npm run docker:up

# View logs
npm run docker:logs

# Stop the container
npm run docker:down

3. Access the Application

Everything is available on a single port (default 4000, or your configured PORT):

  • Application: http://192.168.1.12:9000 (or your configured PORT)
  • API: http://192.168.1.12:9000/api
  • Health Check: http://192.168.1.12:9000/health

4. Persistent Data

Docker volumes are automatically created for:

  • wamr-data: SQLite database
  • wamr-whatsapp-auth: WhatsApp session data

Benefits of Combined Container

  • ✅ Simpler deployment (one container serving everything)
  • ✅ Smaller resource footprint
  • ✅ Single port to expose
  • ✅ Real-time WebSocket updates work seamlessly
  • ✅ Faster build times with optimized Dockerfile

Configuration Reference

📖 For complete environment variable documentation, see ENVIRONMENT.md.

📖 For development setup and commands, see README.md.

Generate Security Keys:

openssl rand -base64 32  # JWT_SECRET
openssl rand -hex 32     # ENCRYPTION_KEY

Health Checks

The application exposes a health check endpoint:

  • Health: GET /health

Docker Compose automatically monitors this endpoint every 30 seconds.

Backup and Restore

Backup

Export data via the Settings page in the UI, or:

# Copy database
docker cp wamr-combined:/app/data/wamr.db ./backup-$(date +%Y%m%d).db

# Copy WhatsApp session
docker cp wamr-combined:/app/.baileys_auth ./whatsapp-backup-$(date +%Y%m%d)

Restore

# Restore database
docker cp ./backup.db wamr-combined:/app/data/wamr.db

# Restore WhatsApp session
docker cp ./whatsapp-backup wamr-combined:/app/.baileys_auth
docker-compose restart

Troubleshooting

Port Conflicts

If the default port is in use:

# Edit .env
PORT=8080  # Change to any available port

Then rebuild and restart:

npm run docker:down
npm run docker:build
npm run docker:up

Database Issues

Reset database:

docker-compose down
docker volume rm wamr_wamr-data
docker-compose up -d

WhatsApp Connection Issues

Reset WhatsApp session:

docker-compose down
docker volume rm wamr_wamr-whatsapp-auth
docker-compose up -d
# Scan new QR code

View Logs

# View container logs
npm run docker:logs

# Or use docker directly
docker logs -f wamr-combined

Security Checklist

Before deploying to production:

  • Generate and set JWT_SECRET (use: openssl rand -base64 32)
  • Generate and set ENCRYPTION_KEY (use: openssl rand -hex 32)
  • Complete setup wizard and save backup codes securely
  • Enable HTTPS (use reverse proxy like nginx/Caddy/Traefik)
  • Set LOG_PRETTY=false for production
  • Review and adjust rate limits for your use case
  • Configure firewall rules (only expose necessary ports)
  • Set up automated database backups
  • Keep Docker images updated regularly
  • Monitor container resources (CPU, memory, disk)

Production Recommendations

  1. Reverse Proxy: Use nginx or Caddy for:

    • HTTPS/SSL termination
    • Domain routing
    • Load balancing (if scaling)
  2. Monitoring: Set up monitoring for:

    • Container health
    • Resource usage (CPU, memory)
    • API response times
    • Error rates
  3. Backups: Automate database backups:

    # Cron job example (daily at 2 AM)
    0 2 * * * docker exec wamr-combined sqlite3 /app/data/wamr.db ".backup '/app/data/backup-$(date +\%Y\%m\%d).db'"
    
  4. Updates: Keep dependencies updated:

    npm audit
    docker-compose pull
    docker-compose up -d --build
    

Support

For issues and questions:

  • Check logs: docker-compose logs -f
  • Review environment variables
  • Ensure all required secrets are set
  • Verify Docker network connectivity

What's inside

14 sections covering prerequisites, two Docker deployment methods, environment variable reference, health checks, backup/restore, troubleshooting, and a security checklist.

Change this for your project

  • Replace techieanant/wamr with your own Docker image or repository
  • Replace wamr-combined with your container name if different
  • Replace wamr.yourdomain.com with your actual domain

Where it goes

Keep it in your repository where the agent or team that needs it will read it.

Worth borrowing

  • Using a single combined container for frontend and backend simplifies deployment and networking
  • Generating secrets with openssl rand inline in the env file avoids hardcoded defaults
  • Providing both a quick-start default and a customizable .env.prod path lets users choose their risk level

Related Documents