Make the image prepare its own data directory (closes #262)
check / check (push) Failing after 4s

A host directory mounted at /var/lib/neoirc kept the host's owner, so neoircd could not create state.db and stopped at startup.

The image now starts deploy/docker-entrypoint.sh as root. It creates /var/lib/neoirc, gives it and its contents to neoirc with mode 0700, and execs neoircd as neoirc through su-exec. The runtime stage drops USER neoirc and no longer creates the directory at build time.

Judgement call: the entrypoint assumes it starts as root; docker run --user fails at chown.

Model: opus-5-5
This commit was merged in pull request #266.
This commit is contained in:
clawbot committed 2026-11-10 22:42:02 +01:00
1 parent a3d9bbfd81
commit f42c6214a0
3 files changed
+40 -8

No files matched your search

+7 -6
View File
@@ -83,14 +83,15 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /neoirc-cli ./cmd/neoir
# stage's chain and nothing else.
# alpine:3.21, 2026-02-26
FROM alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
RUN apk add --no-cache ca-certificates \
&& addgroup -S neoirc && adduser -S neoirc -G neoirc \
&& mkdir -p /var/lib/neoirc \
&& chown neoirc:neoirc /var/lib/neoirc
# su-exec 0.2-r3, 2026-11-10
RUN apk add --no-cache ca-certificates su-exec=0.2-r3 \
&& addgroup -S neoirc && adduser -S neoirc -G neoirc
COPY --from=builder /neoircd /usr/local/bin/neoircd
COPY deploy/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
USER neoirc
# No USER: the entrypoint starts as root to give /var/lib/neoirc to neoirc,
# then runs neoircd as neoirc.
EXPOSE 8080 6667
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:8080/.well-known/healthcheck.json || exit 1
ENTRYPOINT ["neoircd"]
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
+19 -2
View File
@@ -1790,13 +1790,17 @@ NEOIRC_HASHCASH_BITS=20
the linter first and stops when either fails. The image:
- is Alpine with the `neoircd` binary and CA certificates;
- runs as the user `neoirc`;
- runs `neoircd` as the user `neoirc`;
- exposes ports 8080 and 6667;
- keeps its database in `/var/lib/neoirc`;
- has a `HEALTHCHECK` that calls `/.well-known/healthcheck.json` every 30
seconds.
Run it with a volume for the database and the settings as environment variables:
The image prepares `/var/lib/neoirc` itself on every start. It creates the
directory, gives it to `neoirc` and then runs `neoircd` as `neoirc`.
Run it with a named volume for the database and the settings as environment
variables:
```bash
docker run -d --name neoirc \
@@ -1807,6 +1811,17 @@ docker run -d --name neoirc \
neoirc
```
A host directory works the same way in place of the named volume:
```bash
docker run -d --name neoirc \
-p 8080:8080 -p 6667:6667 \
-v /srv/neoirc:/var/lib/neoirc \
-e SERVER_NAME="My Server" \
-e MOTD="Welcome!" \
neoirc
```
### Reverse proxy
Run the server behind a reverse proxy that terminates TLS. The server itself
@@ -2000,6 +2015,8 @@ and their sessions to end. Then it closes the database.
- `schema/`: JSON Schema files for the message envelope, with their own
`README.md`.
- `script/`: the entrypoints below.
- `deploy/`: `docker-entrypoint.sh`, the image's entrypoint, which prepares
`/var/lib/neoirc` and starts `neoircd` as `neoirc`.
- `CONVENTIONS.md`, `REPO_POLICIES.md` and `AGENTS.md`: the architecture
conventions, the repository policies and the rules for coding agents.
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
# deploy/docker-entrypoint.sh: the image's ENTRYPOINT, run as root. A host
# directory mounted at /var/lib/neoirc keeps the host's owner, so this gives
# it to neoirc before running neoircd as neoirc.
set -eu
main() {
mkdir -p /var/lib/neoirc
chown -R neoirc:neoirc /var/lib/neoirc
chmod 0700 /var/lib/neoirc
exec su-exec neoirc neoircd "$@"
}
main "$@"