OpenWA Docker Setup — From Zero to First Login
OpenWA is an open-source WhatsApp API gateway built on NestJS and whatsapp-web.js. It gives you a REST API to send and receive messages, manage multiple WhatsApp sessions, configure webhooks, and control everything from a dashboard — without paying Meta for WhatsApp Business API access.
GitHub: github.com/rmyndharis/OpenWA
What You Need Before Starting
Clone and One Command
cd ~/projects
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
docker compose -f docker-compose.dev.yml up -d
That is it. No environment files to create, no flags to set. The dev compose has zero-config defaults for everything.
What it sets up:
One thing to add before you start — if you plan to connect OpenWA to n8n, append this to the bottom of docker-compose.dev.yml first:
networks:
default:
name: openwa-network
This makes both containers share a named Docker network so n8n can reach OpenWA at http://openwa-api:2785 by container name. If you skip this now, you will need to restart after adding it later.
The image is pre-built by GitHub Container Registry (ghcr.io/rmyndharis/openwa). If you prefer to build locally, the repo includes a Dockerfile.
Wait for It to Start
docker compose -f docker-compose.dev.yml logs -f
Look for:
OpenWA is running on http://localhost:2785
API: http://localhost:2785/api
Swagger Docs: http://localhost:2785/api/docs
This usually takes 10-20 seconds on first run (Chromium download on the first boot adds a delay).
Login to the Dashboard
Open: http://localhost:2785
The first-boot screen prompts for the admin API key. OpenWA stores this key in the Docker named volume — not in any file you edit manually.
Step 1 — Find the container name
docker ps --format '{{.Names}}'
Look for the OpenWA API container name (starts with openwa).
Step 2 — Read the API key
sudo docker exec cat /app/data/.api-key
For example, if the container is named openwa-api-1:
sudo docker exec openwa-api-1 cat /app/data/.api-key
This outputs a single line — that is your API key.
Step 3 — Paste it into the dashboard
Copy the key, paste it into the dashboard login field, and press Enter.
Store this key in a password manager. You need it for every API call, for wiring up n8n credentials, and for accessing the Swagger docs.
The Session State Machine
OpenWA sessions move through these states:
disconnected — Session exists but not startedconnecting — Chromium launching, WhatsApp Web loadingauthenticating — QR code displayed, waiting for phone scanready — Authenticated, can send and receiveIf a session gets stuck at "authenticating" and never reaches "ready": the WhatsApp Web version auto-selected by whatsapp-web.js is incompatible. Pin a known-good version in .env:
WWEBJS_WEB_VERSION=2.3000.1023204257
Known-good versions are listed at github.com/wppconnect-team/wa-version
Dev vs Production Compose
docker-compose.dev.yml is for local setup and first-time use. Everything is configured for zero friction.
docker-compose.yml is the production stack. Differences:
The production compose boots with:
docker compose --profile postgres up -d # PostgreSQL
docker compose --profile full up -d # All services
For production, also set API_MASTER_KEY in .env before first boot:
openssl rand -hex 32
What the Data Volume Contains
After first login, the Docker volume mounts contain:
openwa.sqlite — database (API keys, audit logs, session metadata)sessions/ — WhatsApp authentication state (auth.json, pre-keys)media/ — cached inbound and outbound media files.api-key — your master API keyplugins/ — community pluginsThe sessions/ directory is the most important. Losing it means rescanning QR codes for all sessions. See what's in the data volume and how to back it up.
Series: ← n8nctl management script | Next: OpenWA data volume backup →
Related Posts
Built something similar or want to talk through the architecture? Get in touch.