EchoTune now runs against Postgres for operational data. The legacy data.json file remains in the repo as a migration source and emergency snapshot reference, but the running app should use DATABASE_URL and Postgres-backed storage only.
docker compose up -d --build
Open http://localhost:22023.
- Create a snapshot backup from the current
data.json. - Provision Postgres and set
DATABASE_URL. - Run a dry run to confirm source counts.
- Run the data migration once during a short maintenance window.
npm run data:backup npm run db:migrate-data:dry-run npm run db:migrate-data
- Create or reuse a Docker Compose application in Dokploy.
- In the Dokploy service, use the
Gitprovider instead of the GitHub App provider. - Set repository URL to
git@github.com:akcrnd/echotune.git. - Select branch
main. - Set compose path to
./docker-compose.yml. - Select the Dokploy SSH key that has GitHub access.
- Enable Auto Deploy, or redeploy manually after each push.
Runtime services:
postgres: internal Postgres for application dataechotune: app service exposed on22023
Do not set fixed container_name values in this Compose file. Dokploy needs project-scoped container names so redeploys replace the right containers and logs/metrics stay attached to the selected Compose project.
The default deployment keeps app and database in the same Dokploy Compose app. The app connects to Postgres through Docker's internal service DNS:
DATABASE_URL=postgresql://postgres:EchotunePg2026@postgres:5432/echotune
Do not use the external Postgres port for normal app traffic. If host-side admin/debug access is needed, temporarily uncomment the Postgres ports block in docker-compose.yml.
After deployment, verify both the base health endpoint and a feature API. http://<host>:22023/api/health must return {"status":"ok","database":true}. The team competency API must return JSON, not the frontend HTML fallback:
ECHOTUNE_BASE_URL=http://<host>:22023 npm run deploy:verify-team-competency
If deploy:verify-team-competency reports non-JSON content for /api/team-competency/..., the app is still running an older container image even if /api/health is green.
PORT: app port inside the container, defaults to5000POSTGRES_DB: Postgres database name, defaults toechotunePOSTGRES_USER: Postgres user, defaults topostgresPOSTGRES_PASSWORD: Postgres passwordDATABASE_URL: required runtime Postgres connection stringDB_CONNECTION_TIMEOUT_MS: Postgres connection timeout, defaults to5000DB_QUERY_TIMEOUT_MS: Postgres query/statement timeout, defaults to15000DB_POOL_MAX: Postgres pool size, defaults to10
- Readiness endpoint:
/api/health - The app boot fails fast if Postgres is unavailable or schema bootstrap cannot complete.
- API requests fail instead of hanging indefinitely when Postgres cannot be reached.
- Postgres data persists in the Docker volume
echotune_postgres. - Dokploy deployment must be verified after every
mainpush. Do not treat GitHub push success as production deploy success. - If Dokploy auto deploy is not configured, use the Dokploy dashboard or API to redeploy the Compose app, then run
npm run deploy:verify-team-competencyagainst the production host.
- Pre-cutover snapshot:
npm run data:backup - Ongoing backup target: the Postgres volume, not
data.json - Recovery model: restore Postgres volume backup, redeploy app, verify
/api/health, then smoke-test key APIs
If data already exists in a separate Dokploy Postgres service, back it up before switching to this compose-managed Postgres volume:
pg_dump "postgresql://postgres:EchotunePg2026@192.168.3.17:22024/echotune" > echotune.sql
After the new compose stack starts, restore the dump into the internal postgres service before sending users to the app.