diff --git a/Dockerfile b/Dockerfile index 02f0cd9..ea27a14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,34 @@ -# ---------- build stage ---------- -FROM node:22-alpine AS build +# ---------- Stage 1: builder ---------- +FROM node:24-bookworm-slim AS builder + +# Optional: pin the range42-deployer CLI to a specific version (e.g. --build-arg DEPLOYER_CLI_VERSION=1.2.3) +ARG DEPLOYER_CLI_VERSION WORKDIR /app +# Install Python + venv toolchain (venv is required on Debian bookworm — PEP 668 blocks system-level pip installs) +RUN apt-get update \ + && apt-get install -y --no-install-recommends python3 python3-pip python3-venv \ + && rm -rf /var/lib/apt/lists/* + +# Install the range42-deployer CLI into an isolated venv +RUN python3 -m venv /opt/deployer-env \ + && /opt/deployer-env/bin/pip install --no-cache-dir \ + "range42-deployer${DEPLOYER_CLI_VERSION:+==${DEPLOYER_CLI_VERSION}}" + +ENV PATH="/opt/deployer-env/bin:${PATH}" + +# Install Node dependencies and build the production bundle COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build -# ---------- serve stage ---------- -FROM nginx:stable-alpine +# ---------- Stage 2: runtime ---------- +FROM nginx:stable-bookworm AS runtime -COPY --from=build /app/dist /usr/share/nginx/html +COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx/default.conf /etc/nginx/conf.d/default.conf EXPOSE 80 diff --git a/README.md b/README.md index 6129638..7c9af83 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,44 @@ The UI is available at `http://localhost:3000` (configurable via `UI_PORT` in `. Configure the backend API URL in the settings modal once the app is running. +### Docker: Build & Push + +The multi-stage `Dockerfile` uses **Debian stable (bookworm)** for both the builder and runtime stages. +Stage 1 installs the `range42-deployer` CLI into a Python venv before running the npm production build. +Stage 2 serves the compiled SPA with nginx. + +**Build locally and validate:** + +```bash +# Build and start (image tested via the /health endpoint) +docker compose up --build + +# Confirm the container is healthy +docker compose ps +``` + +**Build and tag for a registry:** + +```bash +IMAGE=ghcr.io/range42/range42-deployer-ui +TAG=$(git rev-parse --short HEAD) + +docker build -t "${IMAGE}:${TAG}" -t "${IMAGE}:latest" . +``` + +**Pin a specific deployer CLI version (optional):** + +```bash +docker build --build-arg DEPLOYER_CLI_VERSION=1.2.3 -t "${IMAGE}:${TAG}" . +``` + +**Push to the registry:** + +```bash +docker push "${IMAGE}:${TAG}" +docker push "${IMAGE}:latest" +``` + ### Development ```bash diff --git a/docker-compose.yml b/docker-compose.yml index e6196bc..2c4d165 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,3 +4,9 @@ services: ports: - "${UI_PORT:-3000}:80" restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost/health"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s