Skip to content

Commit b170fb6

Browse files
committed
Dynamic version support with UV
1 parent 4999fbd commit b170fb6

8 files changed

Lines changed: 73 additions & 86 deletions

File tree

.diploi/helm/app.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,22 @@ spec:
4141
command: ["/bin/sh", "-c"]
4242
args:
4343
- |
44-
uv sync --frozen --no-cache --link-mode=copy && \
45-
cp --remove-destination "$(readlink /app{{ .Values.folder }}/.venv/bin/python)" /app{{ .Values.folder }}/.venv/bin/python 2>/dev/null || :
44+
set -e
45+
uv python install {{ ((.Values.envMap.PYTHON_VERSION).value | default "3.12") | quote }}
46+
uv venv .venv --clear
47+
if [ -f pyproject.toml ]; then
48+
uv sync
49+
elif [ -f requirements.txt ]; then
50+
uv pip install -r requirements.txt
51+
fi
4652
workingDir: /app{{ .Values.folder }}
4753
env:
4854
- name: DJANGO_ENV
4955
value: development
56+
- name: UV_PYTHON
57+
value: {{ ((.Values.envMap.PYTHON_VERSION).value | default "3.12") | quote }}
58+
- name: UV_PYTHON_INSTALL_DIR
59+
value: /app{{ .Values.folder }}/.python
5060
volumeMounts:
5161
- name: app-mount
5262
mountPath: /app
@@ -76,6 +86,10 @@ spec:
7686
{{- end }}
7787
{{- end }}
7888
env:
89+
- name: UV_PYTHON
90+
value: {{ ((.Values.envMap.PYTHON_VERSION).value | default "3.12") | quote }}
91+
- name: UV_PYTHON_INSTALL_DIR
92+
value: /app{{ .Values.folder }}/.python
7993
{{- range .Values.env }}
8094
- name: {{ .identifier }}
8195
value: {{ .value | quote }}

.python-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

Dockerfile

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
1-
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS base
1+
# Use a Python image with uv pre-installed
2+
FROM ghcr.io/astral-sh/uv:bookworm-slim
23

4+
# This will be set by the GitHub action to the folder containing this component.
35
ARG FOLDER=/app
46

7+
# This will be set by the GitHub action if "PYTHON_VERSION" ENV is set in diploi.yaml
8+
ARG PYTHON_VERSION=3.12
9+
10+
RUN mkdir -p /.cache/uv && chown -R 1000:1000 /.cache
11+
RUN mkdir -p /.local/share/uv/python && chown -R 1000:1000 /.local/share/uv
12+
13+
COPY --chown=1000:1000 . /app
514
WORKDIR ${FOLDER}
615

716
ENV UV_COMPILE_BYTECODE=1
817
ENV UV_LINK_MODE=copy
9-
ENV UV_TOOL_BIN_DIR=/usr/local/bin
10-
11-
12-
COPY . /app
13-
RUN uv sync --locked --no-dev --group deploy
14-
1518
ENV PATH="$FOLDER/.venv/bin:$PATH"
19+
ENV UV_PYTHON=${PYTHON_VERSION}
20+
ENV HOME=/tmp
1621

22+
USER 1000:1000
1723

18-
FROM base AS release
19-
20-
WORKDIR ${FOLDER}
21-
22-
RUN apk add --no-cache shadow
23-
24-
RUN groupadd -g 1000 devgroup && \
25-
useradd -u 1000 -g 1000 -m devuser
24+
RUN uv python install ${PYTHON_VERSION} && \
25+
uv venv .venv && \
26+
if [ -f pyproject.toml ]; then \
27+
uv sync --locked --no-dev || uv sync --no-dev; \
28+
elif [ -f requirements.txt ]; then \
29+
uv pip install -r requirements.txt; \
30+
fi
2631

27-
RUN chown -R devuser:devgroup /app
32+
# Install gunicorn in the virtual environment if it's not already installed
33+
RUN uv pip show --python .venv/bin/python gunicorn >/dev/null 2>&1 || \
34+
uv pip install --python .venv/bin/python gunicorn --link-mode=copy
2835

36+
# Collect static files
2937
RUN uv run --locked --no-dev python manage.py collectstatic --noinput
3038

31-
USER devuser
32-
33-
ENTRYPOINT []
34-
35-
EXPOSE 8000
36-
ENV PORT=8000
37-
ENV HOST="0.0.0.0"
38-
3939
CMD ["uv","run","gunicorn","djangoapp.wsgi:application","--bind", "0.0.0.0:8000","--workers", "3", "--log-level", "info"]

Dockerfile.dev

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,23 @@
1-
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS base
1+
FROM ghcr.io/astral-sh/uv:bookworm-slim
22

3+
# This will be set by the GitHub action to the folder containing this component.
34
ARG FOLDER=/app
45

5-
WORKDIR ${FOLDER}
6-
7-
ENV UV_COMPILE_BYTECODE=1
8-
ENV UV_TOOL_BIN_DIR=/usr/local/bin
9-
ENV PATH="$FOLDER/.venv/bin:$PATH"
10-
11-
RUN apk add --no-cache shadow \
12-
&& apk add --no-cache nodejs npm \
13-
&& npm install -g nodemon
14-
15-
RUN groupadd -g 1000 devgroup && \
16-
useradd -u 1000 -g 1000 -m devuser
17-
18-
COPY . /app
19-
20-
RUN mkdir -p /.cache/uv && chown devuser:devgroup -R /.cache /.cache/uv
6+
# This will be set by the GitHub action to the folder containing this component.
7+
ARG FOLDER=/app
218

22-
RUN chown -R devuser:devgroup /app
9+
RUN mkdir /app && chown 1000:1000 /app
2310

24-
RUN uv venv \
25-
&& uv sync
11+
RUN mkdir -p /.cache/uv && chown -R 1000:1000 /.cache
12+
RUN mkdir -p /.local/share/uv/python && chown -R 1000:1000 /.local/share/uv
13+
RUN mkdir -p /.local/bin && chown -R 1000:1000 /.local/bin
2614

27-
USER devuser
15+
WORKDIR /app
2816

29-
EXPOSE 8000
17+
ENV UV_LINK_MODE=copy
18+
ENV UV_PYTHON_INSTALL_DIR=$FOLDER/.python
19+
ENV PATH="$FOLDER/.venv/bin:$PATH"
3020

31-
ENTRYPOINT [ ]
21+
USER 1000:1000
3222

33-
CMD ["/usr/local/bin/nodemon", \
34-
"--delay", "1", \
35-
"--watch", "requirements.txt", \
36-
"--watch", ".venv/lib/*", \
37-
"--watch", ".venv/lib64/*", \
38-
"--watch", "djangoapp", \
39-
"--watch", "manage.py", \
40-
"--ext", "py", \
41-
"--exec", "uv run --isolated python3 manage.py runserver 0.0.0.0:8000", \
42-
"--"]
23+
CMD ["uv", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"]

README.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,11 @@ Uses the official [astral-sh/uv:3.13-alpine](https://github.com/astral-sh/uv/pkg
4343

4444
### Development
4545

46-
Will run
47-
`uv sync`
48-
when component is first initialized, and `uv run --isolated python3 manage.py runserver 0.0.0.0:8000` when deployment is started.
46+
Will run `uv sync` for pyproject.toml or `uv pip install -r requirements.txt` for requirements.txt
47+
when component is first initialized, and `uv run python manage.py runserver 0.0.0.0:8000` when deployment is started.
4948

5049
### Production
5150

52-
Will build a production ready image. The first step runs the command:
53-
`uv sync --locked --no-dev --group deploy`
54-
Which installs **gunicorn**, as part of `--group=deploy` in `pyproject.toml`, to install all necessary dependencies for production.
55-
5651
To get all static files, the image runs the command:
5752
`uv run --locked --no-dev python manage.py collectstatic --noinput` to get all static files.
5853

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ name = "djangoapp"
33
version = "0.1.0"
44
description = "Add your description here"
55
readme = "README.md"
6-
requires-python = ">=3.13"
6+
requires-python = ">=3.12"
77
dependencies = [
8-
"Django==5.2.9",
9-
"environs==14.2.0",
8+
"Django==6.0.3",
9+
"environs==15.0.0",
1010
]
1111

1212
[dependency-groups]
13-
deploy = ["gunicorn==22.0.0",]
13+
deploy = ["gunicorn==25.3.0",]

requirements.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

uv.lock

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)