-
-
Notifications
You must be signed in to change notification settings - Fork 466
feat(litellm): bare-metal LiteLLM proxy via uv, PostgreSQL and systemd #1994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
46927b3
c94f780
eb6a94e
503e8c1
848f04a
f5f73f1
825396a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| #!/usr/bin/env bash | ||
| source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) | ||
| # Copyright (c) 2021-2026 community-scripts ORG | ||
| # Author: stout01 | ||
| # Co-Authors: MickLesk, tremor021 (prior pip/Prisma versions) | ||
| # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE | ||
| # Source: https://github.com/BerriAI/litellm | ||
|
|
||
| APP="LiteLLM" | ||
| var_tags="${var_tags:-ai;proxy;llm}" | ||
| var_cpu="${var_cpu:-1}" | ||
| var_ram="${var_ram:-2048}" | ||
| var_disk="${var_disk:-10}" | ||
| var_os="${var_os:-debian}" | ||
| var_version="${var_version:-13}" | ||
| var_arm64="${var_arm64:-no}" | ||
| var_unprivileged="${var_unprivileged:-1}" | ||
|
|
||
| header_info "$APP" | ||
| variables | ||
| color | ||
| catch_errors | ||
|
|
||
| function update_script() { | ||
| header_info | ||
| check_container_storage | ||
| check_container_resources | ||
|
|
||
| if [[ ! -f /opt/litellm/litellm.yaml ]]; then | ||
| msg_error "No ${APP} Installation Found!" | ||
| exit | ||
| fi | ||
|
|
||
| if check_for_gh_release "litellm" "BerriAI/litellm"; then | ||
| msg_info "Stopping LiteLLM" | ||
| systemctl stop litellm | ||
| msg_ok "Stopped LiteLLM" | ||
|
|
||
| create_backup /opt/litellm/litellm.yaml | ||
|
|
||
| CLEAN_INSTALL=1 fetch_and_deploy_gh_release "litellm" "BerriAI/litellm" "tarball" "latest" "/opt/litellm" | ||
|
|
||
| restore_backup | ||
|
|
||
| msg_info "Updating LiteLLM Python environment (Patience)" | ||
| cd /opt/litellm | ||
| $STD uv pip install --python .venv/bin/python -e ".[proxy]" | ||
| DATABASE_URL=$(grep 'database_url:' /opt/litellm/litellm.yaml | awk '{print $2}') | ||
| export DATABASE_URL | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this be one line? |
||
| export PATH="/opt/litellm/.venv/bin:${PATH}" | ||
| $STD .venv/bin/prisma generate --schema=/opt/litellm/schema.prisma | ||
| msg_ok "Updated LiteLLM" | ||
|
|
||
| msg_info "Starting LiteLLM" | ||
| systemctl start litellm | ||
| msg_ok "Started LiteLLM" | ||
| msg_ok "Updated successfully!" | ||
| fi | ||
| exit | ||
| } | ||
|
|
||
| start | ||
| build_container | ||
| description | ||
|
|
||
| msg_ok "Completed successfully!\n" | ||
| echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" | ||
| echo -e "${INFO}${YW} Access it using the following URL:${CL}" | ||
| echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4000${CL}" | ||
| echo -e "${INFO}${YW} Master key saved to:${CL} ${TAB}${BGN}~/litellm.creds${CL}" | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,112 @@ | ||||||
| #!/usr/bin/env bash | ||||||
|
|
||||||
| # Copyright (c) 2021-2026 community-scripts ORG | ||||||
| # Author: stout01 | ||||||
| # Co-Authors: MickLesk, tremor021 (prior pip/Prisma versions) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE | ||||||
| # Source: https://github.com/BerriAI/litellm | ||||||
|
|
||||||
| source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" | ||||||
| color | ||||||
| verb_ip6 | ||||||
| catch_errors | ||||||
| setting_up_container | ||||||
| network_check | ||||||
| update_os | ||||||
|
|
||||||
| msg_info "Installing Dependencies" | ||||||
| $STD apt install -y \ | ||||||
| build-essential \ | ||||||
| python3-dev \ | ||||||
| libpq-dev \ | ||||||
| openssl | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is already installed i believe |
||||||
| msg_ok "Installed Dependencies" | ||||||
|
|
||||||
| PG_VERSION="16" setup_postgresql | ||||||
| PG_DB_NAME="litellm" PG_DB_USER="litellm" setup_postgresql_db | ||||||
| PYTHON_VERSION="3.12" USE_UVX="YES" setup_uv | ||||||
|
|
||||||
| fetch_and_deploy_gh_release "litellm" "BerriAI/litellm" "tarball" "latest" "/opt/litellm" | ||||||
|
|
||||||
| msg_info "Installing LiteLLM (Patience)" | ||||||
| cd /opt/litellm | ||||||
| $STD uv venv .venv | ||||||
| $STD uv pip install --python .venv/bin/python prisma | ||||||
| $STD uv pip install --python .venv/bin/python -e ".[proxy]" | ||||||
| msg_ok "Installed LiteLLM" | ||||||
|
|
||||||
| msg_info "Configuring LiteLLM" | ||||||
| LITELLM_MASTER_KEY="sk-$(openssl rand -hex 16)" | ||||||
| LITELLM_SALT_KEY="sk-$(openssl rand -hex 16)" | ||||||
| DATABASE_URL="postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}" | ||||||
|
|
||||||
| cat <<EOF >/opt/litellm/litellm.yaml | ||||||
| general_settings: | ||||||
| master_key: ${LITELLM_MASTER_KEY} | ||||||
| database_url: ${DATABASE_URL} | ||||||
| store_model_in_db: true | ||||||
| litellm_settings: | ||||||
| salt_key: ${LITELLM_SALT_KEY} | ||||||
| EOF | ||||||
|
|
||||||
| export DATABASE_URL | ||||||
| export PATH="/opt/litellm/.venv/bin:${PATH}" | ||||||
| $STD .venv/bin/prisma generate --schema=/opt/litellm/schema.prisma | ||||||
| $STD .venv/bin/litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup | ||||||
| msg_ok "Configured LiteLLM" | ||||||
|
|
||||||
| msg_info "Creating Service" | ||||||
| cat <<EOF >/etc/systemd/system/litellm.service | ||||||
| [Unit] | ||||||
| Description=LiteLLM Proxy | ||||||
| After=network.target postgresql.service | ||||||
| Wants=postgresql.service | ||||||
|
|
||||||
| [Service] | ||||||
| Type=simple | ||||||
| WorkingDirectory=/opt/litellm | ||||||
| Environment=DATABASE_URL=${DATABASE_URL} | ||||||
| ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml | ||||||
| Restart=on-failure | ||||||
| RestartSec=5 | ||||||
|
|
||||||
| [Install] | ||||||
| WantedBy=multi-user.target | ||||||
| EOF | ||||||
| systemctl enable -q --now litellm | ||||||
| msg_ok "Created Service" | ||||||
|
|
||||||
| msg_info "Waiting for LiteLLM health check" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i dont believe a health check should be needed, it should just assume that it works. |
||||||
| for i in $(seq 1 90); do | ||||||
| if curl -sf "http://127.0.0.1:4000/health/liveliness" >/dev/null 2>&1; then | ||||||
| msg_ok "LiteLLM is healthy" | ||||||
| break | ||||||
| fi | ||||||
| if ! systemctl is-active --quiet litellm; then | ||||||
| msg_error "LiteLLM service is not running — check: journalctl -u litellm -n 50" | ||||||
| journalctl -u litellm -n 30 --no-pager 2>/dev/null | ||||||
| exit 150 | ||||||
| fi | ||||||
| sleep 2 | ||||||
| if [[ "$i" -eq 90 ]]; then | ||||||
| msg_error "LiteLLM did not become healthy within 180s" | ||||||
| journalctl -u litellm -n 30 --no-pager 2>/dev/null | ||||||
| exit 150 | ||||||
| fi | ||||||
| done | ||||||
|
|
||||||
| cat <<EOF >~/litellm.creds | ||||||
| LiteLLM Credentials | ||||||
| URL: http://${LOCAL_IP}:4000 | ||||||
| Master Key: ${LITELLM_MASTER_KEY} | ||||||
| Salt Key: ${LITELLM_SALT_KEY} | ||||||
| Postgres Password: ${PG_DB_PASS} | ||||||
|
|
||||||
| Note: LITELLM_SALT_KEY cannot be changed after adding models to the proxy. | ||||||
| EOF | ||||||
| chmod 600 ~/litellm.creds | ||||||
| msg_ok "Saved credentials to ~/litellm.creds" | ||||||
|
|
||||||
| motd_ssh | ||||||
| customize | ||||||
| cleanup_lxc | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||
| { | ||||||||||||||
| "name": "LiteLLM", | ||||||||||||||
| "slug": "litellm", | ||||||||||||||
| "categories": [ | ||||||||||||||
| 20 | ||||||||||||||
| ], | ||||||||||||||
| "date_created": "2026-07-05", | ||||||||||||||
| "type": "ct", | ||||||||||||||
| "updateable": true, | ||||||||||||||
| "privileged": false, | ||||||||||||||
| "has_arm": false, | ||||||||||||||
| "interface_port": 4000, | ||||||||||||||
| "documentation": "https://docs.litellm.ai/", | ||||||||||||||
| "website": "https://github.com/BerriAI/litellm", | ||||||||||||||
| "logo": "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f685.png", | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is this image? |
||||||||||||||
| "description": "LiteLLM is an OpenAI-compatible LLM proxy with cost tracking, load balancing, and observability.", | ||||||||||||||
| "install_methods": [ | ||||||||||||||
| { | ||||||||||||||
| "type": "default", | ||||||||||||||
| "script": "ct/litellm.sh", | ||||||||||||||
| "config_path": "/opt/litellm/litellm.yaml", | ||||||||||||||
| "resources": { | ||||||||||||||
| "cpu": 1, | ||||||||||||||
| "ram": 2048, | ||||||||||||||
| "hdd": 10, | ||||||||||||||
| "os": "Debian", | ||||||||||||||
| "version": "13" | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| ], | ||||||||||||||
| "default_credentials": { | ||||||||||||||
| "username": null, | ||||||||||||||
| "password": null | ||||||||||||||
| }, | ||||||||||||||
| "notes": [ | ||||||||||||||
| { | ||||||||||||||
| "text": "Master key and secrets are saved to ~/litellm.creds after install.", | ||||||||||||||
| "type": "info" | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| "text": "Uses PostgreSQL and Python (uv) with the official LiteLLM release tarball.", | ||||||||||||||
| "type": "info" | ||||||||||||||
| }, | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| { | ||||||||||||||
| "text": "LITELLM_SALT_KEY cannot be changed after models are added to the proxy.", | ||||||||||||||
| "type": "warning" | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+39
to
+43
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
having the notice in the file where they set litellm salt key is enough imo |
||||||||||||||
| ] | ||||||||||||||
| } | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.