A step-by-step guide: how to install ERPNext v16 on the prod server with Websocket fixed

ERPNext v16 Production Install (Docker + Traefik + WebSocket Fix)

Domain: YOUR_WEBSITE_ADDRESS. e.g. erpnext.yourcompanycom
Stack: ERPNext v16 + Docker + Traefik + MariaDB (shared)
Based on: [Tutorial][Docker] Installing ERPNext-16 on Docker: A Step-by-Step Guide [Production] - #6 by Antony_Praveenkumar

This guide includes the websocket launch and critical WebSocket fix for:
Unauthorized: TypeError: fetch failed and probably other problems


0. Requirements

  • Ubuntu/Debian server
  • Docker + Docker Compose installed
  • Public DNS: YOUR_WEBSITE_ADDRESS β†’ YOUR_SERVER_IP
  • Open ports: 22, 80, 443

1. Clone frappe_docker

git clone https://github.com/frappe/frappe_docker
cd frappe_docker
mkdir -p ~/gitops

2. Traefik (HTTPS + Let’s Encrypt)

Create environment file:

cat > ~/gitops/traefik.env <<EOF
TRAEFIK_DOMAIN=traefik.YOUR_WEBSITE_ADDRESS
EMAIL=admin@YOUR_WEBSITE_ADDRESS
HASHED_PASSWORD=$(openssl passwd -apr1 'CHANGE_THIS_PASSWORD' | sed 's/\$/\\\$/g')
EOF

Start Traefik:

docker compose --project-name traefik   --env-file ~/gitops/traefik.env   -f overrides/compose.traefik.yaml   -f overrides/compose.traefik-ssl.yaml up -d

3. MariaDB (shared)

echo "DB_PASSWORD=CHANGE_DB_ROOT_PASSWORD" > ~/gitops/mariadb.env

docker compose --project-name mariadb   --env-file ~/gitops/mariadb.env   -f overrides/compose.mariadb-shared.yaml up -d

4. ERPNext Environment

cp example.env ~/gitops/erpnext-one.env

Edit values:

sed -i 's/DB_PASSWORD=123/DB_PASSWORD=CHANGE_DB_ROOT_PASSWORD/g' ~/gitops/erpnext-one.env
sed -i 's/DB_HOST=/DB_HOST=mariadb-database/g' ~/gitops/erpnext-one.env
sed -i 's/DB_PORT=/DB_PORT=3306/g' ~/gitops/erpnext-one.env

sed -i 's/SITES_RULE=Host(`erp.example.com`)/SITES_RULE=Host(`YOUR_WEBSITE_ADDRESS`)/g' ~/gitops/erpnext-one.env
sed -i 's/NGINX_PROXY_HOSTS=erp.example.com/NGINX_PROXY_HOSTS=YOUR_WEBSITE_ADDRESS/g' ~/gitops/erpnext-one.env

echo 'ROUTER=erpnext-one' >> ~/gitops/erpnext-one.env
echo 'BENCH_NETWORK=erpnext-one' >> ~/gitops/erpnext-one.env

5. CRITICAL β€” Allow containers to reach host (host-gateway to reach websockets)

Create:

~/gitops/override.host-gateway.yaml

services:
  websocket:
    extra_hosts:
      - "YOUR_WEBSITE_ADDRESS:host-gateway"

  backend:
    extra_hosts:
      - "YOUR_WEBSITE_ADDRESS:host-gateway"

  frontend:
    extra_hosts:
      - "YOUR_WEBSITE_ADDRESS:host-gateway"

6. Generate Final Compose

docker compose --project-name erpnext-one   --env-file ~/gitops/erpnext-one.env   -f compose.yaml   -f overrides/compose.redis.yaml   -f overrides/compose.multi-bench.yaml   -f overrides/compose.multi-bench-ssl.yaml   -f ~/gitops/override.host-gateway.yaml   config > ~/gitops/erpnext-one.yaml

7. Start ERPNext

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml up -d

8. Create Site

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml exec backend   bench new-site YOUR_WEBSITE_ADDRESS   --mariadb-user-host-login-scope=%   --db-root-password CHANGE_DB_ROOT_PASSWORD   --admin-password CHANGE_ADMIN_PASSWORD

Install ERPNext app if needed:

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml exec backend   bench --site YOUR_WEBSITE_ADDRESS install-app erpnext

Enable scheduler:

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml exec backend   bench --site YOUR_WEBSITE_ADDRESS enable-scheduler

9. Configure WebSocket / Realtime

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml exec backend bash -lc '
bench --site YOUR_WEBSITE_ADDRESS set-config websocket_url "wss://YOUR_WEBSITE_ADDRESS";
bench --site YOUR_WEBSITE_ADDRESS set-config socketio_origin "https://YOUR_WEBSITE_ADDRESS";
bench --site YOUR_WEBSITE_ADDRESS set-config host_name "https://YOUR_WEBSITE_ADDRESS";
bench --site YOUR_WEBSITE_ADDRESS set-config allow_cors "https://YOUR_WEBSITE_ADDRESS";
'

Restart services:

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml restart websocket backend frontend

10. Verification

Test Socket.IO handshake:

curl -vk "https://YOUR_WEBSITE_ADDRESS/socket.io/?EIO=4&transport=polling"   -H "Origin: https://YOUR_WEBSITE_ADDRESS"

Expected: JSON response containing a sid.


Troubleshooting

WebSocket logs:

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml logs --tail=200 websocket

Test container β†’ site connectivity:

docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml exec websocket   curl -vk https://YOUR_WEBSITE_ADDRESS/api/method/ping

Installation Complete.

1 Like