Deploying Django/Python apps that use uv?

I can’t seem to find any info on this - but does fly.io support deploying Python apps that are using uv (rather than say, poetry)?

When I tried to do a fly launch, fly deploy on a new Python app, I got the following error message, that seems to be related to Docker, and expecting some Poetry file?

Secrets are staged for the first deployment
Wrote config file fly.toml

[INFO] Python 3.12.9 was detected. 'python:3.12-slim' image will be set in the Dockerfile.

Validating /Users/foobar/code/plantsale/fly.toml
✓ Configuration is valid
==> Building image
==> Building image with Depot
--> build:  ()
[+] Building 3.3s (9/12)
 => [internal] load build definition from Dockerfile                                                                                                                                                                                      0.1s
 => => transferring dockerfile: 484B                                                                                                                                                                                                      0.1s
 => [internal] load metadata for docker.io/library/python:3.12-slim                                                                                                                                                                       2.8s
 => [internal] load .dockerignore                                                                                                                                                                                                         0.2s
 => => transferring context: 107B                                                                                                                                                                                                         0.1s
 => [1/8] FROM docker.io/library/python:3.12-slim@sha256:85824326bc4ae27a1abb5bc0dd9e08847aa5fe73d8afb593b1b45b7cb4180f57                                                                                                                 0.2s
 => => resolve docker.io/library/python:3.12-slim@sha256:85824326bc4ae27a1abb5bc0dd9e08847aa5fe73d8afb593b1b45b7cb4180f57                                                                                                                 0.0s
 => [internal] load build context                                                                                                                                                                                                         0.2s
 => => transferring context: 16.51kB                                                                                                                                                                                                      0.1s
 => CACHED [2/8] RUN mkdir -p /code                                                                                                                                                                                                       0.0s
 => CACHED [3/8] WORKDIR /code                                                                                                                                                                                                            0.0s
 => CACHED [4/8] RUN pip install poetry                                                                                                                                                                                                   0.0s
 => ERROR [5/8] COPY pyproject.toml poetry.lock /code/                                                                                                                                                                                    0.0s
------
 > [5/8] COPY pyproject.toml poetry.lock /code/:
------
==> Building image
==> Building image with Depot
--> build:  ()
[+] Building 0.9s (9/12)
 => [internal] load build definition from Dockerfile                                                                                                                                                                                      0.2s
 => => transferring dockerfile: 484B                                                                                                                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/python:3.12-slim                                                                                                                                                                       0.3s
 => [internal] load .dockerignore                                                                                                                                                                                                         0.1s
 => => transferring context: 107B                                                                                                                                                                                                         0.0s
 => [1/8] FROM docker.io/library/python:3.12-slim@sha256:85824326bc4ae27a1abb5bc0dd9e08847aa5fe73d8afb593b1b45b7cb4180f57                                                                                                                 0.3s
 => => resolve docker.io/library/python:3.12-slim@sha256:85824326bc4ae27a1abb5bc0dd9e08847aa5fe73d8afb593b1b45b7cb4180f57                                                                                                                 0.0s
 => => sha256:e9ddbe7a005f6950194f9ec89ccfff2c86729491901f767d8b03f8062de3daf5 0B / 249B                                                                                                                                                  0.3s
 => => sha256:b3b4f30c6749b72e9b25139714a21ee8c3c5689b213a023c7b42be2634cfc320 0B / 13.66MB                                                                                                                                               0.3s
 => => sha256:6cca951a45d16183402c0ea0d763285dff4024af76a75119fb405268bc35c359 0B / 3.51MB                                                                                                                                                0.2s
 => => sha256:8a628cdd7ccc83e90e5a95888fcb0ec24b991141176c515ad101f12d6433eb96 0B / 28.23MB                                                                                                                                               0.1s
 => [internal] load build context                                                                                                                                                                                                         0.0s
 => => transferring context: 1.54kB                                                                                                                                                                                                       0.0s
 => CANCELED [2/8] RUN mkdir -p /code                                                                                                                                                                                                     0.0s
 => CACHED [3/8] WORKDIR /code                                                                                                                                                                                                            0.0s
 => CACHED [4/8] RUN pip install poetry                                                                                                                                                                                                   0.0s
 => ERROR [5/8] COPY pyproject.toml poetry.lock /code/                                                                                                                                                                                    0.0s
------
 > [5/8] COPY pyproject.toml poetry.lock /code/:
------
Error: failed to fetch an image or build from source: error building: failed to solve: failed to compute cache key: failed to calculate checksum of ref jgqfcjz2o3vk6iuhtrbbximt6::i8jkw9y7vt3cfpjntoevw6weq: "/poetry.lock": not found

Or is there something different/special you need to do to get uv working?

1 Like

Hi Victor,

uv has taken the Python world by storm. Unfortunately flyctl was stuck in a storm shelter and missed all of it - our Django project scanner/configurer is not aware of uv and if it finds pyproject.toml it’ll assume you’re using Poetry and mess up the install as you saw here.

The two main things you can do right now are:

  • Create a Dockerfile for your project by hand, test it locally to ensure it builds and starts properly, and use that instead of relying on fly launch to create a Dockerfile for you.
  • Move pyproject.toml out of the way and put your dependencies in requirements.txt, this should be properly handled by flyctl.

I generally recommend the first option as you’ll have better control and ability to debug your build if you take a bit of time to learn how to dockerize applications.

I’ll look into adding support for uv-managed projects to flyctl but it’ll understandably take a bit oif time :slight_smile:

  • Daniel

I’ll help.

Victor, if you have questions about Dockerfiles, post them here and we will answer them. For example, the error you are seeing is that build step trying to copy poetry.lock from your machine and not finding it.

Once we (together) have a working Dockerfile, we can work backwards from there and make the necessary adjustments to flyctl.

A tool that we have almost ready to go is dockerfile-django, which is written in Python and has tests. We can add the desired Dockerfile as a test case and work back from there to get the tests passing.

Hi, I just encountered the exact same issue. My problem is that I don’t really know how to start a Dockerfile. The page here doesn’t give a simple starting point. Is there any simple Dockerfile example that I can start with?

Thanks!

Ok, I just managed to make it work, with this Dockerfile (based on Using uv with FastAPI | uv):

FROM python:3.12-slim

# Install uv.
COPY --from=ghcr.io/astral-sh/uv:0.5.0 /uv /uvx /bin/

# Copy the application into the container.
COPY . /app

# Install the application dependencies.
WORKDIR /app
RUN uv sync --frozen --no-cache

EXPOSE 80

# Run the application.
CMD ["/app/.venv/bin/fastapi", "run", "main.py", "--port", "80", "--host", "0.0.0.0"]

2 Likes