EchoHuman Twenty CRM
Twenty is an open-source CRM. EchoHuman's instance is a fully self-contained Docker Compose stack on VM700.
Public URL
Stack
/opt/stacks/echohuman-twenty/ on VM700 — 4 containers:
| Container | Role |
|---|---|
echohuman-twenty-server-1 | Web server + API (7010→3000) |
echohuman-twenty-worker-1 | Background jobs |
echohuman-twenty-db-1 | Local Postgres 16 |
echohuman-twenty-redis-1 | Redis |
First-Boot Time
~25–35 minutes. The entrypoint runs DB init, migrations, cache flush, upgrade, cron registration before binding port 3000. Container shows unhealthy throughout — this is normal.
Key Config
/opt/stacks/echohuman-twenty/.env:
PG_DATABASE_URL=postgres://twenty:<pass>@db:5432/default
REDIS_URL=redis://redis:6379
SERVER_URL=https://crm.echohuman.org
APP_SECRET=<base64-44-chars>
STORAGE_TYPE=local
Use env_file: .env in compose — never ${APP_SECRET} interpolation.
Known Blockers (resolved)
APP_SECRETempty — shell env overrides${VAR}interpolation. Fixed withenv_file:.- Empty
coreschema loop — partial migration left 0 tables. Fixed withDROP SCHEMA core CASCADEthen restart. - CT320 connection — EchoHuman must use its own local DB, not CT320.
Operations
# Status
docker ps --filter name=echohuman-twenty
# Watch startup
docker logs echohuman-twenty-server-1 -f 2>&1 | grep -E '\[Nest\]|ERROR'
# Check migration (expect 61 tables)
docker exec echohuman-twenty-db-1 psql -U twenty -d default \
-c 'SELECT count(*) FROM information_schema.tables WHERE table_schema=chr(99)||chr(111)||chr(114)||chr(101);'