Skip to content
Merged
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
122 changes: 122 additions & 0 deletions Dockerfile-litellm
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# syntax=docker/dockerfile:1-labs

FROM node:20-alpine AS node_base

FROM node_base AS node_deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --legacy-peer-deps

FROM node_base AS node_builder
WORKDIR /app
COPY --from=node_deps /app/node_modules ./node_modules
COPY --exclude=./api . .
RUN NODE_ENV=production npm run build
Comment thread
marazik marked this conversation as resolved.

FROM python:3.11-slim AS py_deps
WORKDIR /api
COPY api/pyproject.toml .
COPY api/poetry.lock .
RUN python -m pip install poetry==2.0.1 --no-cache-dir && \
poetry config virtualenvs.create true --local && \
poetry config virtualenvs.in-project true --local && \
poetry config virtualenvs.options.always-copy --local true && \
POETRY_MAX_WORKERS=10 poetry install --no-interaction --no-ansi --only main && \
poetry cache clear --all .

FROM python:3.11-slim AS ollama_base
RUN apt-get update && apt-get install -y --no-install-recommends \
curl zstd && rm -rf /var/lib/apt/lists/*

# Detect architecture and download appropriate Ollama version
# ARG TARGETARCH can be set at build time with --build-arg TARGETARCH=arm64 or TARGETARCH=amd64
ARG TARGETARCH
RUN OLLAMA_ARCH="" && \
if [ "$TARGETARCH" = "arm64" ]; then \
echo "Building for ARM64 architecture." && \
OLLAMA_ARCH="arm64"; \
elif [ "$TARGETARCH" = "amd64" ]; then \
echo "Building for AMD64 architecture." && \
OLLAMA_ARCH="amd64"; \
else \
echo "Error: Unsupported architecture '$TARGETARCH'. Supported architectures are 'arm64' and 'amd64'." >&2 && \
exit 1; \
fi && \
(set -o pipefail; \
curl -fL "https://ollama.com/download/ollama-linux-${OLLAMA_ARCH}.tar.zst" \
| zstd -d | tar -x -C /usr)

RUN ollama serve > /dev/null 2>&1 & \
sleep 20 && \
ollama pull nomic-embed-text && \
ollama pull qwen3:1.7b
Comment thread
marazik marked this conversation as resolved.

# Use Python 3.11 as final image
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Install Node.js and npm
RUN apt-get update && apt-get install -y \
curl \
gnupg \
git \
Comment thread
marazik marked this conversation as resolved.
ca-certificates \
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

ENV PATH="/opt/venv/bin:$PATH"

# Copy Python dependencies
COPY --from=py_deps /api/.venv /opt/venv
COPY api/ ./api/

# Copy Node app
COPY --from=node_builder /app/public ./public
COPY --from=node_builder /app/.next/standalone ./
COPY --from=node_builder /app/.next/static ./.next/static
COPY --from=ollama_base /usr/bin/ollama /usr/local/bin/
COPY --from=ollama_base /root/.ollama /root/.ollama

# Expose the port the app runs on
EXPOSE ${PORT:-8001} 3000

# Create a script to run both backend and frontend
RUN echo '#!/bin/bash\n\
# Start ollama serve in background\n\
ollama serve > /dev/null 2>&1 &\n\
\n\
# Load environment variables from .env file if it exists\n\
if [ -f .env ]; then\n\
export $(grep -v "^#" .env | xargs -r)\n\
fi\n\
\n\
# Check for required environment variables\n\
if [ -z "$OPENAI_API_KEY" ] || [ -z "$GOOGLE_API_KEY" ]; then\n\
echo "Warning: OPENAI_API_KEY and/or GOOGLE_API_KEY environment variables are not set."\n\
echo "These are required for DeepWiki to function properly."\n\
echo "You can provide them via a mounted .env file or as environment variables when running the container."\n\
fi\n\
\n\
# Start the API server in the background with the configured port\n\
python -m api.main --port ${PORT:-8001} &\n\
PORT=3000 HOSTNAME=0.0.0.0 node server.js &\n\
wait -n\n\
exit $?' > /app/start.sh && chmod +x /app/start.sh

# Set environment variables
ENV PORT=8001
ENV NODE_ENV=production
ENV SERVER_BASE_URL=http://localhost:${PORT:-8001}

# Create empty .env file (will be overridden if one exists at runtime)
RUN touch .env

# Command to run the application
CMD ["/app/start.sh"]
7 changes: 7 additions & 0 deletions docker-compose-litellm.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Same Compose network http://litellm:4000
# LiteLLM on host OS http://host.docker.internal:4000
# LiteLLM on another server http://server-ip:4000
LITELLM_BASE_URL=http://litellm:4000
# Use env. variable LITELLM_API_KEY
# But if it doesn't exist, default to `sk-1234`
LITELLM_API_KEY=${LITELLM_API_KEY:-sk-1234}
70 changes: 70 additions & 0 deletions docker-compose-litellm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
services:
db:
image: postgres:16
environment:
POSTGRES_DB: litellm
POSTGRES_USER: litellm
# Use env. variable LITELLM_DB_PASSWORD
# otherwise default to litellm_password
POSTGRES_PASSWORD: ${LITELLM_DB_PASSWORD:-litellm_password}
ports:
- "5432:5432"
volumes:
- deepwiki_litellm_db:/var/lib/postgresql/data

litellm:
image: ghcr.io/berriai/litellm:v1.83.10-stable
ports:
- "4000:4000"
volumes:
- ./litellm-config.yml:/app/config.yaml
environment:
# Use env. variable LITELLM_MASTER_KEY
# otherwise default to sk-1234
- LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY:-sk-1234}
# Using from litellm-config.yml
#environment:
# DATABASE_URL: postgres://litellm:litellm_password@db:5432/litellm
command: [ "--config", "/app/config.yaml", "--port", "4000" ]
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- db

deepwiki:
image: deepwiki-litellm # Using image name to show it depends on LiteLLM
build:
context: .
dockerfile: Dockerfile-litellm # ← Using Dockerfile that depends on LiteLLM
ports:
- "${PORT:-8001}:${PORT:-8001}" # API port
- "3000:3000" # Next.js port
env_file:
- docker-compose-litellm.env
environment:
- PORT=${PORT:-8001}
- NODE_ENV=production
- SERVER_BASE_URL=http://localhost:${PORT:-8001}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
- LOG_FILE_PATH=${LOG_FILE_PATH:-api/logs/application.log}
# For LiteLLM
- LITELLM_BASE_URL=${LITELLM_BASE_URL}
- LITELLM_API_KEY=${LITELLM_API_KEY}
volumes:
- ~/.adalflow:/root/.adalflow # Persist repository and embedding data
- ./api/logs:/app/api/logs # Persist log files across container restarts
# Resource limits for docker-compose up (not Swarm mode)
mem_limit: 6g
mem_reservation: 2g
# Health check configuration
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:${PORT:-8001}/health"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
depends_on:
- litellm

volumes:
deepwiki_litellm_db:
26 changes: 26 additions & 0 deletions litellm-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
model_list:
# -----------------------
# Chat / Generation models
# -----------------------
- model_name: qwen3:1.7b #Can be named anything - qwen3-1.7b
litellm_params:
model: ollama/qwen3:1.7b
api_base: http://host.docker.internal:11434
Comment thread
marazik marked this conversation as resolved.
api_key: "not-needed"

# -----------------------
# Embedding models
# -----------------------
- model_name: nomic-embed-text
litellm_params:
model: ollama/nomic-embed-text
api_base: http://host.docker.internal:11434
Comment thread
marazik marked this conversation as resolved.
api_key: "not-needed"

# This overrides the one in the docker-compose file
general_settings:
database_url: postgres://litellm:litellm_password@db:5432/litellm

litellm_settings:
set_verbose: true
drop_params: true
Loading