43 lines
1.8 KiB
Docker
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;"]
|