fix: improve image build
This commit is contained in:
23
Dockerfile
23
Dockerfile
@@ -5,6 +5,10 @@
|
||||
ARG TARGETPLATFORM
|
||||
ARG BUILDPLATFORM
|
||||
|
||||
# Arguments for user and group IDs. Default to a common non-root user ID.
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
# 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.
|
||||
@@ -38,21 +42,20 @@ RUN npm prune --production
|
||||
FROM node:18-alpine AS production
|
||||
WORKDIR /app
|
||||
|
||||
# Create a non-root user for better security
|
||||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
||||
|
||||
# The node:18-alpine image comes with a non-root 'node' user (UID/GID 1000)
|
||||
# which we will use. We only need su-exec to drop privileges in the entrypoint.
|
||||
# Install su-exec for dropping privileges from root
|
||||
RUN apk add --no-cache su-exec
|
||||
|
||||
# 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=node:node /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=node:node /app/package.json ./package.json
|
||||
COPY --from=builder --chown=node:node /app/src/server.js .
|
||||
COPY --from=builder --chown=node:node /app/_site ./_site
|
||||
# The _data directory is handled by the volume, but we copy it so the volume can be pre-populated on first run.
|
||||
COPY --from=builder --chown=appuser:appgroup /app/src/_data/ ./_data/
|
||||
COPY --chown=appuser:appgroup healthcheck.js .
|
||||
COPY --from=builder --chown=node:node /app/src/_data/ ./_data/
|
||||
COPY --chown=node:node healthcheck.js .
|
||||
|
||||
# Copy and set up the entrypoint script
|
||||
COPY --chown=root:root entrypoint.sh /usr/local/bin/
|
||||
@@ -60,7 +63,7 @@ RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Add a healthcheck to ensure the container is running correctly.
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||
CMD ["su-exec", "appuser", "node", "healthcheck.js"]
|
||||
CMD ["su-exec", "node", "node", "healthcheck.js"]
|
||||
|
||||
ENTRYPOINT ["entrypoint.sh"]
|
||||
CMD ["node", "server.js"]
|
||||
|
@@ -1,60 +0,0 @@
|
||||
# docker-compose.dev.yml for development
|
||||
# This setup runs two services:
|
||||
# 1. The Eleventy dev server for live-reloading site changes.
|
||||
# 2. The Express API server for the view counter.
|
||||
#
|
||||
# To start both, run: docker compose -f docker-compose.dev.yml up
|
||||
#
|
||||
# Your site will be available at http://localhost:8080.
|
||||
# API requests are proxied from /api to the API service, so you don't need to access port 3000 directly.
|
||||
services:
|
||||
# This service runs the Eleventy development server.
|
||||
eleventy:
|
||||
build:
|
||||
context: .
|
||||
target: development # Use the 'development' stage from the Dockerfile
|
||||
# Adding `init: true` ensures that the container's main process receives
|
||||
# signals correctly (like SIGINT/SIGTERM) when you stop the container.
|
||||
# This helps the dev server to shut down gracefully.
|
||||
init: true
|
||||
container_name: eleventy_dev
|
||||
ports:
|
||||
- "9229:9229" # Node.js debugger port
|
||||
- "8080:8080" # Eleventy dev server port
|
||||
volumes:
|
||||
# Mount the project directory for live-reloading.
|
||||
# The anonymous volume for node_modules prevents the local one from overwriting the container's.
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
networks:
|
||||
# Both services need to be on the same network for the Eleventy dev server
|
||||
# to proxy requests to the API container using its service name ('api').
|
||||
- dev_network
|
||||
# This command runs Eleventy's dev server with file watching.
|
||||
command: npm run debug
|
||||
|
||||
# This service runs your Express API server.
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
target: development # Use the same 'development' stage
|
||||
# Adding `init: true` is especially important for debugging. It ensures
|
||||
# the Node.js process receives shutdown signals, allowing the debugger
|
||||
# to detach cleanly.
|
||||
init: true
|
||||
container_name: api_dev
|
||||
# The API port does not need to be exposed to the host. The 'eleventy'
|
||||
# service proxies requests to it over the internal Docker network.
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
networks:
|
||||
- dev_network
|
||||
# Use Node's built-in --watch mode instead of nodemon. It can be more
|
||||
# stable inside Docker and avoids some of nodemon's complexities. The
|
||||
# --inspect flag has been moved to the eleventy service.
|
||||
command: node --watch src/server.js
|
||||
|
||||
networks:
|
||||
dev_network:
|
||||
driver: bridge
|
@@ -1,29 +1,60 @@
|
||||
# docker-compose.yml for production
|
||||
# This setup builds and runs the optimized production image.
|
||||
# docker-compose.dev.yml for development
|
||||
# This setup runs two services:
|
||||
# 1. The Eleventy dev server for live-reloading site changes.
|
||||
# 2. The Express API server for the view counter.
|
||||
#
|
||||
# To update, run: docker compose build
|
||||
# To start both, run: docker compose -f docker-compose.dev.yml up
|
||||
#
|
||||
# Your site will be available at http://localhost:8080.
|
||||
# API requests are proxied from /api to the API service, so you don't need to access port 3000 directly.
|
||||
services:
|
||||
app:
|
||||
# This service runs the Eleventy development server.
|
||||
eleventy:
|
||||
build:
|
||||
context: .
|
||||
target: production # Use the 'production' stage from the Dockerfile
|
||||
platform: linux/arm64
|
||||
container_name: eleventy_prod
|
||||
target: development # Use the 'development' stage from the Dockerfile
|
||||
# Adding `init: true` ensures that the container's main process receives
|
||||
# signals correctly (like SIGINT/SIGTERM) when you stop the container.
|
||||
# This helps the dev server to shut down gracefully.
|
||||
init: true
|
||||
container_name: eleventy_dev
|
||||
ports:
|
||||
- "9229:9229" # Node.js debugger port
|
||||
- "8080:8080" # Eleventy dev server port
|
||||
volumes:
|
||||
# Persist the view count data in a named volume.
|
||||
- data:/app/_data
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
diun.enable: true
|
||||
homepage.group: Tools
|
||||
homepage.name: 11ty Website
|
||||
homepage.icon: https://jesus.twk95.com/android-chrome-192x192.png
|
||||
homepage.href: ${APP_URL}
|
||||
# Mount the project directory for live-reloading.
|
||||
# The anonymous volume for node_modules prevents the local one from overwriting the container's.
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
networks:
|
||||
- proxy
|
||||
volumes:
|
||||
data: null
|
||||
# Both services need to be on the same network for the Eleventy dev server
|
||||
# to proxy requests to the API container using its service name ('api').
|
||||
- dev_network
|
||||
# This command runs Eleventy's dev server with file watching.
|
||||
command: npm run debug
|
||||
|
||||
# This service runs your Express API server.
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
target: development # Use the same 'development' stage
|
||||
# Adding `init: true` is especially important for debugging. It ensures
|
||||
# the Node.js process receives shutdown signals, allowing the debugger
|
||||
# to detach cleanly.
|
||||
init: true
|
||||
container_name: api_dev
|
||||
# The API port does not need to be exposed to the host. The 'eleventy'
|
||||
# service proxies requests to it over the internal Docker network.
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
networks:
|
||||
- dev_network
|
||||
# Use Node's built-in --watch mode instead of nodemon. It can be more
|
||||
# stable inside Docker and avoids some of nodemon's complexities. The
|
||||
# --inspect flag has been moved to the eleventy service.
|
||||
command: node --watch src/server.js
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
dev_network:
|
||||
driver: bridge
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#!/bin/sh
|
||||
# This script is used as the container's entrypoint.
|
||||
# It ensures that the /app/_data directory (mounted as a volume)
|
||||
# is owned by the non-root 'appuser', so the application can write to it.
|
||||
# is owned by the non-root 'node' user, so the application can write to it.
|
||||
|
||||
set -e
|
||||
|
||||
# Fix ownership of the data volume and execute the main command
|
||||
chown -R appuser:appgroup /app/_data
|
||||
exec su-exec appuser "$@"
|
||||
# Fix ownership of the data volume and execute the main command as the 'node' user
|
||||
chown -R node:node /app/_data
|
||||
exec su-exec node "$@"
|
||||
|
Reference in New Issue
Block a user