|
| 1 | +# Build stage - Download and prepare webapp |
1 | 2 | FROM alpine:3.22.0 AS build |
2 | 3 |
|
3 | | -# set version label |
| 4 | +# Set version label |
4 | 5 | ARG WEBAPP_VERSION |
5 | 6 |
|
6 | | -RUN apk add --no-cache \ |
| 7 | +# Install build dependencies with virtual package for easy cleanup |
| 8 | +RUN apk add --no-cache --virtual .build-deps \ |
7 | 9 | bash \ |
8 | | - busybox \ |
9 | 10 | curl \ |
10 | 11 | git \ |
11 | 12 | jq \ |
12 | | - npm && \ |
13 | | - mkdir /app && \ |
14 | | - if [ -z ${WEBAPP_VERSION+x} ]; then \ |
| 13 | + npm \ |
| 14 | + && mkdir /app \ |
| 15 | + # Determine webapp version if not provided |
| 16 | + && if [ -z "${WEBAPP_VERSION+x}" ]; then \ |
15 | 17 | WEBAPP_VERSION=$(curl -sX GET "https://api.github.com/repos/netbootxyz/webapp/releases/latest" \ |
16 | 18 | | awk '/tag_name/{print $4;exit}' FS='[""]'); \ |
17 | | - fi && \ |
18 | | - curl -o /tmp/webapp.tar.gz -L \ |
19 | | - "https://github.com/netbootxyz/webapp/archive/${WEBAPP_VERSION}.tar.gz" && \ |
20 | | - tar xf /tmp/webapp.tar.gz -C /app/ --strip-components=1 && \ |
21 | | - npm install --prefix /app && \ |
22 | | - rm -rf /tmp/* |
| 19 | + fi \ |
| 20 | + # Download and extract webapp |
| 21 | + && curl -o /tmp/webapp.tar.gz -L \ |
| 22 | + "https://github.com/netbootxyz/webapp/archive/${WEBAPP_VERSION}.tar.gz" \ |
| 23 | + && tar xf /tmp/webapp.tar.gz -C /app/ --strip-components=1 \ |
| 24 | + # Install only production dependencies |
| 25 | + && cd /app \ |
| 26 | + && npm install --omit=dev --no-audit --no-fund \ |
| 27 | + # Clean up build artifacts and cache |
| 28 | + && npm cache clean --force \ |
| 29 | + && rm -rf /tmp/* \ |
| 30 | + && apk del .build-deps |
23 | 31 |
|
| 32 | +# Production stage - Final container |
24 | 33 | FROM alpine:3.22.0 |
25 | 34 |
|
26 | | -# set version label |
| 35 | +# Build arguments for labels |
27 | 36 | ARG BUILD_DATE |
28 | 37 | ARG VERSION |
| 38 | +ARG VCS_REF |
29 | 39 |
|
30 | | -LABEL build_version="netboot.xyz version: ${VERSION} Build-date: ${BUILD_DATE}" |
31 | | -LABEL maintainer="antonym" |
32 | | -LABEL org.opencontainers.image.description="netboot.xyz official docker container - Your favorite operating systems in one place. A network-based bootable operating system installer based on iPXE." |
| 40 | +# Enhanced container labels following OCI spec |
| 41 | +LABEL org.opencontainers.image.title="netboot.xyz" \ |
| 42 | + org.opencontainers.image.description="Your favorite operating systems in one place. A network-based bootable operating system installer based on iPXE." \ |
| 43 | + org.opencontainers.image.version="${VERSION}" \ |
| 44 | + org.opencontainers.image.created="${BUILD_DATE}" \ |
| 45 | + org.opencontainers.image.revision="${VCS_REF}" \ |
| 46 | + org.opencontainers.image.vendor="netboot.xyz" \ |
| 47 | + org.opencontainers.image.url="https://netboot.xyz" \ |
| 48 | + org.opencontainers.image.source="https://github.com/netbootxyz/docker-netbootxyz" \ |
| 49 | + org.opencontainers.image.licenses="Apache-2.0" \ |
| 50 | + maintainer="antonym" |
33 | 51 |
|
| 52 | +# Install runtime dependencies and configure system in a single layer |
34 | 53 | RUN apk add --no-cache \ |
| 54 | + # Core utilities |
35 | 55 | bash \ |
36 | 56 | busybox \ |
37 | 57 | curl \ |
38 | | - dnsmasq \ |
39 | 58 | envsubst \ |
40 | | - git \ |
41 | 59 | jq \ |
42 | | - nghttp2-dev \ |
| 60 | + tar \ |
| 61 | + # Network services |
| 62 | + dnsmasq \ |
43 | 63 | nginx \ |
44 | 64 | nodejs \ |
| 65 | + # System services |
45 | 66 | shadow \ |
46 | 67 | sudo \ |
47 | 68 | supervisor \ |
48 | 69 | syslog-ng \ |
49 | | - tar && \ |
50 | | - groupmod -g 1000 users && \ |
51 | | - useradd -u 911 -U -d /config -s /bin/false nbxyz && \ |
52 | | - usermod -G users nbxyz && \ |
53 | | - mkdir /app /config /defaults |
| 70 | + # Security tools |
| 71 | + gosu \ |
| 72 | + # Runtime libraries |
| 73 | + nghttp2-dev \ |
| 74 | + # Create required directories |
| 75 | + && mkdir -p /app /config /defaults \ |
| 76 | + # Remove unnecessary packages to reduce size |
| 77 | + && rm -rf /var/cache/apk/* |
54 | 78 |
|
| 79 | +# Copy webapp from build stage |
55 | 80 | COPY --from=build /app /app |
56 | 81 |
|
57 | | -ENV TFTPD_OPTS='' |
58 | | -ENV NGINX_PORT='80' |
59 | | -ENV WEB_APP_PORT='3000' |
| 82 | +# Environment variables with defaults |
| 83 | +ENV TFTPD_OPTS='' \ |
| 84 | + NGINX_PORT='80' \ |
| 85 | + WEB_APP_PORT='3000' \ |
| 86 | + NODE_ENV='production' \ |
| 87 | + NPM_CONFIG_CACHE='/tmp/.npm' \ |
| 88 | + PUID='1000' \ |
| 89 | + PGID='1000' |
60 | 90 |
|
61 | 91 | EXPOSE 69/udp |
62 | 92 | EXPOSE 80 |
63 | 93 | EXPOSE 3000 |
64 | 94 |
|
65 | | -COPY root/ / |
| 95 | +# Copy configuration files and scripts |
| 96 | +COPY --chown=root:root root/ / |
| 97 | + |
| 98 | +# Make scripts executable |
| 99 | +RUN chmod +x /start.sh /init.sh /healthcheck.sh /usr/local/bin/dnsmasq-wrapper.sh |
66 | 100 |
|
67 | | -HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 CMD /healthcheck.sh |
| 101 | +# Enhanced health check with better timing for slow systems |
| 102 | +HEALTHCHECK --interval=30s --timeout=15s --start-period=60s --retries=3 \ |
| 103 | + CMD /healthcheck.sh |
68 | 104 |
|
69 | | -CMD ["sh","/start.sh"] |
| 105 | +# Use exec form for better signal handling |
| 106 | +CMD ["/start.sh"] |
0 commit comments