uv-docker-example

repository·main·Indexed 21 days ago

https://github.com/astral-sh/uv-docker-example

An example project demonstrating best practices for using uv within Docker images. It covers efficient development workflows using bind mounts, Docker Compose watch for hot-reloading, and provides three Dockerfile variants: Standard (development), Multistage (production), and Standalone (production with managed Python interpreters).

Tokens
1.2K
Snippets
7
Records
8
Agent score
74%

What's inside uv-docker-example

  1. Understand the available Dockerfile variants

    main

    The project provides three different Dockerfile approaches depending on your environment needs:

    1. Standard (Dockerfile): Optimized for development. It installs uv, installs project dependencies and the project itself separately to maximize build cache efficiency, adds environment executables to the PATH, and runs the web application in development mode.
    2. Multistage (multistage.Dockerfile): Optimized for production. It uses multistage builds to reduce the final image size and runs the application in production mode.
    3. Standalone (standalone.Dockerfile): Optimized for production with controlled runtimes. It extends the multistage approach but uses a managed Python interpreter instead of the system interpreter provided by the base image.

    To build the multistage production image:

    docker build . --file multistage.Dockerfile
  2. Try out the uv-docker-example project

    main

    You can quickly build and run the project using the provided run.sh utility. This script implements best practices for local development by using bind mounts for both the project source and the virtual environment directories, allowing changes to be reflected immediately.

    To start the web application:

    ./run.sh

    Once running, access the application at http://localhost:8000.

    To run the specific command-line entrypoint (hello) instead of the web server:

    ./run.sh hello
    #!/bin/bash
    ./run.sh
  3. Run the project using Docker Compose with watch

    main

    For a more robust development workflow, use the provided Docker Compose configuration. This setup utilizes the Docker Compose watch directive, which is a best-practice method for updating the container automatically when local files change.

    To build and run the application with file watching enabled:

    docker compose up --watch
    docker compose up --watch
  4. Configure the web service in compose.yml

    main

    The compose.yml file defines a web service for running the FastAPI application. It handles building the image from the local directory, mapping ports, and setting environment variables for development.

    Key configurations include:

    • Build: Uses the Dockerfile in the current directory (.).
    • Ports: Maps host port 8000 to container port 8000.
    • Environment: Sets UV_NO_DEV=0 to ensure development dependencies are included during local work.
    • User: Runs as root to allow a mutable environment during development. Alternatively, you can set UV_PROJECT_ENVIRONMENT to a path owned by a non-root user.
    services:
      web:
        build: .
        ports:
          - "8000:8000"
        environment:
          - UV_NO_DEV=0
        user: root
  5. Configure Docker Compose Watch for hot-reloading

    main

    The develop.watch section in compose.yml enables automatic updates to the running container without manual restarts. It uses two distinct actions:

    1. sync: Synchronizes the local working directory with the /app directory in the container. It is configured to ignore the .venv/ directory to prevent platform-specific virtual environment conflicts.
    2. rebuild: Automatically triggers an image rebuild if the uv.lock file changes, ensuring dependencies are always up to date.

    Refer to Docker Compose file watch documentation for more details.

    develop:
      watch:
        - action: sync
          path: .
          target: /app
          ignore:
            - .venv/
        - action: rebuild
          path: ./uv.lock
  6. Useful commands for managing the container

    main

    Use these commands to interact with the containerized environment:

    Sync the environment To ensure the environment is up-to-date after an image build:

    ./run.sh uv sync --locked

    Access the container shell To enter a bash shell inside the running container:

    ./run.sh /bin/bash

    Manual builds To build the standard image without running it:

    docker build .
    # Sync environment
    ./run.sh uv sync --locked
    
    # Enter bash
    ./run.sh /bin/bash
    
    # Build standard image
    docker build .