Files
it_portfolio/Dockerfile
2026-04-21 21:30:11 +02:00

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