Skip to content
Closed
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
64 changes: 64 additions & 0 deletions ct/vllm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: piotrlaczykowski
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vllm-project/vllm

APP="vLLM"
var_tags="${var_tags:-ai;llm}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-40}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-0}"
var_gpu="${var_gpu:-yes}"

header_info "$APP"
variables
color
catch_errors

function update_script() {
header_info
check_container_storage
check_container_resources

if [[ ! -d /opt/vllm ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

if check_for_gh_release "vLLM" "vllm-project/vllm"; then
RELEASE="${CHECK_UPDATE_RELEASE}"
RELEASE_VERSION="${RELEASE#v}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need this extra var and can apply ${RELEASE#v} directly where needed


msg_info "Stopping Service"
systemctl stop vllm
msg_ok "Stopped Service"

msg_info "Updating ${APP} to ${RELEASE}"
$STD uv pip install --python /opt/vllm/.venv/bin/python --upgrade "vllm==${RELEASE_VERSION}"
msg_ok "Updated ${APP} to ${RELEASE}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you directly resovle the $app var


msg_info "Starting Service"
systemctl start vllm
msg_ok "Started Service"
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}:8000${CL}"
echo -e "${INFO}${YW} OpenAI-compatible API endpoint:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000/v1${CL}"
echo -e "${INFO}${YW} Swagger docs:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000/docs${CL}"
Comment on lines +63 to +64

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those probably don't need an extra info, as /docs is pretty much the standard and the api probably also not.

151 changes: 151 additions & 0 deletions install/vllm-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# Author: piotrlaczykowski
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vllm-project/vllm

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 \
python3 \
python3-dev \
build-essential \
pkg-config \
libssl-dev \
libffi-dev
msg_ok "Installed Dependencies"

setup_hwaccel "vllm"
setup_uv

msg_info "Setting up Python Environment"
$STD uv venv /opt/vllm/.venv
msg_ok "Set up Python Environment"

RELEASE=$(get_latest_github_release "vllm-project/vllm")

msg_info "Installing ${APP} v${RELEASE} (Patience — this takes 5-15 minutes)"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolve $app

if nvidia-smi &>/dev/null; then
msg_info "GPU detected — installing vLLM with CUDA support"
$STD uv pip install --python /opt/vllm/.venv/bin/python "vllm==${RELEASE}"
else
msg_info "No GPU detected — installing vLLM with CPU/OpenVINO backend"
$STD uv pip install --python /opt/vllm/.venv/bin/python "vllm==${RELEASE}" --extra-index-url https://download.pytorch.org/whl/cpu
fi
echo "v${RELEASE}" >/opt/vLLM_version.txt

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you do this to ~/.vllm that is where we normally put it.

msg_ok "Installed ${APP} v${RELEASE}"

msg_info "Configuring ${APP}"
mkdir -p /etc/vllm /opt/vllm-models
cat <<EOF >/etc/vllm/vllm.env
# Set MODEL to a Hugging Face model ID before starting the service.
# Example (small, ungated): Qwen/Qwen2.5-0.5B-Instruct
# Example (medium): Qwen/Qwen2.5-7B-Instruct
# Example (gated): meta-llama/Llama-3.1-8B-Instruct (requires HF_TOKEN)
MODEL="Qwen/Qwen2.5-0.5B-Instruct"
HOST="0.0.0.0"
PORT="8000"
GPU_MEM_UTIL="0.90"
MAX_MODEL_LEN="4096"
TENSOR_PARALLEL_SIZE="1"
QUANTIZATION=""
# HF_TOKEN=""
HF_HOME="/opt/vllm-models"
EOF
msg_ok "Configured ${APP}"

msg_info "Creating vLLM Server Wrapper"
Comment on lines +46 to +65

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
msg_info "Configuring ${APP}"
mkdir -p /etc/vllm /opt/vllm-models
cat <<EOF >/etc/vllm/vllm.env
# Set MODEL to a Hugging Face model ID before starting the service.
# Example (small, ungated): Qwen/Qwen2.5-0.5B-Instruct
# Example (medium): Qwen/Qwen2.5-7B-Instruct
# Example (gated): meta-llama/Llama-3.1-8B-Instruct (requires HF_TOKEN)
MODEL="Qwen/Qwen2.5-0.5B-Instruct"
HOST="0.0.0.0"
PORT="8000"
GPU_MEM_UTIL="0.90"
MAX_MODEL_LEN="4096"
TENSOR_PARALLEL_SIZE="1"
QUANTIZATION=""
# HF_TOKEN=""
HF_HOME="/opt/vllm-models"
EOF
msg_ok "Configured ${APP}"
msg_info "Creating vLLM Server Wrapper"
msg_info "Configuring ${APP}"
mkdir -p /etc/vllm /opt/vllm-models
cat <<EOF >/etc/vllm/vllm.env
# Set MODEL to a Hugging Face model ID before starting the service.
# Example (small, ungated): Qwen/Qwen2.5-0.5B-Instruct
# Example (medium): Qwen/Qwen2.5-7B-Instruct
# Example (gated): meta-llama/Llama-3.1-8B-Instruct (requires HF_TOKEN)
MODEL="Qwen/Qwen2.5-0.5B-Instruct"
HOST="0.0.0.0"
PORT="8000"
GPU_MEM_UTIL="0.90"
MAX_MODEL_LEN="4096"
TENSOR_PARALLEL_SIZE="1"
QUANTIZATION=""
# HF_TOKEN=""
HF_HOME="/opt/vllm-models"
EOF

No extra msg block needed for such short actions

cat <<'EOF' >/usr/local/bin/vllm-server
#!/usr/bin/env bash
set -a
source /etc/vllm/vllm.env
set +a

EXTRA_ARGS=()
[[ -n "${QUANTIZATION}" ]] && EXTRA_ARGS+=(--quantization "${QUANTIZATION}")
[[ -n "${MAX_MODEL_LEN}" && "${MAX_MODEL_LEN}" != "0" ]] && EXTRA_ARGS+=(--max-model-len "${MAX_MODEL_LEN}")
[[ -n "${HF_TOKEN}" ]] && export HUGGING_FACE_HUB_TOKEN="${HF_TOKEN}"

exec /opt/vllm/.venv/bin/python -m vllm.entrypoints.openai.api_server \
--model "${MODEL}" \
--host "${HOST}" \
--port "${PORT}" \
--gpu-memory-utilization "${GPU_MEM_UTIL}" \
--tensor-parallel-size "${TENSOR_PARALLEL_SIZE}" \
--trust-remote-code \
"${EXTRA_ARGS[@]}"
EOF
chmod +x /usr/local/bin/vllm-server
msg_ok "Created vLLM Server Wrapper"

msg_info "Creating Service"
cat <<'EOF' >/etc/systemd/system/vllm.service
[Unit]
Description=vLLM OpenAI-Compatible Inference Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/vllm
ExecStart=/usr/local/bin/vllm-server
Restart=on-failure
RestartSec=10
TimeoutStartSec=300
StandardOutput=journal
StandardError=journal
SyslogIdentifier=vllm

[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q vllm
msg_ok "Created Service (not started — configure /etc/vllm/vllm.env first)"

msg_info "Installing vllm-cli helper"
cat <<'EOF' >/usr/local/bin/vllm-cli
#!/usr/bin/env bash
case "$1" in
start)
systemctl start vllm
echo "vLLM starting... check logs with: journalctl -u vllm -f"
;;
stop) systemctl stop vllm ;;
restart) systemctl restart vllm ;;
status) systemctl status vllm ;;
logs) journalctl -u vllm -f --no-pager ;;
config) "${EDITOR:-nano}" /etc/vllm/vllm.env ;;
models)
/opt/vllm/.venv/bin/python -c "
import os, pathlib
hf_home = os.environ.get('HF_HOME', '/opt/vllm-models')
models = [d for d in pathlib.Path(hf_home).glob('models--*') if d.is_dir()]
if models:
print('Cached models:')
for m in models:
print(' ' + m.name.replace('models--', '').replace('--', '/'))
else:
print('No cached models found in', hf_home)
"
;;
version)
/opt/vllm/.venv/bin/python -c "import vllm; print('vLLM', vllm.__version__)"
;;
*) echo "Usage: vllm-cli {start|stop|restart|status|logs|config|models|version}" ;;
esac
EOF
chmod +x /usr/local/bin/vllm-cli
msg_ok "Installed vllm-cli helper"

motd_ssh
customize
cleanup_lxc
42 changes: 42 additions & 0 deletions json/vllm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "vLLM",
"slug": "vllm",
"categories": [
3
],
"description": "vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. It provides an OpenAI-compatible API server for local LLM inference with NVIDIA GPU support.",
"type": "ct",
"privileged": true,
"updateable": true,
"interface_port": 8000,
"documentation": "https://docs.vllm.ai",
"website": "https://github.com/vllm-project/vllm",
"logo": "https://raw.githubusercontent.com/vllm-project/vllm/main/docs/source/assets/logos/vllm-logo-text-light.png",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utilize one from selfh.st/icons

"install_methods": [
{
"type": "default",
"script": "ct/vllm.sh",
"resources": {
"cpu": 4,
"ram": 8192,
"hdd": 40,
"os": "Ubuntu",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is ubuntu preferrable from debian in any way?
because of drivers?

"version": "24.04"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "GPU passthrough requires a privileged LXC container with NVIDIA drivers installed on the Proxmox host. Edit /etc/vllm/vllm.env to configure model and settings before starting the service.",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is just wrong, it does not need to be priviledged for gpu passthrough

"type": "info"
},
{
"text": "Default resources (4 CPU, 8GB RAM) are sufficient for installation and small models only. Large models (7B+) require a GPU with 8GB+ VRAM and 16GB+ RAM. Edit /etc/vllm/vllm.env to configure the model before starting the service.",
"type": "warning"
}
]
}
Loading