Add back in non root image fixes (#7781) (#7795)

* Add back in non root image fixes (#7781)

* Add back in non root image fixes

* Fix dockerfile

* Fix perms

* Add in container structure tests for the nonroot image (#7796)

* feat(helm): add securityContext and pull policy values to migration job (#7652)

* fix(helm): corrected indentation in migration-job.yaml

* feat(helm): add securityContext and pull policy values to migration job

* fix confusing save button label (#7778)

* [integrations/lunary] Improve Lunary documentaiton (#7770)

* update lunary doc

* better title

* tweaks

* Update langchain.md

* Update lunary_integration.md

* Fix wrong URL for internal user invitation (#7762)

* format

* done

* Update instructor tutorial (#7784)

* Add in container structure tests for the nonroot image

---------

Co-authored-by: Zackeus Bengtsson <32719220+Hexoplon@users.noreply.github.com>
Co-authored-by: yujonglee <yujonglee.dev@gmail.com>
Co-authored-by: Hugues Chocart <chocart.hugues@icloud.com>
Co-authored-by: Nikolaiev Dmytro <dima.nikol.99@gmail.com>

---------

Co-authored-by: Rajat Vig <rajatvig@users.noreply.github.com>
Co-authored-by: Zackeus Bengtsson <32719220+Hexoplon@users.noreply.github.com>
Co-authored-by: yujonglee <yujonglee.dev@gmail.com>
Co-authored-by: Hugues Chocart <chocart.hugues@icloud.com>
Co-authored-by: Nikolaiev Dmytro <dima.nikol.99@gmail.com>
This commit is contained in:
Krish Dholakia 2025-01-15 21:49:03 -08:00 committed by GitHub
parent 80d6bbec29
commit d4ed985173
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 128 additions and 77 deletions

View file

@ -47,9 +47,9 @@ jobs:
pip install opentelemetry-api==1.25.0 pip install opentelemetry-api==1.25.0
pip install opentelemetry-sdk==1.25.0 pip install opentelemetry-sdk==1.25.0
pip install opentelemetry-exporter-otlp==1.25.0 pip install opentelemetry-exporter-otlp==1.25.0
pip install openai==1.54.0 pip install openai==1.54.0
pip install prisma==0.11.0 pip install prisma==0.11.0
pip install "detect_secrets==1.5.0" pip install "detect_secrets==1.5.0"
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "respx==0.21.1" pip install "respx==0.21.1"
pip install fastapi pip install fastapi
@ -165,9 +165,9 @@ jobs:
pip install opentelemetry-api==1.25.0 pip install opentelemetry-api==1.25.0
pip install opentelemetry-sdk==1.25.0 pip install opentelemetry-sdk==1.25.0
pip install opentelemetry-exporter-otlp==1.25.0 pip install opentelemetry-exporter-otlp==1.25.0
pip install openai==1.54.0 pip install openai==1.54.0
pip install prisma==0.11.0 pip install prisma==0.11.0
pip install "detect_secrets==1.5.0" pip install "detect_secrets==1.5.0"
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "respx==0.21.1" pip install "respx==0.21.1"
pip install fastapi pip install fastapi
@ -264,9 +264,9 @@ jobs:
pip install opentelemetry-api==1.25.0 pip install opentelemetry-api==1.25.0
pip install opentelemetry-sdk==1.25.0 pip install opentelemetry-sdk==1.25.0
pip install opentelemetry-exporter-otlp==1.25.0 pip install opentelemetry-exporter-otlp==1.25.0
pip install openai==1.54.0 pip install openai==1.54.0
pip install prisma==0.11.0 pip install prisma==0.11.0
pip install "detect_secrets==1.5.0" pip install "detect_secrets==1.5.0"
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "respx==0.21.1" pip install "respx==0.21.1"
pip install fastapi pip install fastapi
@ -367,7 +367,7 @@ jobs:
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
- persist_to_workspace: - persist_to_workspace:
root: . root: .
paths: paths:
@ -375,10 +375,10 @@ jobs:
- auth_ui_unit_tests_coverage - auth_ui_unit_tests_coverage
litellm_router_testing: # Runs all tests with the "router" keyword litellm_router_testing: # Runs all tests with the "router" keyword
docker: docker:
- image: cimg/python:3.11 - image: cimg/python:3.11
auth: auth:
username: ${DOCKERHUB_USERNAME} username: ${DOCKERHUB_USERNAME}
password: ${DOCKERHUB_PASSWORD} password: ${DOCKERHUB_PASSWORD}
working_directory: ~/project working_directory: ~/project
steps: steps:
@ -417,10 +417,10 @@ jobs:
- litellm_router_coverage - litellm_router_coverage
litellm_proxy_unit_testing: # Runs all tests with the "proxy", "key", "jwt" filenames litellm_proxy_unit_testing: # Runs all tests with the "proxy", "key", "jwt" filenames
docker: docker:
- image: cimg/python:3.11 - image: cimg/python:3.11
auth: auth:
username: ${DOCKERHUB_USERNAME} username: ${DOCKERHUB_USERNAME}
password: ${DOCKERHUB_PASSWORD} password: ${DOCKERHUB_PASSWORD}
working_directory: ~/project working_directory: ~/project
steps: steps:
- checkout - checkout
@ -458,9 +458,9 @@ jobs:
pip install opentelemetry-api==1.25.0 pip install opentelemetry-api==1.25.0
pip install opentelemetry-sdk==1.25.0 pip install opentelemetry-sdk==1.25.0
pip install opentelemetry-exporter-otlp==1.25.0 pip install opentelemetry-exporter-otlp==1.25.0
pip install openai==1.54.0 pip install openai==1.54.0
pip install prisma==0.11.0 pip install prisma==0.11.0
pip install "detect_secrets==1.5.0" pip install "detect_secrets==1.5.0"
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "respx==0.21.1" pip install "respx==0.21.1"
pip install fastapi pip install fastapi
@ -514,10 +514,10 @@ jobs:
- litellm_proxy_unit_tests_coverage - litellm_proxy_unit_tests_coverage
litellm_assistants_api_testing: # Runs all tests with the "assistants" keyword litellm_assistants_api_testing: # Runs all tests with the "assistants" keyword
docker: docker:
- image: cimg/python:3.11 - image: cimg/python:3.11
auth: auth:
username: ${DOCKERHUB_USERNAME} username: ${DOCKERHUB_USERNAME}
password: ${DOCKERHUB_PASSWORD} password: ${DOCKERHUB_PASSWORD}
working_directory: ~/project working_directory: ~/project
steps: steps:
@ -616,7 +616,7 @@ jobs:
command: | command: |
mv coverage.xml llm_translation_coverage.xml mv coverage.xml llm_translation_coverage.xml
mv .coverage llm_translation_coverage mv .coverage llm_translation_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -660,7 +660,7 @@ jobs:
command: | command: |
mv coverage.xml batches_coverage.xml mv coverage.xml batches_coverage.xml
mv .coverage batches_coverage mv .coverage batches_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -704,7 +704,7 @@ jobs:
command: | command: |
mv coverage.xml secret_manager_coverage.xml mv coverage.xml secret_manager_coverage.xml
mv .coverage secret_manager_coverage mv .coverage secret_manager_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -747,7 +747,7 @@ jobs:
command: | command: |
mv coverage.xml pass_through_unit_tests_coverage.xml mv coverage.xml pass_through_unit_tests_coverage.xml
mv .coverage pass_through_unit_tests_coverage mv .coverage pass_through_unit_tests_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -789,7 +789,7 @@ jobs:
command: | command: |
mv coverage.xml image_gen_coverage.xml mv coverage.xml image_gen_coverage.xml
mv .coverage image_gen_coverage mv .coverage image_gen_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -835,7 +835,7 @@ jobs:
command: | command: |
mv coverage.xml logging_coverage.xml mv coverage.xml logging_coverage.xml
mv .coverage logging_coverage mv .coverage logging_coverage
# Store test results # Store test results
- store_test_results: - store_test_results:
path: test-results path: test-results
@ -875,7 +875,7 @@ jobs:
pwd pwd
ls ls
python -m pytest -vv tests/local_testing/test_basic_python_version.py python -m pytest -vv tests/local_testing/test_basic_python_version.py
installing_litellm_on_python_3_13: installing_litellm_on_python_3_13:
docker: docker:
- image: cimg/python:3.13.1 - image: cimg/python:3.13.1
@ -1039,7 +1039,7 @@ jobs:
cat docker_output.log cat docker_output.log
exit 1 exit 1
fi fi
build_and_test: build_and_test:
machine: machine:
image: ubuntu-2204:2023.10.1 image: ubuntu-2204:2023.10.1
@ -1085,9 +1085,9 @@ jobs:
pip install "langfuse>=2.0.0" pip install "langfuse>=2.0.0"
pip install "logfire==0.29.0" pip install "logfire==0.29.0"
pip install numpydoc pip install numpydoc
pip install prisma pip install prisma
pip install fastapi pip install fastapi
pip install jsonschema pip install jsonschema
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "gunicorn==21.2.0" pip install "gunicorn==21.2.0"
pip install "anyio==3.7.1" pip install "anyio==3.7.1"
@ -1203,9 +1203,9 @@ jobs:
pip install "langfuse>=2.0.0" pip install "langfuse>=2.0.0"
pip install "logfire==0.29.0" pip install "logfire==0.29.0"
pip install numpydoc pip install numpydoc
pip install prisma pip install prisma
pip install fastapi pip install fastapi
pip install jsonschema pip install jsonschema
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "gunicorn==21.2.0" pip install "gunicorn==21.2.0"
pip install "anyio==3.7.1" pip install "anyio==3.7.1"
@ -1322,9 +1322,9 @@ jobs:
pip install "langfuse>=2.0.0" pip install "langfuse>=2.0.0"
pip install "logfire==0.29.0" pip install "logfire==0.29.0"
pip install numpydoc pip install numpydoc
pip install prisma pip install prisma
pip install fastapi pip install fastapi
pip install jsonschema pip install jsonschema
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "gunicorn==21.2.0" pip install "gunicorn==21.2.0"
pip install "anyio==3.7.1" pip install "anyio==3.7.1"
@ -1387,8 +1387,9 @@ jobs:
pwd pwd
ls ls
python -m pytest -vv tests/otel_tests -x --junitxml=test-results/junit.xml --durations=5 python -m pytest -vv tests/otel_tests -x --junitxml=test-results/junit.xml --durations=5
no_output_timeout: 120m no_output_timeout:
# Clean up first container 120m
# Clean up first container
- run: - run:
name: Stop and remove first container name: Stop and remove first container
command: | command: |
@ -1524,8 +1525,9 @@ jobs:
name: Run tests name: Run tests
command: | command: |
python -m pytest -vv tests/basic_proxy_startup_tests -x --junitxml=test-results/junit-2.xml --durations=5 python -m pytest -vv tests/basic_proxy_startup_tests -x --junitxml=test-results/junit-2.xml --durations=5
no_output_timeout: 120m no_output_timeout:
# Clean up first container 120m
# Clean up first container
- run: - run:
name: Stop and remove first container name: Stop and remove first container
command: | command: |
@ -1572,9 +1574,9 @@ jobs:
pip install mypy pip install mypy
pip install pyarrow pip install pyarrow
pip install numpydoc pip install numpydoc
pip install prisma pip install prisma
pip install fastapi pip install fastapi
pip install jsonschema pip install jsonschema
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "anyio==3.7.1" pip install "anyio==3.7.1"
pip install "asyncio==3.4.3" pip install "asyncio==3.4.3"
@ -1676,7 +1678,6 @@ jobs:
- codecov/upload: - codecov/upload:
file: ./coverage.xml file: ./coverage.xml
publish_to_pypi: publish_to_pypi:
docker: docker:
- image: cimg/python:3.8 - image: cimg/python:3.8
@ -1703,7 +1704,6 @@ jobs:
circleci step halt circleci step halt
fi fi
- run: - run:
name: Checkout code name: Checkout code
command: git checkout $CIRCLE_SHA1 command: git checkout $CIRCLE_SHA1
@ -1792,9 +1792,9 @@ jobs:
pip install mypy pip install mypy
pip install pyarrow pip install pyarrow
pip install numpydoc pip install numpydoc
pip install prisma pip install prisma
pip install fastapi pip install fastapi
pip install jsonschema pip install jsonschema
pip install "httpx==0.24.1" pip install "httpx==0.24.1"
pip install "anyio==3.7.1" pip install "anyio==3.7.1"
pip install "asyncio==3.4.3" pip install "asyncio==3.4.3"
@ -1845,6 +1845,28 @@ jobs:
- store_test_results: - store_test_results:
path: test-results path: test-results
test_nonroot_image:
machine:
image: ubuntu-2204:2023.10.1
resource_class: xlarge
working_directory: ~/project
steps:
- checkout
- run:
name: Build Docker image
command: |
docker build -t non_root_image:latest . -f ./docker/Dockerfile.non_root
- run:
name: Install Container Structure Test
command: |
curl -LO https://github.com/GoogleContainerTools/container-structure-test/releases/download/v1.19.3/container-structure-test-linux-amd64
chmod +x container-structure-test-linux-amd64
sudo mv container-structure-test-linux-amd64 /usr/local/bin/container-structure-test
- run:
name: Run Container Structure Test
command: |
container-structure-test test --image non_root_image:latest --config docker/tests/nonroot.yaml
test_bad_database_url: test_bad_database_url:
machine: machine:
image: ubuntu-2204:2023.10.1 image: ubuntu-2204:2023.10.1
@ -1910,10 +1932,10 @@ workflows:
- /litellm_.*/ - /litellm_.*/
- litellm_assistants_api_testing: - litellm_assistants_api_testing:
filters: filters:
branches: branches:
only: only:
- main - main
- /litellm_.*/ - /litellm_.*/
- litellm_router_testing: - litellm_router_testing:
filters: filters:
branches: branches:
@ -2086,4 +2108,3 @@ workflows:
branches: branches:
only: only:
- main - main

View file

@ -9,3 +9,4 @@ tests
.devcontainer .devcontainer
*.tgz *.tgz
log.txt log.txt
docker/Dockerfile.*

View file

@ -9,13 +9,16 @@ FROM $LITELLM_BUILD_IMAGE AS builder
# Set the working directory to /app # Set the working directory to /app
WORKDIR /app WORKDIR /app
# Set the shell to bash
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Install build dependencies # Install build dependencies
RUN apt-get clean && apt-get update && \ RUN apt-get clean && apt-get update && \
apt-get install -y gcc python3-dev && \ apt-get install -y gcc python3-dev && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip && \ RUN pip install --no-cache-dir --upgrade pip && \
pip install build pip install --no-cache-dir build
# Copy the current directory contents into the container at /app # Copy the current directory contents into the container at /app
COPY . . COPY . .
@ -39,7 +42,7 @@ RUN pip wheel --no-cache-dir --wheel-dir=/wheels/ -r requirements.txt
FROM $LITELLM_RUNTIME_IMAGE AS runtime FROM $LITELLM_RUNTIME_IMAGE AS runtime
# Update dependencies and clean up - handles debian security issue # Update dependencies and clean up - handles debian security issue
RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*
WORKDIR /app WORKDIR /app
# Copy the current directory contents into the container at /app # Copy the current directory contents into the container at /app
@ -53,34 +56,42 @@ COPY --from=builder /wheels/ /wheels/
# Install the built wheel using pip; again using a wildcard if it's the only file # Install the built wheel using pip; again using a wildcard if it's the only file
RUN pip install *.whl /wheels/* --no-index --find-links=/wheels/ && rm -f *.whl && rm -rf /wheels RUN pip install *.whl /wheels/* --no-index --find-links=/wheels/ && rm -f *.whl && rm -rf /wheels
# install semantic-cache [Experimental]- we need this here and not in requirements.txt because redisvl pins to pydantic 1.0 # install semantic-cache [Experimental]- we need this here and not in requirements.txt because redisvl pins to pydantic 1.0
RUN pip install redisvl==0.0.7 --no-deps
# ensure pyjwt is used, not jwt # ensure pyjwt is used, not jwt
RUN pip uninstall jwt -y RUN pip install redisvl==0.0.7 --no-deps --no-cache-dir && \
RUN pip uninstall PyJWT -y pip uninstall jwt -y && \
RUN pip install PyJWT==2.9.0 --no-cache-dir pip uninstall PyJWT -y && \
pip install PyJWT==2.9.0 --no-cache-dir
# Build Admin UI # Build Admin UI
RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh
# Generate prisma client ### Prisma Handling for Non-Root #################################################
ENV PRISMA_BINARY_CACHE_DIR=/app/prisma # Prisma allows you to specify the binary cache directory to use
RUN mkdir -p /.cache ENV PRISMA_BINARY_CACHE_DIR=/nonexistent
RUN chmod -R 777 /.cache
RUN pip install nodejs-bin RUN pip install --no-cache-dir nodejs-bin prisma
RUN pip install prisma
RUN prisma generate # Make a /non-existent folder and assign chown to nobody
RUN mkdir -p /nonexistent && \
chown -R nobody:nogroup /app && \
chown -R nobody:nogroup /nonexistent && \
chown -R nobody:nogroup /usr/local/lib/python3.13/site-packages/prisma/
RUN chmod +x docker/entrypoint.sh RUN chmod +x docker/entrypoint.sh
RUN chmod +x docker/prod_entrypoint.sh RUN chmod +x docker/prod_entrypoint.sh
# Run Prisma generate as user = nobody
USER nobody
RUN prisma generate
### End of Prisma Handling for Non-Root #########################################
EXPOSE 4000/tcp EXPOSE 4000/tcp
# # Set your entrypoint and command # # Set your entrypoint and command
ENTRYPOINT ["docker/prod_entrypoint.sh"] ENTRYPOINT ["docker/prod_entrypoint.sh"]
# Append "--detailed_debug" to the end of CMD to view detailed debug logs # Append "--detailed_debug" to the end of CMD to view detailed debug logs
# CMD ["--port", "4000", "--detailed_debug"] # CMD ["--port", "4000", "--detailed_debug"]
CMD ["--port", "4000"] CMD ["--port", "4000"]

18
docker/tests/nonroot.yaml Normal file
View file

@ -0,0 +1,18 @@
schemaVersion: 2.0.0
metadataTest:
entrypoint: ["docker/prod_entrypoint.sh"]
user: "nobody"
workdir: "/app"
fileExistenceTests:
- name: "Prisma Folder"
path: "/usr/local/lib/python3.13/site-packages/prisma/"
shouldExist: true
uid: 65534
gid: 65534
- name: "Prisma Schema"
path: "/usr/local/lib/python3.13/site-packages/prisma/schema.prisma"
shouldExist: true
uid: 65534
gid: 65534