Last active
June 1, 2024 03:30
-
-
Save adamghill/419d02e95b1563ad76b0c36995e829b8 to your computer and use it in GitHub Desktop.
Multi-stage Dockerfile with Python and `uv`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Layer with Python and some shared environment variables | |
FROM python:3.10-slim-bullseye as python | |
ENV PYTHONDONTWRITEBYTECODE=1 | |
ENV PYTHONUNBUFFERED=1 | |
# Layer for installing Python dependencies | |
FROM python as dependencies | |
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 | |
ENV VIRTUAL_ENV=/opt/venv | |
# Add some libraries sometimes needed for building Python dependencies, e.g. gcc | |
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/var/lib/apt,sharing=locked \ | |
apt-get update --fix-missing && \ | |
apt-get install --no-install-recommends -y \ | |
build-essential | |
# Copy our Python requirements here | |
COPY ./pyproject.toml . | |
# Install uv and Python dependencies | |
# Note: Turn off pip progress bar because it seemed to cause some issues on deployment | |
# Note: Using a virtualenv seems unnecessary, but it reduces the size of the resulting Docker image | |
RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/root/.cache/uv \ | |
python -m pip config --user set global.progress_bar off && \ | |
python -m pip install --upgrade pip uv && \ | |
uv venv /opt/venv && \ | |
uv pip install --requirement pyproject.toml | |
# Layer with only the Python dependencies needed for serving the app in production | |
FROM python as production | |
# Copy over just the code | |
COPY /site /site | |
# Copy over the virtualenv and add it to the path | |
COPY --from=dependencies /opt/venv /opt/venv | |
ENV PATH="/opt/venv/bin:$PATH" | |
WORKDIR /site | |
EXPOSE 80 | |
# Collect static assets | |
RUN python app.py collectstatic -v 2 --noinput | |
# Compress static assets | |
RUN python app.py compress | |
# Run gunicorn | |
CMD ["gunicorn", "app:wsgi", "--config=gunicorn.conf.py"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I do not understand how/why the
mount=type=cache
is being used here: https://github.com/westerveltco/django-twc-project/blob/2443c1e4e8012e6fef586108d7c4119fbbf4bca6/examples/default/Dockerfile#L51C5-L51C91. It doesn't seem to change anything with my (limited) testing on local.