Skip to content

Commit 2954597

Browse files
authored
Merge pull request #1100 from readthedocs/copilot/update-docker-config-ubuntu-24-04
Upgrade to Ubuntu 24.04 LTS and Python 3.12 with modern uv dependency management
2 parents b826a87 + 9485e81 commit 2954597

31 files changed

+3959
-1772
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ jobs:
1111

1212
steps:
1313
- uses: actions/checkout@v3
14+
- uses: astral-sh/setup-uv@v4
15+
with:
16+
enable-cache: true
1417
- uses: actions/setup-python@v4
1518
with:
16-
python-version: "3.10"
19+
python-version: "3.12"
20+
21+
- name: Install dependencies
22+
run: |
23+
uv sync --frozen --extra dev
24+
uv tool install tox --with tox-uv
1725
1826
- name: Run CI
1927
run: |
20-
pip install -r requirements/testing.txt
21-
tox
28+
uv run tox

.github/workflows/pip-tools.yaml

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
# Action to run pip-compile weekly and create a Pull Request with the changes.
2-
# Although GitHub says that pip-compile is supported by dependabot, we couldn't make it work together.
3-
# That's why this action exists.
4-
# If we ever find the proper configuration for dependabot+pip-compile,
5-
# we can delete this action.
1+
# Action to run uv lock monthly and create a Pull Request with the changes.
2+
# This keeps dependencies up-to-date by updating uv.lock with the latest
3+
# compatible versions from pyproject.toml.
64

7-
name: Update dependencies with pip-tools
5+
name: Update dependencies with uv
86

97
on:
108
schedule:
@@ -24,30 +22,33 @@ jobs:
2422
runs-on: ubuntu-latest
2523
steps:
2624
- uses: actions/checkout@v4
25+
- uses: astral-sh/setup-uv@v4
26+
with:
27+
enable-cache: true
2728
- uses: actions/setup-python@v5
2829
with:
29-
python-version: "3.10"
30+
python-version: "3.12"
3031

3132
- name: Install "pg_config" requirement
3233
run: sudo apt-get install libpq-dev
3334

34-
- name: Install piptools
35-
run: python -m pip install -U pip-tools
36-
37-
- name: Update dependencies from requirements/*.txt
38-
run: ./requirements/update.sh
35+
- name: Update dependencies with uv lock
36+
run: uv lock --upgrade
3937

4038
- name: Create Pull Request
4139
uses: peter-evans/create-pull-request@v6
4240
with:
4341
add-paths: |
44-
requirements/*.txt
42+
uv.lock
4543
title: |
46-
Dependencies: all packages updated via pip-tools
44+
Dependencies: all packages updated via uv lock
4745
body: |
48-
Dependencies: all packages updated via pip-tools
46+
Dependencies: all packages updated via uv lock
47+
48+
This PR updates the `uv.lock` file with the latest compatible versions
49+
of all dependencies specified in `pyproject.toml`.
4950
commit-message: |
50-
Dependencies: all packages updated via pip-tools
51+
Dependencies: all packages updated via uv lock
5152
delete-branch: true
52-
branch: dependencies/pip-tools
53+
branch: dependencies/uv-lock
5354
branch-suffix: short-commit-hash

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,4 @@ geoip/*
9595
# ML models for topic classification
9696
trainingset-urls-cache.sqlite
9797
/machine_learning_experiments/assets/*.json
98+
.venv/

.pre-commit-config.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ repos:
77
- id: trailing-whitespace
88
exclude: '.*/dnt-policy.txt$'
99
- repo: https://github.com/adamchainz/django-upgrade
10-
rev: "1.14.1"
10+
rev: "1.29.1"
1111
hooks:
1212
- id: django-upgrade
13-
args: [--target-version, "4.2"]
13+
args: [--target-version, "5.2"]
1414
- repo: https://github.com/astral-sh/ruff-pre-commit
1515
# Ruff version.
1616
rev: v0.5.2
@@ -20,3 +20,9 @@ repos:
2020
args: [ --fix ]
2121
# Run the formatter.
2222
- id: ruff-format
23+
- repo: https://github.com/astral-sh/uv-pre-commit
24+
# uv version.
25+
rev: 0.9.10
26+
hooks:
27+
# Compile requirements to ensure uv.lock is up-to-date
28+
- id: uv-lock

Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ help:
1818
@echo " geoip Download the GeoIP databases"
1919
@echo " ipproxy Download proxy databases"
2020

21+
# Run the full test suite
22+
# Run a specific test with tox -e py3 -- adserver/auth/tests.py
2123
test:
2224
tox
2325

@@ -46,11 +48,11 @@ dockerstop:
4648
# Use this command to inspect the container, run management commands,
4749
# or run anything else on the Django container
4850
dockershell:
49-
docker compose -f $(DOCKER_CONFIG) run --rm django /bin/bash
51+
docker compose -f $(DOCKER_CONFIG) run --rm django /shell
5052

5153
# Get the GeoIP databases from DB-IP or Maxmind
5254
geoip:
53-
python $(GEOIP_DOWNLOADER) --geoip-only --outdir=$(GEOIP_DIR)
55+
uv run python $(GEOIP_DOWNLOADER) --geoip-only --outdir=$(GEOIP_DIR)
5456

5557
ipproxy:
56-
python $(GEOIP_DOWNLOADER) --ipproxy-only --outdir=$(GEOIP_DIR)
58+
uv run python $(GEOIP_DOWNLOADER) --ipproxy-only --outdir=$(GEOIP_DIR)

docker-compose/django/Dockerfile

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
FROM ubuntu:22.04
1+
FROM ubuntu:24.04
22

33
ENV DEBIAN_FRONTEND noninteractive
44
ENV LANG en_US.UTF-8
55
ENV LANGUAGE en_US:en
66
ENV LC_ALL en_US.UTF-8
77
ENV PYTHONUNBUFFERED 1
88

9+
# uv environment variables
10+
# Copy (don't hardlink) files into /.venv. Avoid issues with Docker's FS
11+
# https://docs.astral.sh/uv/reference/environment/
12+
ENV UV_LINK_MODE=copy
13+
ENV UV_PROJECT_ENVIRONMENT=/.venv
14+
15+
916
RUN apt-get -y update
1017
RUN apt-get -y install \
1118
curl \
@@ -17,45 +24,56 @@ RUN apt-get -y install \
1724
libxslt1-dev \
1825
locales \
1926
build-essential \
20-
python3-pip \
21-
python3-dev \
2227
postgresql-client \
2328
libmysqlclient-dev \
2429
libfreetype6 \
2530
libjpeg-dev \
26-
sqlite \
27-
netcat \
31+
sqlite3 \
32+
netcat-openbsd \
2833
telnet \
2934
lsb-release
3035

31-
# Requirements are installed here to ensure they will be cached.
32-
# https://docs.docker.com/build/cache/#use-the-dedicated-run-cache
33-
COPY ./requirements /requirements
34-
RUN pip install --upgrade pip
35-
RUN --mount=type=cache,target=/root/.cache/pip pip install -r /requirements/development.txt
36-
RUN --mount=type=cache,target=/root/.cache/pip pip install -r /requirements/production.txt
36+
# Install uv for fast package management
37+
# https://docs.astral.sh/uv/guides/integration/docker/#installing-uv
38+
ADD https://astral.sh/uv/install.sh /uv-installer.sh
39+
RUN sh /uv-installer.sh && rm /uv-installer.sh
40+
ENV PATH="/root/.local/bin/:$PATH"
41+
42+
# Copy project files for dependency resolution
43+
# uv.lock ensures reproducible builds
44+
COPY pyproject.toml uv.lock ./
3745

38-
# Comment this if you don't need the page/topic analyzer.
39-
# The analyzer is used to target ads better based on page content.
40-
# Its requirements are huge and include PyTorch and other ML tools.
41-
# If not needed, make sure to set `ADSERVER_ANALYZER_BACKEND=` (empty string)
42-
# in your environment file `./envs/local/django`.
43-
RUN --mount=type=cache,target=/root/.cache/pip pip install -r /requirements/analyzer.txt
46+
# Install Python through uv
47+
# Get the version pinned by pyproject.toml
48+
RUN uv python install
49+
50+
# Install dependencies using uv sync
51+
# This creates a virtual environment at /.venv (not in /app)
52+
# This installs all dependencies from uv.lock, ensuring consistency
53+
# --frozen: Don't update the lockfile
54+
# --no-install-project: Don't install the project itself
55+
# If you do not want the analyzer dependencies (which are LARGE), you can use:
56+
# RUN --mount=type=cache,target=/root/.cache/uv \
57+
# uv sync --frozen --no-install-project --extra dev --extra production
58+
RUN --mount=type=cache,target=/root/.cache/uv \
59+
uv sync --frozen --no-install-project --all-extras
4460

4561
COPY ./docker-compose/django/start /start
4662
RUN chmod +x /start
4763

64+
# Launch a shell within the container with this script
65+
COPY ./docker-compose/django/shell /shell
66+
RUN chmod +x /shell
67+
4868
COPY ./docker-compose/django/celery/worker/start /start-celeryworker
4969
RUN chmod +x /start-celeryworker
5070

5171
COPY ./docker-compose/django/celery/beat/start /start-celerybeat
5272
RUN chmod +x /start-celerybeat
5373

54-
# Ensure that ``python`` is in the PATH so that ``./manage.py`` works
55-
RUN ln -s /usr/bin/python3 /usr/bin/python
56-
5774
# Load model
58-
RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('multi-qa-MiniLM-L6-cos-v1', cache_folder='/tmp/sentence_transformers')"
75+
# Not needed if you don't use the analyzer
76+
RUN uv run python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('multi-qa-MiniLM-L6-cos-v1', cache_folder='/tmp/sentence_transformers')"
5977

6078
# Setup the locale
6179
RUN locale-gen en_US.UTF-8

docker-compose/django/celery/beat/start

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ set -o nounset
55

66

77
rm -f './celerybeat.pid'
8-
celery -A config.celery_app beat -l INFO
8+
uv run celery -A config.celery_app beat -l INFO

docker-compose/django/celery/worker/start

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ set -o errexit
44
set -o nounset
55

66

7-
celery -A config.celery_app worker -l INFO -Q celery,analyzer,priority -c 1
7+
uv run celery -A config.celery_app worker -l INFO -Q celery,analyzer,priority -c 1

docker-compose/django/shell

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
set -o nounset
6+
7+
8+
# Use the venv created by `uv sync` in the Dockerfile
9+
source /.venv/bin/activate
10+
11+
# Start shell with the venv activated
12+
/bin/bash

docker-compose/django/start

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ set -o errexit
44
set -o pipefail
55
set -o nounset
66

7+
78
# Reinstall dependencies without rebuilding docker image
89
# pip install -r /app/requirements/development.txt
910

1011
# Don't auto-migrate locally because this can cause weird issues when testing migrations
1112
# python manage.py migrate
12-
python manage.py runserver 0.0.0.0:5000
13+
uv run ./manage.py runserver 0.0.0.0:5000
1314

1415
# In production, we use gunicorn
1516
# This gets us close to that setting for development and testing

0 commit comments

Comments
 (0)