# =============================================================================
# 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;"]
