Passwords: ${secret:source|admin|relay} rendered into a mesh-written icecast.xml (root 0600, mounted :ro at /etc/icecast.xml). icecast reads it as root then drops to uid 100. The secrets-in-environment exemption and server.env are removed (ADR 0086).
Directories placed: state (config, secrets, route binding) and logs (owner 100:101). The image declares VOLUME /var/log/icecast, so without the logs dir every container got a new anonymous volume.
Module network icecast: the sidecar reaches http://icecast:8000 rather than assuming machine port 8000 on host networking.
stream is routed (requires route, label icecast), matching how HAL serves icecast..
Image pin unchanged: it is the digest ace runs (icecast 2.4.4).
Verified: catalogue tests (MESH_CATALOGUE=this tree) pass. A throwaway container of the pinned image with the rendered file (dummy secrets) ran as the icecast user. status-json returned 200; admin returned 401 without credentials and 200 with them. A source PUT mounted and a listener received the stream. A wrong source password got 401. Logs were written into the uid-100 dir.
Known gap: <hostname>, <location>, <admin> and <admin-user> are XML and assignments merge only into JSON, so they keep neutral defaults. Playlists (.m3u) therefore say http://localhost:8000/... ; on ace today they say http://icecast.zurag.be:8000/..., which is not reachable from outside either.
Converts icecast for ace's migration (HAL -> nox-mesh). Preparation only; nothing assigned.
- Passwords: `${secret:source|admin|relay}` rendered into a mesh-written `icecast.xml` (root 0600, mounted :ro at /etc/icecast.xml). icecast reads it as root then drops to uid 100. The `secrets-in-environment` exemption and `server.env` are removed (ADR 0086).
- Directories placed: `state` (config, secrets, route binding) and `logs` (owner 100:101). The image declares VOLUME /var/log/icecast, so without the logs dir every container got a new anonymous volume.
- Module network `icecast`: the sidecar reaches `http://icecast:8000` rather than assuming machine port 8000 on host networking.
- `stream` is routed (`requires route`, label `icecast`), matching how HAL serves icecast.<domain>.
- Image pin unchanged: it is the digest ace runs (icecast 2.4.4).
Verified: catalogue tests (MESH_CATALOGUE=this tree) pass. A throwaway container of the pinned image with the rendered file (dummy secrets) ran as the icecast user. status-json returned 200; admin returned 401 without credentials and 200 with them. A source PUT mounted and a listener received the stream. A wrong source password got 401. Logs were written into the uid-100 dir.
Known gap: `<hostname>`, `<location>`, `<admin>` and `<admin-user>` are XML and assignments merge only into JSON, so they keep neutral defaults. Playlists (.m3u) therefore say http://localhost:8000/... ; on ace today they say http://icecast.zurag.be:8000/..., which is not reachable from outside either.
The image seds ICECAST_*_PASSWORD from the environment into /etc/icecast.xml;
ADR 0086 wants secrets as files. icecast starts as root, reads its config, then
drops to uid 100, so a root-owned 0600 icecast.xml rendered with ${secret:...}
and mounted read-only works and the entrypoint's seds never fire (no env set).
The "secrets-in-environment" exemption and server.env are gone.
Also: directories are placed (state, logs owned 100:101 so the image's VOLUME
/var/log/icecast is not an anonymous volume per container, as HAL learned);
the server and sidecar share a module network, so the sidecar reaches
http://icecast:8000 instead of assuming machine port 8000 on the host; the
stream endpoint is routed (label "icecast"), as HAL served it via traefik.
Secrets remain mesh-vault grants (requires secret), now under ${dir:state}.
Verified: catalogue tests with MESH_CATALOGUE pointed at this tree; a
throwaway container of the pinned digest (the one ace runs) with the rendered
file (dummy secrets, root 0600, :ro): runs as icecast, status-json 200,
admin 401 without / 200 with the admin secret, a source PUT with the source
secret mounts, a listener receives it, a wrong source password gets 401, logs
land in the uid-100 directory.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Converts icecast for ace's migration (HAL -> nox-mesh). Preparation only; nothing assigned.
${secret:source|admin|relay}rendered into a mesh-writtenicecast.xml(root 0600, mounted :ro at /etc/icecast.xml). icecast reads it as root then drops to uid 100. Thesecrets-in-environmentexemption andserver.envare removed (ADR 0086).state(config, secrets, route binding) andlogs(owner 100:101). The image declares VOLUME /var/log/icecast, so without the logs dir every container got a new anonymous volume.icecast: the sidecar reacheshttp://icecast:8000rather than assuming machine port 8000 on host networking.streamis routed (requires route, labelicecast), matching how HAL serves icecast..Verified: catalogue tests (MESH_CATALOGUE=this tree) pass. A throwaway container of the pinned image with the rendered file (dummy secrets) ran as the icecast user. status-json returned 200; admin returned 401 without credentials and 200 with them. A source PUT mounted and a listener received the stream. A wrong source password got 401. Logs were written into the uid-100 dir.
Known gap:
<hostname>,<location>,<admin>and<admin-user>are XML and assignments merge only into JSON, so they keep neutral defaults. Playlists (.m3u) therefore say http://localhost:8000/... ; on ace today they say http://icecast.zurag.be:8000/..., which is not reachable from outside either.The image seds ICECAST_*_PASSWORD from the environment into /etc/icecast.xml; ADR 0086 wants secrets as files. icecast starts as root, reads its config, then drops to uid 100, so a root-owned 0600 icecast.xml rendered with ${secret:...} and mounted read-only works and the entrypoint's seds never fire (no env set). The "secrets-in-environment" exemption and server.env are gone. Also: directories are placed (state, logs owned 100:101 so the image's VOLUME /var/log/icecast is not an anonymous volume per container, as HAL learned); the server and sidecar share a module network, so the sidecar reaches http://icecast:8000 instead of assuming machine port 8000 on the host; the stream endpoint is routed (label "icecast"), as HAL served it via traefik. Secrets remain mesh-vault grants (requires secret), now under ${dir:state}. Verified: catalogue tests with MESH_CATALOGUE pointed at this tree; a throwaway container of the pinned digest (the one ace runs) with the rendered file (dummy secrets, root 0600, :ro): runs as icecast, status-json 200, admin 401 without / 200 with the admin secret, a source PUT with the source secret mounts, a listener receives it, a wrong source password gets 401, logs land in the uid-100 directory.