WAMR Deployment Guide
Walks through Docker-based production deployment of a combined frontend/backend container, including security setup, environment configuration, and backup procedures.
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
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:
- Create your admin account (username and password)
- Save your 5 backup codes for account recovery
- Access the dashboard
Note: If you pre-configure
ADMIN_USERNAMEandADMIN_PASSWORDin.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 withDATA_PATH)./.baileys_auth/- WhatsApp session data (customize withBAILEYS_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:
| Variable | Default | Description |
|---|---|---|
HOST_PORT | 9002 | Host port to expose the application |
NODE_ENV | production | Node environment |
PORT | 9000 | Container internal port |
DATABASE_PATH | /app/data/wamr.db | Database 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_auth | WhatsApp session path |
RATE_LIMIT_WINDOW_MS | 900000 | Rate limit window (15 min) |
RATE_LIMIT_MAX_REQUESTS | 100 | Max requests per window |
LOGIN_RATE_LIMIT_MAX | 5 | Max login attempts |
MEDIA_MONITORING_INTERVAL_MS | 300000 | Monitoring interval (5 min) |
LOG_LEVEL | info | Logging level |
LOG_PRETTY | false | Pretty print logs |
DATA_PATH | ./data | Host path for database |
BAILEYS_PATH | ./.baileys_auth | Host 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 proxyenabled 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 databasewamr-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=falsefor 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
-
Reverse Proxy: Use nginx or Caddy for:
- HTTPS/SSL termination
- Domain routing
- Load balancing (if scaling)
-
Monitoring: Set up monitoring for:
- Container health
- Resource usage (CPU, memory)
- API response times
- Error rates
-
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'" -
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/wamrwith your own Docker image or repository - Replace
wamr-combinedwith your container name if different - Replace
wamr.yourdomain.comwith 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 randinline in the env file avoids hardcoded defaults - Providing both a quick-start default and a customizable
.env.prodpath lets users choose their risk level
Related Documents
OpenCode Agents
Provides a collection of specialised Markdown agent files for OpenCode, each with a distinct role and thinking algorithm.
🌟 GitHub MCP Server - Feature Showcase
Showcases eight GitHub MCP server tools with example inputs, outputs, and real-world use cases for AI agents.
Chloe 部署文档
Guides you through deploying an enhanced SillyTavern fork with direct, Docker, and reverse-proxy setups, plus security hardening and troubleshooting.
Software License Compliance Report
Documents that all dependencies in an early cancer prediction project are FOSS and OSI-approved, confirming commercial use is permitted.