37 lines
1.5 KiB
Docker
37 lines
1.5 KiB
Docker
# ── Stage 1 : nothing to build, just copy static assets ──────────────────────
|
|
# Use nginx:alpine — ~8 MB, actively maintained, CVE-scanned by Docker Hub
|
|
FROM nginx:stable-alpine AS runtime
|
|
|
|
# Drop all Linux capabilities the HTTP server doesn't need.
|
|
# Only CAP_NET_BIND_SERVICE is kept when binding to port 80; since we expose
|
|
# 8080 (>1024) and run as non-root, we can drop everything.
|
|
# These are set at runtime via docker-compose; the label is informational.
|
|
LABEL org.opencontainers.image.title="it_portfolio" \
|
|
org.opencontainers.image.description="Static portfolio — nginx/alpine" \
|
|
org.opencontainers.image.authors="Gauvain Boiché"
|
|
|
|
# Replace the default nginx config with our hardened one
|
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|
|
|
# Copy static assets
|
|
COPY index.html /usr/share/nginx/html/index.html
|
|
COPY content/ /usr/share/nginx/html/content/
|
|
COPY resources/ /usr/share/nginx/html/resources/
|
|
|
|
# Give the non-root nginx user ownership of what it needs at runtime.
|
|
# Temp files go to /tmp (1777 tmpfs), so no pre-creation needed.
|
|
RUN chown -R nginx:nginx \
|
|
/var/log/nginx \
|
|
/etc/nginx/nginx.conf \
|
|
/usr/share/nginx/html \
|
|
&& chmod -R 755 /usr/share/nginx/html
|
|
|
|
# Switch to the built-in unprivileged nginx user
|
|
USER nginx
|
|
|
|
# Expose unprivileged port (no CAP_NET_BIND_SERVICE required)
|
|
EXPOSE 8080
|
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
|
CMD wget -qO- http://localhost:8080/ || exit 1
|