Add Dockerfile and automation to build and publish a docker image

This commit is contained in:
Przemek Więch
2026-05-06 00:02:53 +02:00
parent fdc0f50a97
commit 40df8112bd
9 changed files with 609 additions and 3 deletions

41
docker/Caddyfile Normal file
View File

@@ -0,0 +1,41 @@
{
# Disable administrative API to prevent permission errors in read-only environments
admin off
}
:8080 {
root * /app/public
# Compress static assets (HTML, JS, CSS, GEDCOM text files)
encode gzip zstd
file_server
# Robust Security Headers
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "geolocation=(), microphone=(), camera=()"
}
# Cache Control: Long-lived cache ONLY for immutable hashed build assets
@immutable_assets {
path /assets/*
}
header @immutable_assets Cache-Control "public, max-age=31536000, immutable"
# Cache Control: Immediate revalidation for all mutable assets (HTML, mounted dynamic family trees/photos)
@mutable_assets {
not {
path /assets/*
}
}
header @mutable_assets Cache-Control "public, max-age=0, must-revalidate"
templates {
mime text/html
}
try_files {path} /index.html
}

24
docker/Dockerfile Normal file
View File

@@ -0,0 +1,24 @@
# Stage 1: Compile the React/TypeScript bundle
FROM node:20-alpine AS react-builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Package static assets & Caddy binary on Distroless Static
FROM gcr.io/distroless/static-debian12
USER nonroot:nonroot
WORKDIR /app
# Copy static Caddy binary from the official Caddy image
COPY --from=caddy:2.7.6-alpine /usr/bin/caddy /usr/bin/caddy
# Copy Caddy server config with nonroot ownership
COPY --chown=nonroot:nonroot docker/Caddyfile ./
# Copy React build outputs with nonroot ownership to support strict read-only filesystem deployments
COPY --chown=nonroot:nonroot --from=react-builder /app/dist ./public
EXPOSE 8080
ENTRYPOINT ["/usr/bin/caddy", "run", "--config", "./Caddyfile", "--adapter", "caddyfile"]