CourseWhatsApp Automation for Business
ModulePayments and production
Duration12 min
Progress0/7
Course material0/7 · 0%
  1. 1What we are building, and the project setup8 min
  2. 2Connecting to the WhatsApp Cloud API12 min
  3. 3Sessions and the order flow state machine12 min
  4. 4The mini CRM: contacts, orders, and labels10 min
  5. 5Payments in chat with the Midtrans sandbox12 min
  6. 6Hardening: dedupe, retries, and human takeover10 min
  7. 7Deploying with Docker, off the laptop for good12 min

Lesson 7 / 7 · 12 min

Deploying with Docker, off the laptop for good

Dockerfile, a server, HTTPS with Caddy, and the production checklist. Checkpoint: the bot answers while your laptop is off.

ngrok dies with your laptop. Production means a small server (any VPS with 1 GB RAM is plenty for this bot), your code in a container, and a real HTTPS domain that Meta and Midtrans can call day and night.

Step 1: the Dockerfile

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
CMD ["node", "server.js"]
If better-sqlite3 fails to install on the slim image, switch the first line to FROM node:20 (the full image ships the build tools).

Step 2: build and run on the server

# .dockerignore first: node_modules, data, .env
docker build -t wa-bot .

docker run -d --name wa-bot \
  --restart unless-stopped \
  --env-file .env \
  -p 127.0.0.1:3000:3000 \
  -v "$(pwd)/data:/app/data" \
  wa-bot

docker logs -f wa-bot   # watch it boot
--restart survives reboots; the volume keeps bot.db outside the container so deploys never lose data; binding to 127.0.0.1 hides the port from the public internet.

Step 3: HTTPS with Caddy

# /etc/caddy/Caddyfile  (point bot.yourdomain.com's DNS at the server)
bot.yourdomain.com {
  reverse_proxy localhost:3000
}
Caddy obtains and renews the TLS certificate automatically. Two lines buy you production HTTPS.

Step 4: repoint the webhooks

In the Meta console change the callback URL to https://bot.yourdomain.com/webhook and re-verify; in Midtrans set the notification URL to /payment/notify on the same domain. Send a test message and a sandbox payment to prove both paths reach the server.

The going-live checklist

  • Replace the temporary Meta token with a permanent system-user token, and store it only in .env on the server.
  • To message any customer (beyond 5 test recipients), complete business verification and register a real number in the Meta console.
  • Switch Midtrans from sandbox to production keys and domain when you are ready for real money.
  • Back up data/bot.db daily (a cron job copying the file is enough at this scale).
  • Point an uptime monitor at the server so you learn about downtime before customers do.

Final checkpoint: turn your laptop off, message the bot, complete a sandbox order and payment. If the confirmation arrives, you have built and shipped a production WhatsApp commerce system, the same architecture our team operates for clients, just smaller.

What you take away

  • A 1 GB VPS, one container, and Caddy give you real production hosting
  • The data volume and --restart flag protect the database and uptime
  • Repoint Meta and Midtrans webhooks to the HTTPS domain and re-verify
  • Permanent token, business verification, backups, and an uptime monitor complete go-live
Want this built and operated for you?Our AI CRM is exactly this system, run as a service.
Deploying with Docker, off the laptop for good - WhatsApp Automation for Business | Etzal Academy | Etzal Group