Files
template_001/Dockerfile
SAAC Daemon e349453fbb Document hot-reload workflow for AI agents
Rewrite SAAC_DEPLOYMENT.md to lead with the two-domain model:
- Production (yourapp.<server>.domain.com) — updates on saac deploy
- Hot-reload (yourapp-hot.<server>.domain.com) — auto-rebuilds on git push

Added: recommended dev workflow (push → check hot → deploy to prod),
nodemon.json explanation, development cycle diagram, customization guide.

Updated Dockerfile and docker-compose.yml headers to explain which
container uses which file and reference nodemon.json.
2026-02-18 16:50:06 +01:00

62 lines
2.1 KiB
Docker

# Multi-stage Dockerfile for React + Express application (PRODUCTION container)
# See SAAC_DEPLOYMENT.md for deployment rules and common mistakes.
#
# This Dockerfile is ONLY used by the production container (yourapp.<server>.domain.com).
# The hot-reload container (yourapp-hot.<server>.domain.com) does NOT use this file —
# it mounts your source code directly and uses nodemon.json to watch for changes.
#
# Stage 1 (builder): Installs client deps and builds the React app with Vite.
# Stage 2 (production): Installs server deps only, copies built React output.
#
# The .dockerignore excludes client/dist from the build context — this is
# intentional. The builder stage creates a fresh dist/ inside the container,
# and COPY --from=builder copies it between stages (bypasses .dockerignore).
# --- Stage 1: Build React frontend ---
FROM node:20-alpine AS builder
WORKDIR /app/client
# Install client dependencies first (layer caching — only re-runs if package*.json change)
COPY client/package*.json ./
RUN npm install
# Copy client source and build
COPY client/ ./
RUN npm run build
# --- Stage 2: Production server ---
FROM node:20-alpine
ARG SOURCE_COMMIT=unknown
ARG APP_VERSION=1.0.0
WORKDIR /app
# curl is required for the Docker healthcheck below
RUN apk add --no-cache curl
# Install server dependencies only (not devDependencies — they're not needed in production).
# If your app needs devDependencies for a build step (e.g. TypeScript), install ALL deps
# first, run the build, then prune: RUN npm install && npm run build && npm prune --production
COPY package*.json ./
RUN npm install --production
# Copy server code
COPY server.js ./
# Copy built React app from the builder stage (not from host — .dockerignore doesn't apply)
COPY --from=builder /app/client/dist ./client/dist
ENV GIT_COMMIT=${SOURCE_COMMIT} \
APP_VERSION=${APP_VERSION}
# Use "expose" in docker-compose.yml, not "ports". This EXPOSE is just documentation.
EXPOSE 3000
# Healthcheck — must match the healthcheck in docker-compose.yml
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=2 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "server.js"]