Files
mailgoserver/Dockerfile.aio
T

80 lines
4.5 KiB
Docker

# syntax=docker/dockerfile:1
#
# All-in-one: mailgoserver + rspamd + redis, bundled in one container — the full spam-
# filtering stack, not just rspamd's SPF/DKIM/RBL/regexp scoring. Redis backs rspamd's
# Bayes classifier (learns from mail marked as spam/ham) and its greylisting module,
# neither of which work without it (see docker-deploy/README.md's original note on
# Dockerfile.rspamd, which intentionally skips redis for a lighter image — use that one
# instead if you don't want Bayes/greylisting). mailgoserver itself has no direct use
# for redis — it's a single-instance app already backed by SQLite for everything, so
# there's nothing here for redis to cache or coordinate; it exists purely to make
# rspamd's scoring meaningfully better.
#
# Build from the repo root:
# docker build -f docker-deploy/Dockerfile.aio -t mailgoserver-aio .
FROM golang:1.26-bookworm AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/mailgoserver .
FROM debian:bookworm-slim
# rspamd from its own APT repo (rspamd.com), same as Dockerfile.rspamd, for the latest
# stable release rather than Debian's older bundled version. redis-server is Debian's
# own package — no third-party repo needed there, and bookworm's version (7.0.x) is
# recent enough for everything rspamd's Bayes/greylist modules need.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates tzdata curl gnupg lsb-release libcap2-bin redis-server \
&& mkdir -p /usr/share/keyrings \
&& curl -fsSL https://rspamd.com/apt-stable/gpg.key | gpg --dearmor -o /usr/share/keyrings/rspamd.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/rspamd.gpg] https://rspamd.com/apt-stable/ $(lsb_release -cs) main" \
> /etc/apt/sources.list.d/rspamd.list \
&& apt-get update && apt-get install -y --no-install-recommends rspamd \
&& rm -rf /var/lib/apt/lists/*
# Point rspamd's Bayes classifier and greylisting module at the redis instance this same
# container runs (loopback-only, see entrypoint-aio.sh) — both are otherwise inert
# without a redis backend. Every other redis-capable module (ratelimit, etc.) picks up
# the same servers = ... from this one redis.conf too, rspamd's own convention for
# sharing one connection config across modules. Also redirects rspamd's own dbdir (fuzzy
# storage, DNS/maps cache) into server_data/rspamd — created/chowned at container start
# by entrypoint-aio.sh, since it lives on the volume, not the image — so this whole
# bundle only ever needs one thing mounted: server_data/.
RUN mkdir -p /etc/rspamd/local.d \
&& printf 'servers = "127.0.0.1:6379";\n' > /etc/rspamd/local.d/redis.conf \
&& printf 'backend = "redis";\nservers = "127.0.0.1:6379";\n' > /etc/rspamd/local.d/classifier-bayes.conf \
&& printf 'enabled = true;\nservers = "127.0.0.1:6379";\n' > /etc/rspamd/local.d/greylist.conf \
&& printf 'dbdir = "/app/server_data/rspamd";\n' > /etc/rspamd/local.d/options.inc
COPY --from=build /out/mailgoserver /usr/local/bin/mailgoserver
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/mailgoserver
COPY docker-deploy/entrypoint-aio.sh /usr/local/bin/entrypoint-aio.sh
RUN chmod +x /usr/local/bin/entrypoint-aio.sh
# rspamd and redis's own .deb postinsts already create their system users;
# mailgoserver gets one here for the same reason as the other images — none of the
# three processes run as root (see entrypoint-aio.sh for how each is dropped).
RUN useradd --system --create-home --home-dir /app --shell /usr/sbin/nologin mailgoserver \
&& mkdir -p /app/server_data \
&& chown -R mailgoserver:mailgoserver /app \
&& chmod 755 /app
WORKDIR /app
VOLUME ["/app/server_data"]
# Deliberately stays root here (unlike the standalone Dockerfile's USER mailgoserver) —
# the entrypoint script itself needs root just long enough to chown server_data's
# rspamd/redis subdirectories and drop privileges for each child individually.
# 11334 (rspamd's own web UI, controller worker) is intentionally NOT exposed here —
# it has no authentication configured by default, and this bundle doesn't need it for
# anything mailgoserver itself uses. Add a `password` to rspamd's controller worker
# config and publish it yourself if you want it. Port 6379 (redis) is never exposed at
# all — loopback-only, see entrypoint-aio.sh.
EXPOSE 25 465 143 993 80 5000 5001
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD curl -fs http://127.0.0.1:5000/health || exit 1
ENTRYPOINT ["/usr/local/bin/entrypoint-aio.sh"]