docker-netbootxyz/Dockerfile
Antony Messerli cd1950c036
CI: Use native arm64 runner to fix QEMU build crash (#130)
* CI: Split into native per-arch build jobs to fix QEMU arm64 crash

The arm64 build was failing with 'Illegal instruction (core dumped)'
during npm install because QEMU user-mode emulation doesn't support
all arm64 instructions used by newer Node.js versions.

Split the single multi-platform build job into:
- setup: determines tags, webapp version (shared via outputs)
- build-amd64: builds on ubuntu-latest natively
- build-arm64: builds on ubuntu-24.04-arm natively (no QEMU)
- manifest: merges per-arch digests into multi-arch manifest
- comment: posts PR test instructions

Both architectures get independent Trivy scans. The amd64 and arm64
builds run in parallel so total build time should be similar or faster.

Also pins Trivy CLI to v0.69.3 to work around deleted release assets
from the Trivy supply chain attack (aquasecurity/trivy#10265).

* Address review feedback: fix BUILD_DATE, add permissions, add event fallback

- Compute BUILD_DATE in setup job and pass as output instead of using
  $(date) in build-args YAML which is not evaluated at runtime
- Add explicit permissions block (contents:read, packages:write,
  pull-requests:write) to limit GITHUB_TOKEN scope
- Add else fallback in tag strategy for unsupported event types

* Bump Alpine base image from 3.22.2 to 3.23.3 to clear Trivy CVEs

* Fix Trivy CVEs: upgrade systeminformation to 5.31.0 and zlib to >=1.3.2

- systeminformation 5.27.1->5.31.0: fixes CVE-2025-68154, CVE-2026-26280,
  CVE-2026-26318 (command injection vulnerabilities)
- zlib 1.3.1-r2->1.3.2: fixes CVE-2026-22184 (buffer overflow in untgz)

The systeminformation fix overrides the version pinned by the webapp
upstream (5.27.10) until that repo is updated.

* Fix zlib upgrade: use apk --upgrade to ensure CVE-2026-22184 is resolved

The previous 'apk add zlib>=1.3.2' wasn't upgrading zlib because it
was already installed as a transitive dependency. Use --upgrade flag
to force apk to pull the latest available version (1.3.2-r0).

* Fix Trivy arm64 scan: set TRIVY_PLATFORM to match image architecture

Trivy defaults to linux/amd64 when resolving remote image digests.
On the arm64 build job, the pushed digest is a single-platform arm64
image, so Trivy fails with 'no child with platform linux/amd64'.
Setting TRIVY_PLATFORM=linux/arm64 resolves this.
2026-03-15 15:08:28 -05:00

111 lines
3.3 KiB
Docker

# Build stage - Download and prepare webapp
FROM alpine:3.23.3 AS build
# Set version label
ARG WEBAPP_VERSION
# Install build dependencies with virtual package for easy cleanup
RUN apk add --no-cache --virtual .build-deps \
bash \
curl \
git \
jq \
npm \
&& mkdir /app \
# Determine webapp version if not provided
&& if [ -z "${WEBAPP_VERSION+x}" ]; then \
WEBAPP_VERSION=$(curl -sX GET "https://api.github.com/repos/netbootxyz/webapp/releases/latest" \
| awk '/tag_name/{print $4;exit}' FS='[""]'); \
fi \
# Download and extract webapp
&& curl -o /tmp/webapp.tar.gz -L \
"https://github.com/netbootxyz/webapp/archive/${WEBAPP_VERSION}.tar.gz" \
&& tar xf /tmp/webapp.tar.gz -C /app/ --strip-components=1 \
# Install only production dependencies
&& cd /app \
&& npm install --omit=dev --no-audit --no-fund \
# Upgrade systeminformation to fix CVE-2025-68154, CVE-2026-26280, CVE-2026-26318
&& npm install systeminformation@5.31.0 --omit=dev --no-audit --no-fund --save \
# Clean up build artifacts and cache
&& npm cache clean --force \
&& rm -rf /tmp/* \
&& apk del .build-deps
# Production stage - Final container
FROM alpine:3.23.3
# Build arguments for labels
ARG BUILD_DATE
ARG VERSION
ARG VCS_REF
# Enhanced container labels following OCI spec
LABEL org.opencontainers.image.title="netboot.xyz" \
org.opencontainers.image.description="Your favorite operating systems in one place. A network-based bootable operating system installer based on iPXE." \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.created="${BUILD_DATE}" \
org.opencontainers.image.revision="${VCS_REF}" \
org.opencontainers.image.vendor="netboot.xyz" \
org.opencontainers.image.url="https://netboot.xyz" \
org.opencontainers.image.source="https://github.com/netbootxyz/docker-netbootxyz" \
org.opencontainers.image.licenses="Apache-2.0" \
maintainer="antonym"
# Install runtime dependencies and configure system in a single layer
RUN apk --initdb add --no-cache \
# Base system
alpine-baselayout \
# Core utilities
bash \
busybox \
curl \
envsubst \
jq \
tar \
# Network services
dnsmasq \
nginx \
nodejs \
# System services
shadow \
sudo \
supervisor \
syslog-ng \
# Runtime libraries
nghttp2-dev \
# Create required directories
&& mkdir -p /app /config /defaults \
# Upgrade zlib to fix CVE-2026-22184
&& apk add --no-cache --upgrade zlib \
# Remove unnecessary packages to reduce size
&& rm -rf /var/cache/apk/*
# Copy webapp from build stage
COPY --from=build /app /app
# Environment variables with defaults
ENV TFTPD_OPTS='' \
NGINX_PORT='80' \
WEB_APP_PORT='3000' \
NODE_ENV='production' \
NPM_CONFIG_CACHE='/tmp/.npm' \
PUID='1000' \
PGID='1000'
EXPOSE 69/udp
EXPOSE 80
EXPOSE 3000
# Copy configuration files and scripts
COPY root/ /
# Make scripts executable
RUN chmod +x /start.sh /init.sh /healthcheck.sh /usr/local/bin/dnsmasq-wrapper.sh
# Enhanced health check with better timing for slow systems
HEALTHCHECK --interval=30s --timeout=15s --start-period=60s --retries=3 \
CMD /healthcheck.sh
# Use exec form for better signal handling
CMD ["/start.sh"]