Deployment
Production, updates, and recovery
Production checklist
- Change all secrets in
.env(JWT, CSRF, passwords, PyOrch keys) - Set strong
ADMIN_PASSWORDandMQTT_PASSWORDforsystem(before CRM configuration) - Configure
CORS_ORIGINfor real domains - Restrict ports 80, 3001, 8080 (and 8000, 8090, 8010 with PyOrch) with firewall
- Do not publish MongoDB and Mosquitto unless necessary
- Configure
BACKUP_CRONand verify restore
Startup
./scripts/start.sh
The script attaches overlays: Redis, external MQTT, PyOrchestrator — based on .env variables.
Updates
Dynamic API Platform (vendored v1.5.13)
./scripts/update-dynamic-api.sh
docker compose up -d --build dynamic-api dynamic-api-panel
./scripts/run-init-seed.sh # if CRM schema changed
In-app updater in panel
:8080is disabled in WASH (UPDATE_EXECUTOR_ENABLED=false). Use the update script.
PyOrchestrator (vendored v0.1.10, optional)
./scripts/update-pyorchestrator.sh
docker compose -f docker-compose.yml -f docker-compose.pyorchestrator.yml up -d --build pyorch-backend pyorchestrator-panel pyorch-bridge
Dashboard and bridge
docker compose up -d --build dashboard pyorch-bridge
Full stack
docker compose up -d --build
# or with PyOrch:
PYORCHESTRATOR_ENABLED=true ./scripts/start.sh
Data is stored on the host disk in DATA_DIR (default ./data), not in Docker volumes. Image rebuild and docker compose down do not delete this directory. Details: data/README.md.
One-time migration from old named volumes:
./scripts/migrate-volumes-to-data.sh
./scripts/start.sh
Restore from backup
./scripts/restore.sh wash-pro-crm-2024-06-22T02-00-00.archive.gz
Or Dashboard → Backups.
GitHub Pages
- Settings → Pages → GitHub Actions
docs/_config.yml:urlandbaseurl- Push to
main→ workflow.github/workflows/pages.yml
Reverse proxy (TLS)
Example for Dashboard:
server {
listen 443 ssl;
server_name crm.example.com;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Separate blocks for :3001, :8080, :8090 if needed.
Monitoring
docker compose ps
docker logs -f wash-dynamic-api
docker logs -f wash-message-processor
docker logs -f wash-pyorch-bridge # if PyOrch
curl -s http://localhost:3001/api/health | jq
curl -s http://localhost/api/telegram-bots/health | jq # via Dashboard nginx
PyOrchestrator observability: PYORCH_OBSERVABILITY_ENABLED=true → Grafana :3000, Prometheus :9090.
Telemetry component updates
After changes in message-processor or Dashboard proxy:
docker compose up -d --build message-processor dashboard
Post control HTTP API check (JWT required):
curl -s -o /dev/null -w '%{http_code}\n' \
-H "Authorization: Bearer TOKEN" \
http://localhost/api/crm/post-device/posts/SERIAL/command
# 404 without body — normal; 401 — no token; 400/500 — see response body