Files
2026-09-13 20:05:01 +01:00

43 lines
1.8 KiB
Docker

# =============================================================================
# Cipher Barcode Studio — production image
# Base: nginx 1.30.1 on Alpine 3.23 (unprivileged variant — runs as UID 101)
# =============================================================================
FROM nginxinc/nginx-unprivileged:1.30.1-alpine3.23-slim
# OCI labels for traceability
LABEL org.opencontainers.image.title="Cipher Barcode Studio" \
org.opencontainers.image.description="Static web app for generating barcodes in 22 symbologies and exporting JPG/PNG" \
org.opencontainers.image.version="1.0.0" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.source="https://example.com/cipher-barcode-studio"
# The unprivileged image runs as user 101 (nginx). All file ops use --chown.
USER root
# Apply the latest Alpine security patches at build time, then strip the cache
RUN apk update && apk upgrade --no-cache && rm -rf /var/cache/apk/*
# Replace the default nginx config with our hardened one
COPY --chown=nginx:nginx nginx/nginx.conf /etc/nginx/nginx.conf
# Copy the static site
COPY --chown=nginx:nginx web/ /usr/share/nginx/html/
# Make sure runtime dirs the unprivileged user needs are writable
RUN mkdir -p /tmp/client_body /tmp/proxy /tmp/fastcgi /tmp/uwsgi /tmp/scgi \
&& chown -R nginx:nginx /tmp/client_body /tmp/proxy /tmp/fastcgi /tmp/uwsgi /tmp/scgi /var/log/nginx \
&& chmod -R 755 /usr/share/nginx/html
# Drop back to the non-root user for runtime
USER nginx
# Internal port — unprivileged nginx listens on 8080
EXPOSE 8080
# Healthcheck driven by /healthz from nginx.conf
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://127.0.0.1:8080/healthz || exit 1
CMD ["nginx", "-g", "daemon off;"]