Summary
After a host reboot, the postiz container comes up but its backend (pm2 process on :3000) is dead, leaving nginx to 502 every /api call. The container's healthcheck correctly reports unhealthy, but nothing acts on it, so the app stays broken until someone manually restarts the container.
Root cause is not the package's compose file — it's that depends_on ordering is silently discarded on boot.
Observed
Seen on a Proxmox LXC host reboot (hola, 18 containers). Immediately after boot:
hola-postiz-4520f878-postiz-1 unhealthy fails=9
Backend logs:
2|backend | [ioredis] Unhandled error event: Error: getaddrinfo ENOTFOUND postiz-redis
2|backend | at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:122:26)
and nginx, continuously:
[error] connect() failed (111: Connection refused) while connecting to upstream,
upstream: "http://127.0.0.1:3000/auth/can-register"
Once things settled, redis was fine and DNS resolved — the failure was purely a startup race that the backend never recovered from:
ENOTFOUND count in last 3 min: 0
dns.lookup("postiz-redis") -> OK 172.28.0.2
redis-cli ping -> PONG
GET http://127.0.0.1:3000/ -> ECONNREFUSED <-- backend still dead
docker restart hola-postiz-4520f878-postiz-1 fixed it permanently: healthy, backend HTTP 200.
Root cause
src/postiz/src/compose.yaml already declares the dependency correctly:
depends_on:
postiz-postgres: { condition: service_healthy }
postiz-redis: { condition: service_healthy }
temporal: { condition: service_healthy }
and this survives into the runtime container labels:
com.docker.compose.depends_on=temporal:service_healthy:false,
postiz-postgres:service_healthy:false,
postiz-redis:service_healthy:false
But depends_on is only evaluated by docker compose up. It is metadata; the Docker daemon does not read it. On boot:
restart policy: unless-stopped (every container)
enabled units: docker.service, docker.socket — nothing runs `docker compose up`
dockerd restarts all containers concurrently in arbitrary order. postiz beats redis, ioredis throws on an unresolvable host during NestJS init, the backend pm2 process dies, and pm2 does not bring it back. The frontend and nginx come up fine, so the container stays "running" while /api is dead.
This affects every multi-service package in this repo, not just postiz — any package relying on depends_on for ordering has no ordering guarantee across a host reboot. postiz is just the most fragile because its backend crashes rather than retries.
Suggested fixes
Roughly in increasing order of effort:
-
Autoheal (cheapest, highest value). Run a small autoheal sidecar that restarts containers reporting unhealthy. The healthchecks in this repo are already accurate — postiz's deliberately probes /api/auth/can-register through nginx specifically to catch a dead backend (per the comment in compose.yaml). That healthcheck correctly detected this outage; nothing was listening. This turns an existing, working signal into an automatic recovery and fixes the whole class of problem for all packages.
-
Bring deployments up with compose on boot. Set restart: "no" (or on-failure) and have the runtime run docker compose up -d --wait per deployment at startup. This makes depends_on: service_healthy actually mean something. Likely belongs in the Hola runtime rather than here — see note below.
-
Make postiz tolerate an absent redis at boot. ioredis supports retryStrategy/lazyConnect; the crash comes from an unhandled error event during init. This is upstream gitroomhq/postiz-app, so probably out of scope here except as a wrapper/entrypoint workaround.
Note on repo scope
Filing here since src/postiz/src/compose.yaml is the artifact that exhibits it, but the actual defect is in boot-time orchestration, and that may live in the Hola runtime (try-hola/hola) rather than in this package repo. The package's compose file is, as far as I can tell, already correct. Feel free to move or split this — fix (1) in particular is a runtime-level concern.
Environment
- Host: Proxmox VE 9.1.11, LXC guest
hola (unprivileged), 18 containers
- Docker 29.6.1, containerd image store, overlayfs storage driver
- postiz
v2.21.10, redis 7.4-alpine, temporal 1.29.7
- Surfaced during a storage migration that required a clean stop/start of the guest
Summary
After a host reboot, the
postizcontainer comes up but its backend (pm2 process on :3000) is dead, leaving nginx to 502 every/apicall. The container's healthcheck correctly reportsunhealthy, but nothing acts on it, so the app stays broken until someone manually restarts the container.Root cause is not the package's compose file — it's that
depends_onordering is silently discarded on boot.Observed
Seen on a Proxmox LXC host reboot (
hola, 18 containers). Immediately after boot:Backend logs:
and nginx, continuously:
Once things settled, redis was fine and DNS resolved — the failure was purely a startup race that the backend never recovered from:
docker restart hola-postiz-4520f878-postiz-1fixed it permanently:healthy, backendHTTP 200.Root cause
src/postiz/src/compose.yamlalready declares the dependency correctly:and this survives into the runtime container labels:
But
depends_onis only evaluated bydocker compose up. It is metadata; the Docker daemon does not read it. On boot:dockerd restarts all containers concurrently in arbitrary order. postiz beats redis,
ioredisthrows on an unresolvable host during NestJS init, the backend pm2 process dies, and pm2 does not bring it back. The frontend and nginx come up fine, so the container stays "running" while/apiis dead.This affects every multi-service package in this repo, not just postiz — any package relying on
depends_onfor ordering has no ordering guarantee across a host reboot. postiz is just the most fragile because its backend crashes rather than retries.Suggested fixes
Roughly in increasing order of effort:
Autoheal (cheapest, highest value). Run a small autoheal sidecar that restarts containers reporting
unhealthy. The healthchecks in this repo are already accurate — postiz's deliberately probes/api/auth/can-registerthrough nginx specifically to catch a dead backend (per the comment incompose.yaml). That healthcheck correctly detected this outage; nothing was listening. This turns an existing, working signal into an automatic recovery and fixes the whole class of problem for all packages.Bring deployments up with compose on boot. Set
restart: "no"(oron-failure) and have the runtime rundocker compose up -d --waitper deployment at startup. This makesdepends_on: service_healthyactually mean something. Likely belongs in the Hola runtime rather than here — see note below.Make postiz tolerate an absent redis at boot.
ioredissupportsretryStrategy/lazyConnect; the crash comes from an unhandled error event during init. This is upstreamgitroomhq/postiz-app, so probably out of scope here except as a wrapper/entrypoint workaround.Note on repo scope
Filing here since
src/postiz/src/compose.yamlis the artifact that exhibits it, but the actual defect is in boot-time orchestration, and that may live in the Hola runtime (try-hola/hola) rather than in this package repo. The package's compose file is, as far as I can tell, already correct. Feel free to move or split this — fix (1) in particular is a runtime-level concern.Environment
hola(unprivileged), 18 containersv2.21.10, redis7.4-alpine, temporal1.29.7