Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 10 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Hadolint configuration for Opik's Dockerfiles.
# Runs on every PR via the `hadolint` hook in .pre-commit-config.yaml (and the
# unified πŸ™ Code Quality workflow), and locally through `make precommit`.
#
# The default rule set is used as-is: every Dockerfile in the repo lints clean
# against it. The few genuinely-undesirable rules (pinning rolling-channel OS
# packages, which would rot as base-image repos update) are suppressed inline,
# per-line, with a reason β€” not globally here β€” so the suppression stays visible
# next to the code it applies to and no new violation is silently swallowed.
failure-threshold: info
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,19 @@ repos:
# when a workflow that `uses:` them is linted. Matches actionlint's own
# default files pattern.
files: ^\.github/workflows/.+\.(yml|yaml)$

# ---------------------------------------------------------------------------
# Dockerfiles β€” hadolint. The docker-image hook needs only Docker (no local
# binary), matching CI runners. Config + baselined exceptions live in the
# repo-root .hadolint.yaml, which hadolint reads automatically.
# ---------------------------------------------------------------------------
- repo: https://github.com/hadolint/hadolint
rev: v2.14.0
hooks:
- id: hadolint-docker
name: 🐳 hadolint β€” dockerfiles
# Explicit files: regex (not the upstream `types: [dockerfile]`) so the
# CI matrix builder in scripts/precommit-detect-hooks.py can route a
# changed Dockerfile to this leg β€” it matches on paths, not content type.
files: (^|/)Dockerfile(\..+)?$
...
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Please review the CLA before contributing:
## GitHub Actions workflows
Workflow files in `.github/workflows/` are validated with [actionlint](https://github.com/rhysd/actionlint), which runs as a hook in the unified `πŸ™ Code Quality` workflow (and locally via pre-commit) on changed workflow files. The pre-commit framework builds the pinned actionlint from source automatically β€” no manual install needed. Run `make hooks` once per clone to enable it locally.

## Dockerfiles
Dockerfiles are linted with [hadolint](https://github.com/hadolint/hadolint), which runs as a hook in the unified `πŸ™ Code Quality` workflow (and locally via pre-commit) on changed Dockerfiles. It uses hadolint's default rule set; project-wide config lives in `.hadolint.yaml` at the repo root, and the handful of intentionally-suppressed rules are annotated inline with a reason. The hook runs hadolint via its Docker image, so it needs only Docker β€” no manual install. To run it directly on a single file: `docker run --rm -i ghcr.io/hadolint/hadolint < path/to/Dockerfile`.

## Generated files (do not edit manually)
- `apps/opik-backend/src/main/resources/model_prices_and_context_window.json`
- `apps/opik-frontend/src/data/model_prices_and_context_window.json`
Expand Down
5 changes: 5 additions & 0 deletions apps/opik-backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ COPY install_rds_cert.sh /tmp/install_rds_cert.sh
# perl is intentionally not installed: it pulls in perl-Archive-Tar, which is
# affected by CVE-2026-9538 (ALAS2023-2026-1805) and has no patched AL2023 RPM.
# install_rds_cert.sh uses sed/openssl instead of perl to extract the cert CN.
# pipefail so the `sha256sum -c` failing inside the piped RUN below aborts the build.
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# DL3033: AL2023 core packages track a rolling security channel; pinning exact
# RPM versions here would rot as AWS updates the base image's repos.
# hadolint ignore=DL3033
RUN yum update -y && \
yum install -y --allowerasing shadow ca-certificates openssl dos2unix curl && \
yum clean all && \
Expand Down
6 changes: 2 additions & 4 deletions apps/opik-frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ ENV NODE_OPTIONS="--max-old-space-size=8192"
ARG BUILD_MODE=production
ARG BUILD_PLUGINS
ENV VITE_FE_PLUGINS=${BUILD_PLUGINS}
RUN npm run build -- --mode $BUILD_MODE

# Create version.json for checking version
RUN printf '{"version": "%s"}\n' "$VITE_APP_VERSION" > dist/version.json
RUN npm run build -- --mode $BUILD_MODE \
&& printf '{"version": "%s"}\n' "$VITE_APP_VERSION" > dist/version.json

# Production stage
# Using nginx alpine image with OpenTelemetry support
Expand Down
20 changes: 13 additions & 7 deletions apps/opik-guardrails-backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ ENV PYTHONUNBUFFERED=1 \
OPIK_GUARDRAILS_DEVICE=cuda:0

# Install Python and other dependencies
# DL3008: Ubuntu apt packages track a rolling security channel; pinning exact
# versions here would rot as the base image's repos are updated.
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
python3.10 \
python3-pip \
Expand All @@ -22,8 +25,11 @@ RUN ln -sf /usr/bin/python3.10 /usr/bin/python && \
WORKDIR /opt/opik-guardrails-backend

COPY requirements.txt .
RUN pip install --no-cache-dir -U pip
RUN pip install --no-cache-dir --disable-pip-version-check -r requirements.txt
# DL3013: pip itself is upgraded to latest by design; requirements.txt pins the
# actual dependency versions.
# hadolint ignore=DL3013
RUN pip install --no-cache-dir -U pip && \
pip install --no-cache-dir --disable-pip-version-check -r requirements.txt

COPY entrypoint.sh .
RUN chmod u+x entrypoint.sh
Expand All @@ -33,13 +39,13 @@ RUN chmod u+x entrypoint.sh
RUN mkdir /.cache/ /.local/ && chown -R 1001:1001 /opt/opik-guardrails-backend /.cache/ /.local/
USER 1001:1001

# Download spaCy model for PII detection
RUN python -m spacy download en_core_web_lg

# Download transformer model for restricted topic validation
# Download models with the final user so files land readable by the user:
# - spaCy en_core_web_lg for PII detection
# - transformer bart-large-mnli for restricted topic validation
# HF_HUB_DISABLE_XET=1 forces standard HTTP fallback; the Xet protocol
# used by huggingface_hub[hf_xet] is blocked in most CI/Docker build environments.
RUN HF_HUB_DISABLE_XET=1 python -c "from transformers import AutoModelForSequenceClassification, AutoTokenizer; AutoModelForSequenceClassification.from_pretrained('facebook/bart-large-mnli'); AutoTokenizer.from_pretrained('facebook/bart-large-mnli')"
RUN python -m spacy download en_core_web_lg && \
HF_HUB_DISABLE_XET=1 python -c "from transformers import AutoModelForSequenceClassification, AutoTokenizer; AutoModelForSequenceClassification.from_pretrained('facebook/bart-large-mnli'); AutoTokenizer.from_pretrained('facebook/bart-large-mnli')"

COPY --chown=1001:1001 opik_guardrails ./opik_guardrails

Expand Down
16 changes: 11 additions & 5 deletions apps/opik-python-backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
#######################################################################
FROM docker:29.5.1 AS builder

# Alpine base ships /bin/ash, not bash; ash honors -o pipefail for the RUN
# below whose pipe into xargs would otherwise mask a failing find.
SHELL ["/bin/ash", "-o", "pipefail", "-c"]

# Toolchain only for compiling native wheels (rust/cargo for pydantic-core).
# hadolint ignore=DL3018
RUN apk add --no-cache python3 py3-pip build-base python3-dev musl-dev gcc libffi-dev rust cargo

WORKDIR /opt/opik-python-backend
Expand All @@ -26,7 +31,7 @@ RUN set -eux; \
find "$PY_SITE" \
-path "$PY_SITE/datasets/*" -prune -o \
-path "$PY_SITE/opik_optimizer/*" -prune -o \
-name '*.py' -type f -print | xargs -r rm -f; \
-name '*.py' -type f -print0 | xargs -0 -r rm -f; \
find "$PY_SITE" -type d -name '__pycache__' -prune -exec rm -rf {} +; \
find "$PY_SITE" -name '*.pyi' -delete; \
pip uninstall -y pip setuptools wheel || true; \
Expand All @@ -37,10 +42,11 @@ RUN set -eux; \
#######################################################################
FROM docker:29.5.1

# Upgrade libexpat to the latest available version to mitigate CVEs.
RUN apk add --no-cache --upgrade libexpat
# Runtime-only OS deps: tini (PID 1 reaper) + python3 interpreter.
RUN apk add --no-cache tini python3
# libexpat --upgrade mitigates CVEs; tini (PID 1 reaper) + python3 are the
# runtime-only OS deps.
# hadolint ignore=DL3018
RUN apk add --no-cache --upgrade libexpat && \
apk add --no-cache tini python3

WORKDIR /opt/opik-python-backend

Expand Down
Loading