Files
zonemaster.es/Dockerfile.backend

237 lines
7.8 KiB
Docker
Raw Normal View History

# =============================================================================
# Zonemaster Backend — multi-stage build from source
# Chain: LDNS → Engine → CLI → Backend
# =============================================================================
# ── Stage 1: Build LDNS ──────────────────────────────────────────────────────
FROM alpine:3.22 AS ldns-build
RUN apk add --no-cache \
build-base \
libidn2-dev \
make \
openssl-dev \
perl-app-cpanminus \
perl-dev \
perl-devel-checklib \
perl-extutils-depends \
perl-extutils-pkgconfig \
perl-lwp-protocol-https \
perl-mime-base32 \
perl-module-install \
perl-test-differences \
perl-test-fatal \
perl-test-nowarnings \
&& cpanm --notest --no-wget --from=https://cpan.metacpan.org/ \
Module::Install::XSUtil
COPY zonemaster-ldns/ /src/ldns/
RUN cpanm --notest --no-wget /src/ldns/
# ── Stage 2: LDNS runtime base ────────────────────────────────────────────────
FROM alpine:3.22 AS ldns
COPY --from=ldns-build \
/usr/local/lib/perl5/site_perl/auto/Zonemaster \
/usr/local/lib/perl5/site_perl/auto/Zonemaster
COPY --from=ldns-build \
/usr/local/lib/perl5/site_perl/Zonemaster \
/usr/local/lib/perl5/site_perl/Zonemaster
RUN apk add --no-cache libidn2 perl
# ── Stage 3: Build Engine ─────────────────────────────────────────────────────
FROM ldns AS engine-build
RUN apk add --no-cache \
gcc \
make \
musl-dev \
perl-dev \
perl-app-cpanminus \
perl-mailtools \
perl-module-build-tiny \
perl-class-accessor \
perl-clone \
perl-file-sharedir \
perl-file-slurp \
perl-io-socket-inet6 \
perl-list-moreutils \
perl-locale-msgfmt \
perl-log-any \
perl-lwp-protocol-https \
perl-mail-spf \
perl-module-install \
perl-pod-coverage \
perl-readonly \
perl-sub-override \
perl-test-differences \
perl-test-exception \
perl-test-fatal \
perl-test-nowarnings \
perl-test-pod \
perl-text-csv \
perl-yaml \
perl-yaml-libyaml \
&& cpanm --no-wget --from=https://cpan.metacpan.org/ \
Email::Valid \
List::Compare \
Locale::PO \
Locale::TextDomain \
Module::Find \
Net::IP::XS
COPY zonemaster-engine/ /src/engine/
RUN cpanm --notest --no-wget /src/engine/
# ── Stage 4: Engine runtime base ─────────────────────────────────────────────
FROM ldns AS engine
COPY --from=engine-build /usr/local/lib/perl5/site_perl /usr/local/lib/perl5/site_perl
COPY --from=engine-build /usr/local/share/perl5/site_perl /usr/local/share/perl5/site_perl
RUN apk add --no-cache \
musl-locales \
perl-class-accessor \
perl-clone \
perl-file-sharedir \
perl-file-slurp \
perl-io-socket-inet6 \
perl-list-moreutils \
perl-locale-msgfmt \
perl-log-any \
perl-mail-spf \
perl-mailtools \
perl-module-install \
perl-net-ip \
perl-readonly \
perl-text-csv \
perl-try-tiny \
perl-yaml-libyaml
# ── Stage 5: Build CLI ────────────────────────────────────────────────────────
FROM engine AS cli-build
RUN apk add --no-cache \
make \
perl-app-cpanminus \
perl-json-xs \
perl-lwp-protocol-https \
perl-mojolicious \
perl-test-deep \
perl-test-differences \
perl-try-tiny \
&& cpanm --notest --no-wget --from=https://cpan.metacpan.org/ \
JSON::Validator
COPY zonemaster-cli/ /src/cli/
RUN cpanm --notest --no-wget /src/cli/
# ── Stage 6: CLI runtime base ─────────────────────────────────────────────────
FROM engine AS cli
RUN apk add --no-cache perl-json-xs perl-try-tiny
COPY --from=cli-build /usr/local/bin/zonemaster-cli /usr/local/bin/zonemaster-cli
COPY --from=cli-build /usr/local/lib/perl5/site_perl /usr/local/lib/perl5/site_perl
COPY --from=cli-build /usr/local/share/perl5/site_perl /usr/local/share/perl5/site_perl
# ── Stage 7: Build Backend ────────────────────────────────────────────────────
FROM cli AS backend-build
RUN apk add --no-cache \
make \
curl \
gcc \
perl-dev \
musl-dev \
perl-app-cpanminus \
jq \
perl-class-method-modifiers \
perl-config-inifiles \
perl-dbd-sqlite \
perl-dbi \
perl-file-share \
perl-file-slurp \
perl-html-parser \
perl-http-parser-xs \
perl-mojolicious \
perl-io-stringy \
perl-log-any \
perl-log-dispatch \
perl-moose \
perl-parallel-forkmanager \
perl-plack \
perl-role-tiny \
perl-test-nowarnings \
perl-test-differences \
perl-test-exception \
perl-try-tiny \
perl-doc \
&& cpanm --notest --no-wget --from=https://cpan.metacpan.org/ \
Net::Statsd
COPY zonemaster-backend/ /src/backend/
RUN cpanm --notest --no-wget /src/backend/
# ── Stage 8: Backend runtime (final image) ────────────────────────────────────
FROM cli AS backend
RUN apk add --no-cache \
jq \
perl-config-inifiles \
perl-mojolicious \
perl-moose \
perl-dbi \
perl-dbd-sqlite \
perl-plack \
perl-parallel-forkmanager
COPY --from=backend-build /usr/local/share/perl5 /usr/local/share/perl5
COPY --from=backend-build /usr/local/bin/ /usr/local/bin/
COPY --from=backend-build /usr/lib/perl5 /usr/lib/perl5
RUN addgroup -S zonemaster \
&& adduser -S zonemaster -G zonemaster
RUN SHARE=$(perl -MFile::ShareDir=dist_dir -E 'say dist_dir("Zonemaster-Backend")') \
&& install -v -m 755 -d /etc/zonemaster \
&& install -v -m 775 -g zonemaster -d /var/log/zonemaster \
&& install -v -m 640 -g zonemaster "$SHARE/backend_config.ini" /etc/zonemaster/
RUN install -v -m 755 -o zonemaster -g zonemaster -d /var/lib/zonemaster
USER zonemaster
RUN "$(perl -MFile::ShareDir -le 'print File::ShareDir::dist_dir("Zonemaster-Backend")')/create_db.pl"
USER root
# Install s6-overlay for process supervision (rpcapi + testagent)
ARG S6_OVERLAY_VERSION=3.2.1.0
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz
COPY zonemaster-backend/zonemaster_launch /usr/local/bin/zonemaster_launch
RUN chmod +x /usr/local/bin/zonemaster_launch
# Register rpcapi service (JSON-RPC API on :5000)
RUN mkdir -p /etc/s6-overlay/s6-rc.d/rpcapi \
&& echo "longrun" > /etc/s6-overlay/s6-rc.d/rpcapi/type \
&& printf '#!/command/with-contenv sh\nexec zonemaster_launch rpcapi\n' \
> /etc/s6-overlay/s6-rc.d/rpcapi/run \
&& chmod +x /etc/s6-overlay/s6-rc.d/rpcapi/run \
&& touch /etc/s6-overlay/s6-rc.d/user/contents.d/rpcapi
# Register testagent service (background test runner)
RUN mkdir -p /etc/s6-overlay/s6-rc.d/testagent \
&& echo "longrun" > /etc/s6-overlay/s6-rc.d/testagent/type \
&& printf '#!/command/with-contenv sh\nexec zonemaster_launch testagent\n' \
> /etc/s6-overlay/s6-rc.d/testagent/run \
&& chmod +x /etc/s6-overlay/s6-rc.d/testagent/run \
&& touch /etc/s6-overlay/s6-rc.d/user/contents.d/testagent
EXPOSE 5000
ENTRYPOINT ["/init"]