astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
27.17k stars 785 forks source link

Unable to package django app with staticfiles #9352

Open Mapiarz opened 9 hours ago

Mapiarz commented 9 hours ago

Hi. I have a django app and I cannot build a docker image with django's staticfiles artifact.

Here's my dockerfile (this is just the first stage of my image, in the second stage I copy the environment)

FROM python:3.11-slim-bookworm AS builder

COPY --from=ghcr.io/astral-sh/uv:0.5 /uv /bin/

WORKDIR /myapp

# Copy app source code
...

# Create the virtual environment with myapp in it
RUN uv sync --frozen --no-dev --no-cache --compile-bytecode --no-editable

# Activate the environment - we will need it for commands below
ENV PATH="/myapp/.venv/bin:$PATH"

# Install static files
RUN COLLECT_STATIC=True python manage.py collectstatic

# Add the static files to .venv
RUN uv sync --frozen --no-dev --no-cache --compile-bytecode --no-editable

This is a pretty simple set up. Copy the app source code, run uv sync to install all the dependencies. Once that's done, I can start up my django app and collect the static files. The files are placed in the source folder. Then, I run uv sync again so that the staticfiles are copied to virtual environment. The problem is they are not.

#16 [builder  8/10] RUN uv sync --frozen --no-dev --no-cache --compile-bytecode --no-editable
#16 0.257 Using CPython 3.11.10 interpreter at: /usr/local/bin/python3
#16 0.257 Creating virtual environment at: .venv
#16 3.969 Prepared 141 packages in 3.69s
#16 4.107 Installed 141 packages in 138ms
#16 5.654 Bytecode compiled 6109 files in 1.54s
...
#16 DONE 6.2s

#17 [builder  9/10] RUN COLLECT_STATIC=True python manage.py collectstatic
#17 1.869 177 static files copied to '/myapp/myapp/staticfiles', 497 post-processed.
#17 DONE 2.4s

#18 [builder 10/10] RUN uv sync --frozen --no-dev --no-cache --compile-bytecode --no-editable
#18 0.216 Audited 141 packages in 0.52ms
#18 DONE 0.2s

Here's also the relevant part in pyproject.toml

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.metadata]
allow-direct-references = true

[tool.hatch.build.targets.wheel]
only-include = ["myapp", "manage.py"]
artifacts = ["myapp/staticfiles"]

I'm completely lost on what's going on for 2 primary reasons:

  1. In my local dev env, I can follow this procedure and it works: uv sync, collect static files, uv sync again and the app is packaged correctly with the static files.
  2. I can add RUN rm -rf .venv to my dockerfile before the second invocation of uv sync and the static files will be then collected correctly.

Please advise.

charliermarsh commented 5 hours ago

Thanks for the issue. I think I wouldn't expect this to work either locally or in CI, because we won't re-build / re-install your project after the static files are generated. By default, we only re-build / re-install local projects if the pyproject.toml, setup.py, or setup.cfg files change -- it's similar to https://docs.astral.sh/uv/concepts/cache/#dynamic-metadata, but this is about extra content and not dynamic metadata per se.

I think you probably want --reinstall-package {project_name} in the second command.