Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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