mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
Merge pull request #885 from tobimichael96/main
Refactor: Migrate to UV
This commit is contained in:
commit
45da11eb7b
10 changed files with 114 additions and 69 deletions
|
|
@ -29,6 +29,5 @@
|
|||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
data/
|
||||
docker/data/
|
||||
|
|
|
|||
4
.github/workflows/base-image.yml
vendored
4
.github/workflows/base-image.yml
vendored
|
|
@ -6,13 +6,13 @@ on:
|
|||
paths:
|
||||
- 'docker/DispatcharrBase'
|
||||
- '.github/workflows/base-image.yml'
|
||||
- 'requirements.txt'
|
||||
- 'pyproject.toml'
|
||||
pull_request:
|
||||
branches: [main, dev]
|
||||
paths:
|
||||
- 'docker/DispatcharrBase'
|
||||
- '.github/workflows/base-image.yml'
|
||||
- 'requirements.txt'
|
||||
- 'pyproject.toml'
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
permissions:
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -19,4 +19,5 @@ debugpy*
|
|||
uwsgi.sock
|
||||
package-lock.json
|
||||
models
|
||||
.idea
|
||||
.idea
|
||||
uv.lock
|
||||
1
.python-version
Normal file
1
.python-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
3.13
|
||||
|
|
@ -160,15 +160,28 @@ EOSU
|
|||
# 6) Setup Python Environment
|
||||
##############################################################################
|
||||
|
||||
install_uv() {
|
||||
echo ">>> Installing UV package manager..."
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
}
|
||||
|
||||
setup_python_env() {
|
||||
echo ">>> Setting up Python virtual environment..."
|
||||
echo ">>> Setting up Python virtual environment with UV..."
|
||||
# Install UV globally first
|
||||
install_uv
|
||||
|
||||
su - "$DISPATCH_USER" <<EOSU
|
||||
cd "$APP_DIR"
|
||||
$PYTHON_BIN -m venv env
|
||||
source env/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install gunicorn
|
||||
export PATH="\$HOME/.local/bin:\$PATH"
|
||||
# Install UV for the dispatch user if not already available
|
||||
if ! command -v uv &> /dev/null; then
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
export PATH="\$HOME/.local/bin:\$PATH"
|
||||
fi
|
||||
# Create venv and install dependencies using UV
|
||||
uv venv env --python $PYTHON_BIN
|
||||
uv sync --python env/bin/python --no-install-project --no-dev
|
||||
EOSU
|
||||
ln -sf /usr/bin/ffmpeg "$APP_DIR/env/bin/ffmpeg"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
FROM lscr.io/linuxserver/ffmpeg:latest
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV UV_PROJECT_ENVIRONMENT=/dispatcharrpy
|
||||
ENV VIRTUAL_ENV=/dispatcharrpy
|
||||
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
ENV UV_COMPILE_BYTECODE=1
|
||||
ENV UV_LINK_MODE=copy
|
||||
|
||||
# --- Install Python 3.13 and build dependencies ---
|
||||
# Note: Hardware acceleration (VA-API, VDPAU, NVENC) already included in base ffmpeg image
|
||||
|
|
@ -18,24 +21,28 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
|||
vlc-bin vlc-plugin-base \
|
||||
build-essential gcc g++ gfortran libopenblas-dev libopenblas0 ninja-build
|
||||
|
||||
# --- Create Python virtual environment ---
|
||||
RUN python3.13 -m venv $VIRTUAL_ENV && $VIRTUAL_ENV/bin/pip install --upgrade pip
|
||||
# --- Install UV ---
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
||||
|
||||
# --- Install Python dependencies ---
|
||||
COPY requirements.txt /tmp/requirements.txt
|
||||
RUN $VIRTUAL_ENV/bin/pip install --no-cache-dir -r /tmp/requirements.txt && \
|
||||
rm /tmp/requirements.txt
|
||||
# --- Create Python virtual environment and install dependencies ---
|
||||
WORKDIR /tmp/build
|
||||
COPY pyproject.toml /tmp/build/
|
||||
COPY version.py /tmp/build/
|
||||
COPY README.md /tmp/build/
|
||||
RUN uv sync --python 3.13 --no-cache --no-install-project --no-dev && \
|
||||
rm -rf /tmp/build
|
||||
WORKDIR /
|
||||
|
||||
# --- Build legacy NumPy wheel for old hardware (store for runtime switching) ---
|
||||
RUN $VIRTUAL_ENV/bin/pip install --no-cache-dir build && \
|
||||
RUN uv pip install --python $UV_PROJECT_ENVIRONMENT/bin/python --no-cache build pip && \
|
||||
cd /tmp && \
|
||||
$VIRTUAL_ENV/bin/pip download --no-binary numpy --no-deps numpy && \
|
||||
$UV_PROJECT_ENVIRONMENT/bin/python -m pip download --no-binary numpy --no-deps numpy && \
|
||||
tar -xzf numpy-*.tar.gz && \
|
||||
cd numpy-*/ && \
|
||||
$VIRTUAL_ENV/bin/python -m build --wheel -Csetup-args=-Dcpu-baseline="none" -Csetup-args=-Dcpu-dispatch="none" && \
|
||||
$UV_PROJECT_ENVIRONMENT/bin/python -m build --wheel -Csetup-args=-Dcpu-baseline="none" -Csetup-args=-Dcpu-dispatch="none" && \
|
||||
mv dist/*.whl /opt/ && \
|
||||
cd / && rm -rf /tmp/numpy-* /tmp/*.tar.gz && \
|
||||
$VIRTUAL_ENV/bin/pip uninstall -y build
|
||||
uv pip uninstall --python $UV_PROJECT_ENVIRONMENT/bin/python build pip
|
||||
|
||||
# --- Clean up build dependencies to reduce image size ---
|
||||
RUN apt-get remove -y build-essential gcc g++ gfortran libopenblas-dev libpcre3-dev python3.13-dev ninja-build && \
|
||||
|
|
|
|||
|
|
@ -27,18 +27,6 @@ echo_with_timestamp() {
|
|||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
|
||||
}
|
||||
|
||||
# --- NumPy version switching for legacy hardware ---
|
||||
if [ "$USE_LEGACY_NUMPY" = "true" ]; then
|
||||
# Check if NumPy was compiled with baseline support
|
||||
if /dispatcharrpy/bin/python -c "import numpy; numpy.show_config()" 2>&1 | grep -qi "baseline"; then
|
||||
echo_with_timestamp "🔧 Switching to legacy NumPy (no CPU baseline)..."
|
||||
/dispatcharrpy/bin/pip install --no-cache-dir --force-reinstall --no-deps /opt/numpy-*.whl
|
||||
echo_with_timestamp "✅ Legacy NumPy installed"
|
||||
else
|
||||
echo_with_timestamp "✅ Legacy NumPy (no baseline) already installed, skipping reinstallation"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set PostgreSQL environment variables
|
||||
export POSTGRES_DB=${POSTGRES_DB:-dispatcharr}
|
||||
export POSTGRES_USER=${POSTGRES_USER:-dispatch}
|
||||
|
|
@ -186,6 +174,19 @@ else
|
|||
pids+=("$nginx_pid")
|
||||
fi
|
||||
|
||||
|
||||
# --- NumPy version switching for legacy hardware ---
|
||||
if [ "$USE_LEGACY_NUMPY" = "true" ]; then
|
||||
# Check if NumPy was compiled with baseline support
|
||||
if $VIRTUAL_ENV/bin/python -c "import numpy; numpy.show_config()" 2>&1 | grep -qi "baseline"; then
|
||||
echo_with_timestamp "🔧 Switching to legacy NumPy (no CPU baseline)..."
|
||||
uv pip install --python $VIRTUAL_ENV/bin/python --no-cache --force-reinstall --no-deps /opt/numpy-*.whl
|
||||
echo_with_timestamp "✅ Legacy NumPy installed"
|
||||
else
|
||||
echo_with_timestamp "✅ Legacy NumPy (no baseline) already installed, skipping reinstallation"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run Django commands as non-root user to prevent permission issues
|
||||
su - $POSTGRES_USER -c "cd /app && python manage.py migrate --noinput"
|
||||
su - $POSTGRES_USER -c "cd /app && python manage.py collectstatic --noinput"
|
||||
|
|
@ -214,7 +215,7 @@ fi
|
|||
# Users can override via UWSGI_NICE_LEVEL environment variable in docker-compose
|
||||
# Start with nice as root, then use setpriv to drop privileges to dispatch user
|
||||
# This preserves both the nice value and environment variables
|
||||
nice -n $UWSGI_NICE_LEVEL su - "$POSTGRES_USER" -c "cd /app && exec /dispatcharrpy/bin/uwsgi $uwsgi_args" & uwsgi_pid=$!
|
||||
nice -n $UWSGI_NICE_LEVEL su - "$POSTGRES_USER" -c "cd /app && exec $VIRTUAL_ENV/bin/uwsgi $uwsgi_args" & uwsgi_pid=$!
|
||||
echo "✅ uwsgi started with PID $uwsgi_pid (nice $UWSGI_NICE_LEVEL)"
|
||||
pids+=("$uwsgi_pid")
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ fi
|
|||
|
||||
# Install frontend dependencies
|
||||
cd /app/frontend && npm install
|
||||
# Install pip dependencies
|
||||
cd /app && pip install -r requirements.txt
|
||||
# Install Python dependencies using UV
|
||||
cd /app && uv sync --python $UV_PROJECT_ENVIRONMENT/bin/python --no-install-project --no-dev
|
||||
|
||||
# Install debugpy for remote debugging
|
||||
if [ "$DISPATCHARR_DEBUG" = "true" ]; then
|
||||
echo "=== setting up debugpy ==="
|
||||
pip install debugpy
|
||||
uv pip install --python $UV_PROJECT_ENVIRONMENT/bin/python debugpy
|
||||
fi
|
||||
|
|
|
|||
56
pyproject.toml
Normal file
56
pyproject.toml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
[project]
|
||||
name = "dispatcharr"
|
||||
description = "Dispatcharr - Stream dispatching and management"
|
||||
readme = "README.md"
|
||||
license = "CC-BY-NC-SA-4.0"
|
||||
requires-python = ">=3.13"
|
||||
dynamic = ["version"]
|
||||
dependencies = [
|
||||
"Django==5.2.9",
|
||||
"psycopg2-binary==2.9.11",
|
||||
"celery[redis]==5.6.0",
|
||||
"djangorestframework==3.16.1",
|
||||
"requests==2.32.5",
|
||||
"psutil==7.1.3",
|
||||
"pillow",
|
||||
"drf-spectacular>=0.29.0",
|
||||
"streamlink",
|
||||
"python-vlc",
|
||||
"yt-dlp",
|
||||
"gevent==25.9.1",
|
||||
"daphne",
|
||||
"uwsgi",
|
||||
"django-cors-headers",
|
||||
"djangorestframework-simplejwt",
|
||||
"m3u8",
|
||||
"rapidfuzz==3.14.3",
|
||||
"regex",
|
||||
"tzlocal",
|
||||
"pytz",
|
||||
"torch==2.9.1+cpu",
|
||||
"sentence-transformers==5.2.0",
|
||||
"channels",
|
||||
"channels-redis==4.3.0",
|
||||
"django-filter",
|
||||
"django-celery-beat",
|
||||
"lxml==6.0.2",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
# PyTorch CPU-only wheels index
|
||||
[[tool.uv.index]]
|
||||
url = "https://download.pytorch.org/whl/cpu"
|
||||
name = "pytorch-cpu"
|
||||
explicit = true
|
||||
|
||||
[tool.uv.sources]
|
||||
torch = { index = "pytorch-cpu" }
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["dispatcharr", "apps", "core"]
|
||||
|
||||
[tool.hatch.version]
|
||||
path = "version.py"
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
Django==5.2.9
|
||||
psycopg2-binary==2.9.11
|
||||
celery[redis]==5.6.0
|
||||
djangorestframework==3.16.1
|
||||
requests==2.32.5
|
||||
psutil==7.1.3
|
||||
pillow
|
||||
drf-spectacular>=0.29.0
|
||||
streamlink
|
||||
python-vlc
|
||||
yt-dlp
|
||||
gevent==25.9.1
|
||||
daphne
|
||||
uwsgi
|
||||
django-cors-headers
|
||||
djangorestframework-simplejwt
|
||||
m3u8
|
||||
rapidfuzz==3.14.3
|
||||
regex # Required by transformers but also used for advanced regex features
|
||||
tzlocal
|
||||
pytz
|
||||
|
||||
# PyTorch dependencies (CPU only)
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu/
|
||||
torch==2.9.1+cpu
|
||||
|
||||
# ML/NLP dependencies
|
||||
sentence-transformers==5.2.0
|
||||
channels
|
||||
channels-redis==4.3.0
|
||||
django-filter
|
||||
django-celery-beat
|
||||
lxml==6.0.2
|
||||
Loading…
Add table
Add a link
Reference in a new issue