Coolify is preventing variable interpolation in compose labels — the
container's labels were stored literally as Host(\`\${SERVICE_FQDN_COUCHDB_5984}\`)
etc., so Traefik matched no router and fell back to default_redirect_503.
Variable substitution works in environment: (CouchDB env was correct),
just not in labels: — likely Coolify sets labels via the Docker API
after compose runs, bypassing compose interpolation. Hardcoding the host
and the per-resource network name is the only thing left that works.
coolcouch
CouchDB 3 on Coolify. The couchdb-init sidecar waits for the server to come up, creates the three system databases, and enables CORS via the config API — no file mounts required.
Deploy
- In Coolify: New Resource → Docker Compose and point it at this repository.
- In the resource's Environment Variables tab, set:
COUCHDB_PASSWORD— requiredCOUCHDB_USER— optional, defaults toadmin
- In the resource's Domains tab, assign a domain to the
couchdbservice on port5984. Coolify fillsSERVICE_FQDN_COUCHDB_5984from this. - Deploy.
couchdb-initruns once, exits, and won't restart.
Verify
Replace $DOMAIN and $PASS:
curl -fsS https://$DOMAIN/_up
curl -fsS -u admin:$PASS https://$DOMAIN/
curl -fsS -u admin:$PASS https://$DOMAIN/_all_dbs
curl -fsS -I -X OPTIONS https://$DOMAIN/ \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: GET"
Expected: _up returns {"status":"ok",...}; / returns the CouchDB welcome JSON; _all_dbs returns ["_global_changes","_replicator","_users"]; the preflight returns 2xx with an Access-Control-Allow-Origin header.
If the init logs show CORS errors, you can re-trigger only that step by redeploying — the PUTs against /_node/_local/_config/... are idempotent.
CORS
Wildcard origin (*) with credentials = false — the only browser-spec-legal combination with a wildcard. For credentialed auth from the browser, edit the put_config cors origins/credentials lines in docker-compose.yml.
Files
docker-compose.yml— services, volume, Traefik labels, init sidecar