Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,21 @@ tests
*.tgz
log.txt
docker/Dockerfile.*
venv/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
env/
.venv/
.env
.mypy_cache/
.pytest_cache/
.coverage
.coverage.*
coverage.xml
*.cover
.idea/
.vscode/
*.log
98 changes: 98 additions & 0 deletions .github/workflows/litellm-acr-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Build and Deploy LiteLLM to Azure Container Registry

on:
push:
branches:
- main
- staging
paths:
- '**'
- '.github/workflows/litellm-acr-deploy.yml'
workflow_dispatch:

jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read

steps:
- name: Checkout to the branch
uses: actions/checkout@v4

- name: Azure Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: 'Build and push image for main branch'
if: github.ref == 'refs/heads/main'
uses: azure/docker-login@v1
with:
login-server: ${{ secrets.PLATFORM_REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.PLATFORM_REGISTRY_USERNAME }}
password: ${{ secrets.PLATFORM_REGISTRY_PASSWORD }}

- name: 'Run Docker build and push for main branch'
if: github.ref == 'refs/heads/main'
run: |
docker buildx build --platform linux/amd64,linux/arm64 \
--build-arg LITELLM_BUILD_IMAGE=cgr.dev/chainguard/python:latest-dev \
--build-arg LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/python:latest-dev \
-t ${{ secrets.PLATFORM_REGISTRY_LOGIN_SERVER }}/litellm:latest \
-t ${{ secrets.PLATFORM_REGISTRY_LOGIN_SERVER }}/litellm:${{ github.sha }} \
--push .

- name: 'Build and push image for staging branch'
if: github.ref == 'refs/heads/staging'
uses: azure/docker-login@v1
with:
login-server: ${{ secrets.STAGING_REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.STAGING_REGISTRY_USERNAME }}
password: ${{ secrets.STAGING_REGISTRY_PASSWORD }}

- name: 'Run Docker build and push for staging branch'
if: github.ref == 'refs/heads/staging'
run: |
docker buildx build --platform linux/amd64,linux/arm64 \
--build-arg LITELLM_BUILD_IMAGE=cgr.dev/chainguard/python:latest-dev \
--build-arg LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/python:latest-dev \
-t ${{ secrets.STAGING_REGISTRY_LOGIN_SERVER }}/litellm:latest \
-t ${{ secrets.STAGING_REGISTRY_LOGIN_SERVER }}/litellm:${{ github.sha }} \
--push .

- name: 'Security scan with Trivy'
if: github.ref == 'refs/heads/main'
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ secrets.PLATFORM_REGISTRY_LOGIN_SERVER }}/litellm:latest
format: 'sarif'
output: 'trivy-results.sarif'

- name: 'Upload Trivy scan results to GitHub Security tab'
if: github.ref == 'refs/heads/main'
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'

- name: 'Notification on success'
if: success()
run: |
echo "✅ LiteLLM Docker image successfully built and pushed to ACR"
echo "Branch: ${{ github.ref_name }}"
echo "Commit: ${{ github.sha }}"
echo "Registry: ${{ github.ref == 'refs/heads/main' && secrets.PLATFORM_REGISTRY_LOGIN_SERVER || secrets.STAGING_REGISTRY_LOGIN_SERVER }}"

- name: 'Notification on failure'
if: failure()
run: |
echo "❌ LiteLLM Docker build and push failed"
echo "Branch: ${{ github.ref_name }}"
echo "Commit: ${{ github.sha }}"
exit 1
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ config.yaml
tests/litellm/litellm_core_utils/llm_cost_calc/log.txt
tests/test_custom_dir/*
test.py
litellm/bin/*
litellm/lib/*
litellm/dev/*
litellm/lib64/*
litellm/pyvenv.cfg
.vscode/*
litellm_config.yaml
litellm/lib64
SwaggerAPIs.json


50 changes: 21 additions & 29 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/python:latest-dev

# Runtime image
ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/python:latest-dev

# Builder stage
FROM $LITELLM_BUILD_IMAGE AS builder

Expand All @@ -14,36 +15,29 @@ USER root
# Install build dependencies
RUN apk add --no-cache gcc python3-dev openssl openssl-dev

RUN pip install --upgrade pip

RUN pip install --upgrade pip && \
pip install build
# Copy requirements and install dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Copy the current directory contents into the container at /app
COPY . .
# Copy source code
COPY pyproject.toml poetry.lock ./
COPY litellm/ litellm/
COPY README.md ./
COPY docker/ docker/

# Build Admin UI
RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh

# Build the package
RUN rm -rf dist/* && python -m build

# There should be only one wheel file now, assume the build only creates one
RUN ls -1 dist/*.whl | head -1

# Install the package
RUN pip install dist/*.whl

# install dependencies as wheels
RUN pip wheel --no-cache-dir --wheel-dir=/wheels/ -r requirements.txt
# Install the package directly without building wheel
RUN pip install -e .

# ensure pyjwt is used, not jwt
RUN pip uninstall jwt -y
RUN pip uninstall PyJWT -y
RUN pip uninstall jwt -y || true
RUN pip uninstall PyJWT -y || true
RUN pip install PyJWT==2.9.0 --no-cache-dir

# Build Admin UI
RUN chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh

# Runtime stage
FROM $LITELLM_RUNTIME_IMAGE AS runtime

Expand All @@ -54,19 +48,17 @@ USER root
RUN apk add --no-cache openssl

WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . .
RUN ls -la /app

# Copy the built wheel from the builder stage to the runtime stage; assumes only one wheel file is present
COPY --from=builder /app/dist/*.whl .
COPY --from=builder /wheels/ /wheels/
# Copy installed packages from builder
COPY --from=builder /usr/lib/python3.13/site-packages/ /usr/lib/python3.13/site-packages/
COPY --from=builder /usr/bin/ /usr/bin/

# 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
# Copy the entire project
COPY . .
RUN ls -la /app

# Generate prisma client
RUN prisma generate
RUN prisma generate || true
RUN chmod +x docker/entrypoint.sh
RUN chmod +x docker/prod_entrypoint.sh

Expand Down
43 changes: 43 additions & 0 deletions debug_eureka.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# debug_eureka.py
import asyncio
import logging
import os

# Configure detailed logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("eureka_debug")

# Import the Eureka integration class from LiteLLM
from litellm.proxy.eureka_integration import EurekaIntegration, eureka_error_handler

async def test_eureka_registration():
try:
# Use the same config values you have in your litellm_config.yaml
eureka_integration = EurekaIntegration(
app_name="litellm-proxy",
host="localhost", # or whatever host you're using
port=4000,
eureka_server_urls="http://localhost:8762/eureka",
# Add any other parameters from your config
on_error=eureka_error_handler
)

logger.debug("Attempting to register with Eureka...")
await eureka_integration.register()
logger.debug("Successfully registered with Eureka")

# Wait a bit to keep the process alive
await asyncio.sleep(50)

# Deregister
logger.debug("Attempting to deregister from Eureka...")
await eureka_integration.stop()
logger.debug("Successfully deregistered from Eureka")

except Exception as e:
logger.error(f"Error during Eureka registration: {str(e)}", exc_info=True)

# Run the test
if __name__ == "__main__":
asyncio.run(test_eureka_registration())
Loading