PouchDB-style apps call fetch with credentials: 'include' to maintain the CouchDB _session cookie. Without Access-Control-Allow-Credentials: true in the preflight response, the browser silently blocks the mutating request (Firefox HAR shows status 0, _securityState insecure). Switching cors/credentials to true forces enumerating allowed origins (wildcard + credentials is forbidden by the CORS spec). Listed are the common Vite/Next/etc. local dev ports plus the vaquant.at frontend.
2.8 KiB
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
credentials = true with an explicit origin list — required for PouchDB-style cookie sessions (POST /_session). Wildcard origin is incompatible with credentials per the CORS spec, so allowed origins must be enumerated.
Update the put_config cors origins line in docker-compose.yml (comma-separated, no spaces) and redeploy when you add a new frontend. Or apply live:
curl -fsS -X PUT -u admin:$PASS \
-H "Content-Type: application/json" \
https://couch.apoena.dev/_node/_local/_config/cors/origins \
-d '"http://localhost:8080,https://new-frontend.example.com"'
Hardcoded values (cloning to another Coolify resource)
Two strings in docker-compose.yml are pinned to this specific Coolify deployment and must be updated if you redeploy as a new resource:
- The host in
traefik.http.routers.coolcouch.rule=Host(couch.apoena.dev) - The per-resource Coolify network name, appearing twice:
traefik.docker.network=lvw8efvnvsxduodrkg68zul3andnetworks.coolify.name: lvw8efvnvsxduodrkg68zul3
They're hardcoded because Coolify does not interpolate ${...} inside the labels: block (it does inside environment: and networks.<name>.name:). The network UUID matches COOLIFY_RESOURCE_UUID for the resource — find it in Coolify's UI or in docker network ls after first deploy.
A sed swap before push, or a Coolify "Custom Build Command" running sed -i over the file, is the simplest way to keep this template portable.
Files
docker-compose.yml— services, volume, Traefik labels, init sidecar