-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathContainerfile
More file actions
148 lines (123 loc) · 6.29 KB
/
Containerfile
File metadata and controls
148 lines (123 loc) · 6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# vim: set filetype=dockerfile
ARG BUILDER_BASE_IMAGE=registry.access.redhat.com/ubi9/python-312
ARG BUILDER_DNF_COMMAND=dnf
ARG RUNTIME_BASE_IMAGE=registry.access.redhat.com/ubi9/python-312-minimal
ARG RUNTIME_DNF_COMMAND=microdnf
FROM ${BUILDER_BASE_IMAGE} AS builder
ARG BUILDER_DNF_COMMAND=dnf
ARG APP_ROOT=/app-root
ARG LSC_SOURCE_DIR=.
# UV_PYTHON_DOWNLOADS=0 : Disable Python interpreter downloads and use the system interpreter.
# MATURIN_NO_INSTALL_RUST=1 : Disable installation of Rust dependencies by Maturin.
ENV UV_COMPILE_BYTECODE=0 \
UV_LINK_MODE=copy \
UV_PYTHON_DOWNLOADS=0 \
MATURIN_NO_INSTALL_RUST=1
WORKDIR /app-root
USER root
# Install gcc - required by polyleven python package on aarch64
# (dependency of autoevals, no pre-built binary wheels for linux on aarch64)
# cmake and cargo are required by fastuuid, maturin
RUN ${BUILDER_DNF_COMMAND} install -y --nodocs --setopt=keepcache=0 --setopt=tsflags=nodocs gcc gcc-c++ cmake cargo
# Install uv package manager
RUN pip3.12 install "uv>=0.8.15"
# Add explicit files and directories
# (avoid accidental inclusion of local directories or env files or credentials)
COPY ${LSC_SOURCE_DIR}/src ./src
COPY ${LSC_SOURCE_DIR}/pyproject.toml ${LSC_SOURCE_DIR}/LICENSE ${LSC_SOURCE_DIR}/README.md ${LSC_SOURCE_DIR}/uv.lock ${LSC_SOURCE_DIR}/requirements.*.txt ./
# lightspeed-providers:
# Fully hermetic — uses prefetched artifact or pinned commit from GitHub
ARG LIGHTSPEED_PROVIDERS_COMMIT=8576c2172087aa32b8eadfa2140a879dec238f00
RUN set -eux; \
ZIP_PATH="/tmp/lightspeed-providers.zip"; \
EXTRACT_DIR="/tmp/providers"; \
\
# Use hermetic pre-fetched artifact if available, otherwise download pinned commit
if [ -f "/cachi2/output/deps/generic/lightspeed-providers.zip" ]; then \
cp "/cachi2/output/deps/generic/lightspeed-providers.zip" "${ZIP_PATH}"; \
else \
curl -fL --retry 2 --retry-delay 5 "https://github.com/lightspeed-core/lightspeed-providers/archive/${LIGHTSPEED_PROVIDERS_COMMIT}.zip" -o "${ZIP_PATH}"; \
fi; \
\
# Extract zip (stdlib zipfile — no unzip RPM; works on minimal Konflux builders)
mkdir -p "${EXTRACT_DIR}"; \
export ZIP_PATH EXTRACT_DIR; \
ROOT_DIR="$(python3.12 -c 'import os, zipfile; z=zipfile.ZipFile(os.environ["ZIP_PATH"]); print(z.namelist()[0].split("/")[0])')"; \
python3.12 -c 'import os, zipfile; zipfile.ZipFile(os.environ["ZIP_PATH"]).extractall(os.environ["EXTRACT_DIR"])'; \
\
# Move relevant directories into container filesystem
mv "${EXTRACT_DIR}/${ROOT_DIR}/lightspeed_stack_providers" /app-root/; \
mv "${EXTRACT_DIR}/${ROOT_DIR}/resources/external_providers" /app-root/providers.d; \
\
# Cleanup
rm -rf "${ZIP_PATH}" "${EXTRACT_DIR}"
# Bundle additional dependencies for library mode.
# Source cachi2 environment for hermetic builds if available, otherwise use normal installation
# cachi2.env has these env vars:
# PIP_FIND_LINKS=/cachi2/output/deps/pip
# PIP_NO_INDEX=true
RUN if [ -f /cachi2/cachi2.env ]; then \
. /cachi2/cachi2.env && \
uv venv --seed --no-index --find-links ${PIP_FIND_LINKS} && \
. .venv/bin/activate && \
pip install --no-cache-dir --ignore-installed --no-index --find-links ${PIP_FIND_LINKS} --no-deps -r requirements.hashes.wheel.txt -r requirements.hashes.source.txt && \
pip check; \
else \
uv sync --locked --no-dev --group llslibdev; \
fi
# Explicitly remove some packages to mitigate some CVEs
# - GHSA-wj6h-64fc-37mp: python-ecdsa package won't fix it upstream.
# This package is required by python-jose. python-jose supports multiple
# backends. By default it uses python-cryptography package instead of
# python-ecdsa. It is safe to remove python-ecdsa package.
RUN uv pip uninstall ecdsa
# Final image without uv package manager
FROM ${RUNTIME_BASE_IMAGE}
ARG RUNTIME_DNF_COMMAND=microdnf
ARG APP_ROOT=/app-root
WORKDIR /app-root
# PYTHONDONTWRITEBYTECODE 1 : disable the generation of .pyc
# PYTHONUNBUFFERED 1 : force the stdout and stderr streams to be unbuffered
# PYTHONCOERCECLOCALE 0, PYTHONUTF8 1 : skip legacy locales and use UTF-8 mode
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONCOERCECLOCALE=0 \
PYTHONUTF8=1 \
PYTHONIOENCODING=UTF-8 \
LANG=en_US.UTF-8
COPY --from=builder --chown=1001:1001 /app-root /app-root
# this directory is checked by ecosystem-cert-preflight-checks task in Konflux
COPY --from=builder /app-root/LICENSE /licenses/
# Add uv to final image for derived images to add additional dependencies
# with command:
# $ uv pip install <dependency>
# Temporarily disabled due to temp directory issues
# RUN pip3.12 install "uv==0.8.15"
USER root
# Additional tools for derived images
RUN ${RUNTIME_DNF_COMMAND} install -y --nodocs --setopt=keepcache=0 --setopt=tsflags=nodocs jq patch
# Create llama-stack directories for library mode
RUN mkdir -p /opt/app-root/src/.llama/storage /opt/app-root/src/.llama/providers.d && \
chown -R 1001:1001 /opt/app-root/src/.llama
# Create Hugging Face cache directory for embedding models
RUN mkdir -p /opt/app-root/src/.cache/huggingface && \
chown -R 1001:1001 /opt/app-root/src/.cache
# Add executables from .venv to system PATH
ENV PATH="/app-root/.venv/bin:$PATH"
# Library mode: Llama Stack expects external provider configs under a path named providers.d (hardcoded).
# We place them at /app-root/providers.d. YAMLs there reference lightspeed_stack_providers.*, so that package must be on PYTHONPATH.
ENV PYTHONPATH="/app-root"
# Run the application
EXPOSE 8080
ENTRYPOINT ["python3.12", "src/lightspeed_stack.py"]
LABEL vendor="Red Hat, Inc." \
name="lightspeed-core/lightspeed-stack-rhel9" \
com.redhat.component="lightspeed-core/lightspeed-stack" \
cpe="cpe:/a:redhat:lightspeed_core:0.4::el9" \
io.k8s.display-name="Lightspeed Stack" \
summary="A service that provides a REST API for the Lightspeed Core Stack." \
description="Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases." \
io.k8s.description="Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases." \
io.openshift.tags="lightspeed-core,lightspeed-stack,lightspeed"
# no-root user is checked in Konflux
USER 1001