Public Access
1
0

refactor: optimize Dockerfile for multi-platform builds and add healthcheck script

This commit is contained in:
2025-08-23 18:11:39 -04:00
parent a54d6e445f
commit a100ea3159
4 changed files with 66 additions and 23 deletions

View File

@@ -1,40 +1,61 @@
# STAGE 1: Development
# This stage installs all dependencies (including devDependencies) and copies the source code.
# It's used as a base for the 'builder' stage and for the development environment via docker-compose.
FROM node:18-alpine AS development
# Dockerfile optimized for Raspberry Pi (ARM64) and faster builds.
# Docker BuildKit arguments for multi-platform builds.
# These are automatically populated by Docker.
ARG TARGETPLATFORM
ARG BUILDPLATFORM
# STAGE 1: Dependencies
# This stage installs all dependencies (dev and prod) from package-lock.json
# It's used as a base for both development and builder stages to leverage caching.
FROM --platform=${BUILDPLATFORM} node:18-alpine AS deps
WORKDIR /app
# Copy project files and install dependencies
COPY package*.json ./
RUN npm install
# Use `npm ci` for faster, more reliable builds from package-lock.json
RUN npm ci
# STAGE 2: Development
# This stage is for local development. It includes devDependencies and source code.
# In docker-compose.dev.yml, the source is mounted for hot-reloading.
FROM deps AS development
COPY . .
# The command is specified in docker-compose.dev.yml, but we can add a default.
CMD ["npm", "start"]
# STAGE 2: Builder
# STAGE 3: Builder
# This stage builds the Eleventy site for production.
FROM development AS builder
# The output will be in the default `_site` directory
RUN npx @11ty/eleventy
FROM deps AS builder
COPY . .
# Build the site. Requires a "build": "eleventy" script in package.json
RUN npm run build
# After building, remove development dependencies to keep the final image small.
RUN npm prune --production
# STAGE 3: Production
# STAGE 4: Production
# This stage creates a lean, production-ready image.
FROM node:18-alpine AS production
WORKDIR /app
# Copy server dependencies from the builder stage
COPY --from=builder /app/package*.json ./
# Create a non-root user for better security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Install only production dependencies for the server
RUN npm install --omit=dev
# Copy only the necessary artifacts from the builder stage
# Using --chown ensures the non-root user owns the files.
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./package.json
COPY --from=builder --chown=appuser:appgroup /app/src/server.js .
COPY --from=builder --chown=appuser:appgroup /app/_site ./_site
COPY --from=builder --chown=appuser:appgroup /app/src/_data ./_data
COPY --chown=appuser:appgroup healthcheck.js .
# Copy the server, the built Eleventy site, and the data file for the view counter.
# Note: The paths here are relative to the WORKDIR inside the 'builder' stage (/app).
COPY --from=builder /app/src/server.js .
COPY --from=builder /app/_site ./_site
# The server expects the _data directory in /app/_data, and your config places it in src/_data.
COPY --from=builder /app/src/_data ./_data
USER appuser
# Expose the port the server runs on
EXPOSE 3000
# Add a healthcheck to ensure the container is running correctly.
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD [ "node", "healthcheck.js" ]
# The command to start the server
CMD [ "node", "server.js" ]

View File

@@ -8,6 +8,7 @@ services:
build:
context: .
target: production # Use the 'production' stage from the Dockerfile
platform: linux/arm64
container_name: eleventy_prod
ports:
- 3000:3000

20
healthcheck.js Normal file
View File

@@ -0,0 +1,20 @@
const http = require('http');
const options = {
host: 'localhost',
port: 3000,
path: '/',
timeout: 2000,
};
const request = http.request(options, (res) => {
console.log(`HEALTHCHECK STATUS: ${res.statusCode}`);
process.exit(res.statusCode === 200 ? 0 : 1);
});
request.on('error', (err) => {
console.error('HEALTHCHECK ERROR', err);
process.exit(1);
});
request.end();

View File

@@ -4,7 +4,8 @@
"description": "An Eleventy project with Docker and VS Code debugging.",
"scripts": {
"start": "eleventy --serve --watch",
"debug": "node --inspect=0.0.0.0:9229 ./node_modules/.bin/eleventy --serve --watch"
"debug": "node --inspect=0.0.0.0:9229 ./node_modules/.bin/eleventy --serve --watch",
"build": "eleventy"
},
"keywords": [],
"author": "",