Inline NATS config via docker-compose configs

Coolify's compose executor rewrites relative bind mounts to a persistent
app dir with no source file, causing docker to auto-create the mount
target as a directory and fail with "not a directory". Delivering the
config through configs.content instead avoids the rewrite entirely and
lets Docker Compose substitute NATS_USER/NATS_PASSWORD at parse time.
This commit is contained in:
2026-08-25 10:07:05 +00:00
parent f9a999d6bd
commit acd37942e9
3 changed files with 32 additions and 29 deletions
+4 -5
View File
@@ -94,7 +94,7 @@ asyncio.run(main())
- `8080` — WebSocket listener, `no_tls: true`. Traefik terminates TLS and forwards `ws://nats:8080` from the public `wss://nats.tes.gd`. - `8080` — WebSocket listener, `no_tls: true`. Traefik terminates TLS and forwards `ws://nats:8080` from the public `wss://nats.tes.gd`.
- `8222` — HTTP monitoring (`/healthz`, `/varz`, `/jsz`), internal only. Used by the compose healthcheck. - `8222` — HTTP monitoring (`/healthz`, `/varz`, `/jsz`), internal only. Used by the compose healthcheck.
- **JetStream**: enabled, persisted to the named volume `nats-data` mounted at `/data`. Limits: 256MB memory / 4GB file. Bump `max_file_store` in `nats-server.conf` if you need more. - **JetStream**: enabled, persisted to the named volume `nats-data` mounted at `/data`. Limits: 256MB memory / 4GB file. Bump `max_file_store` in `nats-server.conf` if you need more.
- **Auth**: a single user, whose name and password come from the `NATS_USER` / `NATS_PASSWORD` env vars via NATS' native `$VAR` substitution in the config. No accounts, no operator/JWT mode. - **Auth**: a single user, whose name and password come from the `NATS_USER` / `NATS_PASSWORD` env vars. Substitution happens at Docker Compose parse time (the config lives inline in `docker-compose.yml` under `configs.nats-conf.content`), so NATS itself sees a static config. No accounts, no operator/JWT mode.
## Managing / redeploying ## Managing / redeploying
@@ -108,15 +108,14 @@ curl -sS -X POST "$COOLIFY_URL/api/v1/deploy?uuid=$APP_UUID" \
# → { "deployments": [ { "deployment_uuid": "…" } ] } done, don't poll # → { "deployments": [ { "deployment_uuid": "…" } ] } done, don't poll
``` ```
Rotating the password: PATCH the `NATS_PASSWORD` env on the Coolify app, then redeploy. Do not edit `nats-server.conf` — auth is env-driven. Rotating the password: PATCH the `NATS_PASSWORD` env on the Coolify app, then redeploy. The value is substituted into `configs.nats-conf.content` at compose parse time.
To add a second user (e.g. a scoped app account), edit the `authorization.users` array in `nats-server.conf`, wire the new credential env vars into `docker-compose.yml`, and set them in Coolify. To add a second user (e.g. a scoped app account), edit the `authorization.users` array in the `configs.nats-conf.content` block in `docker-compose.yml`, and set any new credential env vars in Coolify.
## Files in this repo ## Files in this repo
| File | Purpose | | File | Purpose |
|---|---| |---|---|
| `docker-compose.yml` | Single `nats` service, exposes 4222/8080/8222 internally; only 8080 is routed publicly via `SERVICE_FQDN_NATS_8080` + Coolify's `docker_compose_domains`. | | `docker-compose.yml` | Single `nats` service, exposes 4222/8080/8222 internally; only 8080 is routed publicly via `SERVICE_FQDN_NATS_8080` + Coolify's `docker_compose_domains`. The NATS config lives inline under `configs.nats-conf.content` (delivered to the container as `/etc/nats/nats-server.conf`) — no separate config file, no bind mount (Coolify's compose executor rewrites relative host paths into a persistent app dir and can't materialise a source file for them). |
| `nats-server.conf` | NATS config: JetStream, WebSocket listener (`no_tls`), env-driven auth. |
| `.gitignore` | Keeps `deploy.json` out of git. | | `.gitignore` | Keeps `deploy.json` out of git. |
| `deploy.json` (local only) | Coolify app config used by the `deploying-to-coolify-via-api` skill. | | `deploy.json` (local only) | Coolify app config used by the `deploying-to-coolify-via-api` skill. |
+28 -3
View File
@@ -5,10 +5,10 @@ services:
command: ["-c", "/etc/nats/nats-server.conf"] command: ["-c", "/etc/nats/nats-server.conf"]
environment: environment:
- SERVICE_FQDN_NATS_8080 - SERVICE_FQDN_NATS_8080
- NATS_USER=${NATS_USER} configs:
- NATS_PASSWORD=${NATS_PASSWORD} - source: nats-conf
target: /etc/nats/nats-server.conf
volumes: volumes:
- ./nats-server.conf:/etc/nats/nats-server.conf:ro
- nats-data:/data - nats-data:/data
expose: expose:
- "4222" - "4222"
@@ -20,5 +20,30 @@ services:
timeout: 5s timeout: 5s
retries: 3 retries: 3
configs:
nats-conf:
content: |
server_name: "nats-volcanic"
port: 4222
http_port: 8222
jetstream {
store_dir: "/data"
max_memory_store: 256MB
max_file_store: 4GB
}
websocket {
port: 8080
no_tls: true
}
authorization {
users = [
{ user: "${NATS_USER}", password: "${NATS_PASSWORD}" }
]
}
volumes: volumes:
nats-data: nats-data:
-21
View File
@@ -1,21 +0,0 @@
server_name: "nats-volcanic"
port: 4222
http_port: 8222
jetstream {
store_dir: "/data"
max_memory_store: 256MB
max_file_store: 4GB
}
websocket {
port: 8080
no_tls: true
}
authorization {
users = [
{ user: $NATS_USER, password: $NATS_PASSWORD }
]
}