From 5ccc1a762cf3a477c1b0f2e1b9c243debc2c3af1 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 09:48:12 -0800 Subject: [PATCH 1/8] Save database build to reusable workspace --- .circleci/config.yml | 80 +++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d98fdaa4a4..2f19ad19f0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3421,6 +3421,38 @@ jobs: --coverage.reporter=html \ --coverage.reportsDirectory=coverage/html + build_docker_database_image: + machine: + image: ubuntu-2204:2023.10.1 + resource_class: xlarge + working_directory: ~/project + steps: + - checkout + + - run: + name: Upgrade Docker + command: | + curl -fsSL https://get.docker.com | sh + docker version + + - run: + name: Build Docker image + command: | + docker build \ + -t litellm-docker-database:ci \ + -f docker/Dockerfile.database . + + - run: + name: Save Docker image to workspace + command: | + mkdir -p workspace + docker save litellm-docker-database:ci | gzip > workspace/litellm-docker-database.tar.gz + + - persist_to_workspace: + root: . + paths: + - litellm-docker-database.tar.gz + e2e_ui_testing: machine: image: ubuntu-2204:2023.10.1 @@ -3432,53 +3464,18 @@ jobs: - attach_workspace: at: ~/project - run: - name: Upgrade Docker to v24.x (API 1.44+) + name: Load Docker image command: | - curl -fsSL https://get.docker.com | sh - sudo usermod -aG docker $USER - docker version - - run: - name: Install Python 3.9 - command: | - curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh --output miniconda.sh - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - conda init bash - source ~/.bashrc - conda create -n myenv python=3.9 -y - conda activate myenv - python --version + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Install Dependencies command: | npm install -D @playwright/test - npm install @google-cloud/vertexai - pip install "pytest==7.3.1" - pip install "pytest-retry==1.6.3" - pip install "pytest-asyncio==0.21.1" - pip install aiohttp - pip install "openai==1.100.1" - python -m pip install --upgrade pip - pip install "pydantic==2.10.2" - pip install "pytest==7.3.1" - pip install "pytest-mock==3.12.0" - pip install "pytest-asyncio==0.21.1" - pip install "mypy==1.18.2" - pip install pyarrow - pip install numpydoc - pip install prisma - pip install fastapi - pip install jsonschema - pip install "httpx==0.24.1" - pip install "anyio==3.7.1" - pip install "asyncio==3.4.3" - run: name: Install Playwright Browsers command: | npx playwright install - - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . - run: name: Run Docker container command: | @@ -3490,9 +3487,9 @@ jobs: -e UI_USERNAME="admin" \ -e UI_PASSWORD="gm" \ -e LITELLM_LICENSE=$LITELLM_LICENSE \ - --name my-app \ + --name litellm-docker-database \ -v $(pwd)/litellm/proxy/example_config_yaml/simple_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:latest \ --config /app/config.yaml \ --port 4000 \ --detailed_debug @@ -3506,7 +3503,7 @@ jobs: sudo rm dockerize-linux-amd64-v0.6.1.tar.gz - run: name: Start outputting logs - command: docker logs -f my-app + command: docker logs -f litellm-docker-database background: true - run: name: Wait for app to be ready @@ -3710,6 +3707,7 @@ workflows: - e2e_ui_testing: requires: - ui_build + - build_docker_database_image filters: branches: only: From 3ce5de485faea1bb04914405a0c456dd92f15055 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 09:52:05 -0800 Subject: [PATCH 2/8] add job to build_and_test --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2f19ad19f0..543f0ef480 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3704,6 +3704,12 @@ workflows: only: - main - /litellm_.*/ + - build_docker_database_image: + filters: + branches: + only: + - main + - /litellm_.*/ - e2e_ui_testing: requires: - ui_build From 75a43e1a59168347a1717b93130f73946b79026e Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 10:03:43 -0800 Subject: [PATCH 3/8] fixing path --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 543f0ef480..2832b28b95 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3449,7 +3449,7 @@ jobs: docker save litellm-docker-database:ci | gzip > workspace/litellm-docker-database.tar.gz - persist_to_workspace: - root: . + root: workspace paths: - litellm-docker-database.tar.gz @@ -3466,7 +3466,7 @@ jobs: - run: name: Load Docker image command: | - gunzip -c litellm-docker-database.tar.gz | docker load + gunzip -c workspace/litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database - run: name: Install Dependencies From 22019aed79225d6c492ce4529f3055e5d8a42921 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 10:12:10 -0800 Subject: [PATCH 4/8] fixing path for e2e --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2832b28b95..c05da1f930 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3462,7 +3462,7 @@ jobs: - checkout - setup_google_dns - attach_workspace: - at: ~/project + at: workspace - run: name: Load Docker image command: | From c7820997a4e16df3385fca12165b106406b95218 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 10:19:24 -0800 Subject: [PATCH 5/8] saving docker build at root --- .circleci/config.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c05da1f930..a830aac152 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3443,13 +3443,12 @@ jobs: -f docker/Dockerfile.database . - run: - name: Save Docker image to workspace + name: Save Docker image to workspace root command: | - mkdir -p workspace - docker save litellm-docker-database:ci | gzip > workspace/litellm-docker-database.tar.gz + docker save litellm-docker-database:ci | gzip > litellm-docker-database.tar.gz - persist_to_workspace: - root: workspace + root: . paths: - litellm-docker-database.tar.gz @@ -3462,11 +3461,11 @@ jobs: - checkout - setup_google_dns - attach_workspace: - at: workspace + at: ~/project - run: name: Load Docker image command: | - gunzip -c workspace/litellm-docker-database.tar.gz | docker load + gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database - run: name: Install Dependencies From 5b66658a87aae0b217fe405a282b713820e0bdf3 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 10:37:25 -0800 Subject: [PATCH 6/8] using built image instead of latest --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a830aac152..512c914877 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3488,7 +3488,7 @@ jobs: -e LITELLM_LICENSE=$LITELLM_LICENSE \ --name litellm-docker-database \ -v $(pwd)/litellm/proxy/example_config_yaml/simple_config.yaml:/app/config.yaml \ - litellm-docker-database:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug From e22b2186c251885801228786e0bac9084d329891 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 11:04:13 -0800 Subject: [PATCH 7/8] Mirroring to other ci jobs that require docker database --- .circleci/config.yml | 74 ++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 512c914877..cac97e3508 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2009,9 +2009,10 @@ jobs: pip install aiohttp pip install apscheduler - run: - name: Build Docker image + name: Load Docker image command: | - docker build -t myapp . -f ./docker/Dockerfile.database + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container command: | @@ -2024,7 +2025,7 @@ jobs: -v $(pwd)/litellm/proxy/example_config_yaml/bad_schema.prisma:/app/litellm/proxy/schema.prisma \ -v $(pwd)/litellm/proxy/example_config_yaml/disable_schema_update.yaml:/app/config.yaml \ --name my-app \ - myapp:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 - run: @@ -2277,8 +2278,10 @@ jobs: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container command: | @@ -2313,7 +2316,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/oai_misc_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -2417,8 +2420,10 @@ jobs: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container # intentionally give bad redis credentials here @@ -2451,7 +2456,7 @@ jobs: --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/otel_test_config.yaml:/app/config.yaml \ -v $(pwd)/litellm/proxy/example_config_yaml/custom_guardrail.py:/app/custom_guardrail.py \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -2502,7 +2507,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app-3 \ -v $(pwd)/litellm/proxy/example_config_yaml/enterprise_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug @@ -2578,8 +2583,10 @@ jobs: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container # intentionally give bad redis credentials here @@ -2603,7 +2610,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/spend_tracking_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -2691,8 +2698,10 @@ jobs: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container 1 # intentionally give bad redis credentials here @@ -2712,7 +2721,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/multi_instance_simple_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -2733,7 +2742,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app-2 \ -v $(pwd)/litellm/proxy/example_config_yaml/multi_instance_simple_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4001 \ --detailed_debug @@ -2827,8 +2836,10 @@ jobs: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container # intentionally give bad redis credentials here @@ -2843,7 +2854,7 @@ jobs: --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/store_model_db_config.yaml:/app/config.yaml \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -3058,10 +3069,11 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - # Run pytest and generate JUnit XML report - run: - name: Build Docker image - command: docker build -t my-app:latest -f ./docker/Dockerfile.database . + name: Load Docker image + command: | + gunzip -c litellm-docker-database.tar.gz | docker load + docker images | grep litellm-docker-database - run: name: Run Docker container command: | @@ -3083,7 +3095,7 @@ jobs: --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/pass_through_config.yaml:/app/config.yaml \ -v $(pwd)/litellm/proxy/example_config_yaml/custom_auth_basic.py:/app/custom_auth_basic.py \ - my-app:latest \ + litellm-docker-database:ci \ --config /app/config.yaml \ --port 4000 \ --detailed_debug \ @@ -3725,30 +3737,40 @@ workflows: - main - /litellm_.*/ - e2e_openai_endpoints: + requires: + - build_docker_database_image filters: branches: only: - main - /litellm_.*/ - proxy_logging_guardrails_model_info_tests: + requires: + - build_docker_database_image filters: branches: only: - main - /litellm_.*/ - proxy_spend_accuracy_tests: + requires: + - build_docker_database_image filters: branches: only: - main - /litellm_.*/ - proxy_multi_instance_tests: + requires: + - build_docker_database_image filters: branches: only: - main - /litellm_.*/ - proxy_store_model_in_db_tests: + requires: + - build_docker_database_image filters: branches: only: @@ -3761,6 +3783,8 @@ workflows: - main - /litellm_.*/ - proxy_pass_through_endpoint_tests: + requires: + - build_docker_database_image filters: branches: only: @@ -3899,6 +3923,8 @@ workflows: - litellm_assistants_api_testing - auth_ui_unit_tests - db_migration_disable_update_check: + requires: + - build_docker_database_image filters: branches: only: From ba52490488e32529f769076945aae7153136ab03 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 1 Jan 2026 11:15:10 -0800 Subject: [PATCH 8/8] adding attach workspace --- .circleci/config.yml | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cac97e3508..a105700300 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2008,8 +2008,10 @@ jobs: pip install "pytest-asyncio==0.21.1" pip install aiohttp pip install apscheduler + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -2277,8 +2279,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -2419,8 +2423,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -2582,8 +2588,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -2697,8 +2705,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -2835,8 +2845,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -3069,8 +3081,10 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m + - attach_workspace: + at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database @@ -3475,7 +3489,7 @@ jobs: - attach_workspace: at: ~/project - run: - name: Load Docker image + name: Load Docker Database Image command: | gunzip -c litellm-docker-database.tar.gz | docker load docker images | grep litellm-docker-database