# ---- frontend --------------------------------------------------------------- FROM node:22-alpine AS ui WORKDIR /ui COPY frontend/package.json frontend/package-lock.json* ./ RUN npm ci --no-audit --no-fund 2>/dev/null || npm install --no-audit --no-fund COPY frontend/ . RUN npm run build # ---- backend ---------------------------------------------------------------- FROM python:3.12-slim ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 # curl is what the triage engine shells out to for the Infrahub API. RUN apt-get update \ && apt-get install -y --no-install-recommends curl ca-certificates \ && rm -rf /var/lib/apt/lists/* # Just the Docker *client*, from the official static build. CX-Tools reaches # OpenStack with `docker exec -osc openstack ...`, so with the host's # socket mounted those become sibling containers. The `docker.io` apt package # would drag in the daemon and containerd for a binary we never run. ARG DOCKER_CLI_VERSION=27.3.1 RUN set -eux; \ arch="$(dpkg --print-architecture)"; \ case "$arch" in amd64) dl=x86_64 ;; arm64) dl=aarch64 ;; *) echo "unsupported $arch" >&2; exit 1 ;; esac; \ curl -fsSL "https://download.docker.com/linux/static/stable/${dl}/docker-${DOCKER_CLI_VERSION}.tgz" \ | tar -xz -C /tmp docker/docker; \ mv /tmp/docker/docker /usr/local/bin/docker; \ rm -rf /tmp/docker; \ docker --version WORKDIR /app COPY backend/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY backend/app ./app COPY backend/triagelib ./triagelib COPY --from=ui /ui/dist ./static RUN useradd --uid 10001 --create-home cx && mkdir -p /data && chown -R cx /data /app USER cx ENV CX_STATIC_DIR=/app/static CX_DATABASE_URL=sqlite:////data/cx-triage.db EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=40s \ CMD python -c "import urllib.request;urllib.request.urlopen('http://127.0.0.1:8080/api/health').read()" CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]