Local deployment
The development compose file runs supporting services only. Nuxt stays on the host for hot module replacement and listens on port 3000.
Service profiles
| Command | Services | Use for |
|---|---|---|
pnpm services:up | Postgres | PostgreSQL connectors |
pnpm services:up:whatsapp | Postgres, Redis, Evolution | WhatsApp connectors |
pnpm services:up:telegram | Postgres, Telegram bridge | Telegram connectors |
pnpm services:down | All enabled profiles | Routine shutdown |
pnpm services:logs | All enabled profiles | Combined service logs |
pnpm services:ps | All enabled profiles | Service status |
After bringing up services, run pnpm dev on the host.
This stack is for development: Nuxt runs on the host and the images are not used. To run Automata on a server without building anything, use Docker Compose.
One Postgres, three schemas
| Schema | Owner | Holds |
|---|---|---|
app | Web | Users, sessions, organizations, connections, invitations, token hashes |
public | Evolution | WhatsApp instances, chats, and messages |
telegram | Telegram bridge | Encrypted sessions and synced chats |
The web app applies its migrations at startup under an advisory lock. To start over locally, drop the schema; the next boot recreates it:
psql postgres://evolution:change-me@localhost:5432/evolution -c 'DROP SCHEMA app CASCADE'
Local topology
| From | To | Address |
|---|---|---|
| Nuxt | Postgres (app and messages) | localhost:5432 |
| Nuxt | Evolution | http://localhost:8080 |
| Nuxt | Telegram bridge | http://localhost:8095 |
| Evolution | Nuxt webhook | http://host.docker.internal:3000/api/webhook/evolution |
| Telegram bridge | Nuxt webhook | http://host.docker.internal:3000/api/webhook/telegram |
Ports and webhooks
Postgres 5432, Redis 6379, Evolution 8080, and the Telegram bridge 8095 bind to loopback in the development compose file. Nuxt listens on 0.0.0.0 so containers can reach its webhook.
Set WEBHOOK_URL and NUXT_WEBHOOK_URL to the same Evolution callback. Set NUXT_WEBHOOK_SECRET so per-instance webhook requests carry and verify x-webhook-secret.
Testing mail locally
Run a mail catcher and point NUXT_SMTP_HOST at it:
docker run -d --name wamcp-mailpit -p 1025:1025 -p 8025:8025 axllent/mailpit:v1.21
# .env: NUXT_SMTP_HOST=localhost, NUXT_SMTP_PORT=1025, NUXT_MAIL_FROM=alerts@automata.test
Read sent mail at http://localhost:8025. See Connection alerts for how detection works. Trigger the alert sweep by hand with curl -X POST http://localhost:3000/_nitro/tasks/alerts:sweep.
Linux firewall
On Linux with ufw, container-to-host webhook traffic enters the host input chain and may time out. The compose subnet is pinned so it can be narrowly allowed:
sudo ufw allow from 172.31.250.0/24 to 172.17.0.1 \
port 3000 proto tcp comment 'automata webhooks'
Verify from the Evolution container:
docker compose -f docker-compose.dev.yml exec evolution \
wget -T 5 -qO- --post-data='{"event":"ping"}' \
--header='content-type: application/json' \
http://host.docker.internal:3000/api/webhook/evolution
A response of {"ok":true} confirms the path. A timeout usually means the firewall rule or subnet is wrong.
On an untrusted network, binding Nuxt to 0.0.0.0 can expose port 3000 if the host firewall does not block LAN traffic.