Skip to content

Commit bb36798

Browse files
committed
🚧 containerfile has an option to remove some providers based on a provider-list
1 parent 5a44dff commit bb36798

File tree

4 files changed

+132
-38
lines changed

4 files changed

+132
-38
lines changed

Dockerfile.server

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
1-
FROM python:3.11-slim
2-
3-
# System dependencies
4-
RUN apt-get update && apt-get install -y gcc g++ git curl \
5-
&& rm -rf /var/lib/apt/lists/*
1+
FROM registry.access.redhat.com/ubi9/python-312 as build
62

3+
USER 0
74
WORKDIR /app
85

9-
# Install Poetry
10-
RUN pip install --no-cache-dir poetry
6+
RUN dnf install -y gcc gcc-c++ git && \
7+
pip install --no-cache-dir poetry==1.8.2 pyyaml==6.0.2 && \
8+
dnf clean all && \
9+
rm -rf /var/cache/dnf
1110

12-
# Copy project files
1311
COPY pyproject.toml poetry.lock* README.md ./
12+
COPY nemoguardrails/ ./nemoguardrails/
1413
COPY examples/ ./examples/
1514
COPY chat-ui/ ./chat-ui/
16-
COPY nemoguardrails/ ./nemoguardrails/
17-
COPY scripts/ ./scripts/
15+
COPY scripts/provider-list.yaml ./scripts/
16+
COPY scripts/filter_guardrails.py ./scripts/
17+
COPY scripts/entrypoint.sh ./scripts/
1818
RUN chmod +x ./scripts/entrypoint.sh
1919

20-
# Create non-root user and set permissions
21-
RUN useradd --create-home guardrails && \
22-
mkdir -p /app/config && \
23-
mkdir -p /app/.cache/pypoetry && \
24-
chown -R guardrails:guardrails /app
20+
ARG GUARDRAILS_PROFILE=opensource
21+
RUN python3 ./scripts/filter_guardrails.py ./scripts/provider-list.yaml $GUARDRAILS_PROFILE
2522

26-
USER guardrails
23+
ENV POETRY_VIRTUALENVS_IN_PROJECT=1 \
24+
POETRY_NO_INTERACTION=1
2725

28-
# Set Poetry cache and virtualenvs path
29-
ENV POETRY_CACHE_DIR=/app/.cache/pypoetry
30-
ENV POETRY_VIRTUALENVS_PATH=/app/.cache/pypoetry/virtualenvs
26+
RUN poetry install --no-ansi --extras="sdd jailbreak openai nvidia tracing" && \
27+
poetry run pip install "spacy>=3.4.4,<4.0.0" && \
28+
poetry run python -m spacy download en_core_web_lg
3129

32-
# Install all dependencies (main + extras) as non-root user
33-
RUN poetry install --no-interaction --no-ansi --all-extras
34-
RUN poetry run python -m spacy download en_core_web_lg
30+
FROM registry.access.redhat.com/ubi9/python-312
3531

36-
EXPOSE 8000
32+
USER 0
33+
WORKDIR /app
34+
35+
COPY --from=build /app /app
36+
RUN rm -f /etc/security/namespace.conf /usr/lib64/security/pam_namespace.so || true && \
37+
chgrp -R 0 /app && \
38+
chmod -R g+rwX /app
3739

40+
USER 1001
41+
42+
ENV PATH="/app/.venv/bin:$PATH"
43+
EXPOSE 8000
3844
ENTRYPOINT ["./scripts/entrypoint.sh"]

scripts/entrypoint.sh

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,27 @@
11
#!/bin/bash
22

33
# Allow runtime overrides via env vars or args
4-
CONFIG_ID="${CONFIG_ID:-$1}"
5-
PORT="${PORT:-$2}"
6-
7-
# Set defaults if not provided
8-
CONFIG_ID="${CONFIG_ID:-nemo}"
9-
PORT="${PORT:-8000}"
4+
CONFIG_ID="${CONFIG_ID:-${1:-nemo}}"
5+
PORT="${PORT:-${2:-8000}}"
106

117
CONFIG_DIR="/app/config/${CONFIG_ID}"
128

139
echo "🚀 Starting NeMo Guardrails with config from: $CONFIG_DIR (port: $PORT)"
1410

1511
# Validate config exists
1612
if [[ ! -f "$CONFIG_DIR/config.yaml" ]]; then
17-
echo "❌ ERROR: config.yaml not found in $CONFIG_DIR"
18-
exit 1
13+
echo "❌ ERROR: config.yaml not found in $CONFIG_DIR"
14+
exit 1
1915
fi
2016

21-
# Do NOT attempt to create rails.co if missing (ConfigMap is read-only)
2217
if [[ ! -f "$CONFIG_DIR/rails.co" ]]; then
23-
echo "❌ ERROR: rails.co not found in $CONFIG_DIR (ConfigMap is read-only, please provide it)"
24-
exit 1
18+
echo "❌ ERROR: rails.co not found in $CONFIG_DIR (ConfigMap is read-only, please provide it)"
19+
exit 1
2520
fi
2621

2722
echo "✅ Configuration validated. Starting server..."
28-
exec poetry run nemoguardrails server \
29-
--config "/app/config" \
30-
--port "$PORT" \
31-
--default-config-id "$CONFIG_ID"
23+
exec /app/.venv/bin/nemoguardrails server \
24+
--config "/app/config" \
25+
--port "$PORT" \
26+
--default-config-id "$CONFIG_ID" \
27+
--disable-chat-ui

scripts/filter_guardrails.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import sys
4+
import yaml
5+
import shutil
6+
import logging
7+
from pathlib import Path
8+
9+
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
10+
logger = logging.getLogger(__name__)
11+
12+
13+
def main():
14+
if len(sys.argv) != 3:
15+
logger.error("Usage: filter_guardrails.py <config-file> <profile>")
16+
sys.exit(1)
17+
18+
config_file = sys.argv[1]
19+
profile = sys.argv[2]
20+
21+
# Load configuration
22+
with open(config_file, "r") as f:
23+
config = yaml.safe_load(f)
24+
25+
if profile not in config["profiles"]:
26+
logger.error(
27+
f"Profile '{profile}' not found. Available: {list(config['profiles'].keys())}"
28+
)
29+
sys.exit(1)
30+
31+
include_closed_source = config["profiles"][profile]["include_closed_source"]
32+
closed_source_list = config["closed_source_guardrails"]
33+
34+
logger.info(f"Profile: {profile}")
35+
logger.info(f"Description: {config['profiles'][profile]['description']}")
36+
37+
library_path = Path("./nemoguardrails/library")
38+
if not library_path.exists():
39+
logger.error(f"Library path {library_path} does not exist")
40+
sys.exit(1)
41+
42+
kept_dirs = []
43+
removed_dirs = []
44+
45+
for guardrail_dir in library_path.iterdir():
46+
if (
47+
not guardrail_dir.is_dir()
48+
or guardrail_dir.name.startswith(".")
49+
or guardrail_dir.name.startswith("__")
50+
):
51+
continue
52+
53+
guardrail_name = guardrail_dir.name
54+
is_closed_source = guardrail_name in closed_source_list
55+
56+
if is_closed_source and not include_closed_source:
57+
logger.info(f"Removing closed source: {guardrail_name}")
58+
shutil.rmtree(guardrail_dir)
59+
removed_dirs.append(guardrail_name)
60+
else:
61+
source_type = "closed source" if is_closed_source else "open source"
62+
logger.info(f"Keeping {source_type}: {guardrail_name}")
63+
kept_dirs.append(guardrail_name)
64+
65+
logger.info(
66+
f"\nSummary: kept {len(kept_dirs)}, removed {len(removed_dirs)} guardrails"
67+
)
68+
69+
70+
if __name__ == "__main__":
71+
main()

scripts/provider-list.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Build time guardrails selection
2+
profiles:
3+
opensource:
4+
description: "Open source guardrails only"
5+
include_closed_source: false
6+
7+
all:
8+
description: "All available guardrails (open + closed source)"
9+
include_closed_source: true
10+
11+
# Define which guardrails are closed source (everything else is considered open source)
12+
closed_source_guardrails:
13+
- "activefence"
14+
- "cleanlab"
15+
- "clavata"
16+
- "privateai"
17+
- "fiddler"
18+
- "patronusai"
19+
- "clavata"
20+
- "prompt_security"
21+
- "gcp_moderate_text"

0 commit comments

Comments
 (0)