Skip to content

Commit

Permalink
Add multistage Docker example
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Sep 4, 2024
1 parent 292d997 commit 8b7d86a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
27 changes: 26 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,27 @@ jobs:
cache-to: type=gha,mode=min,scope=uv-docker-example
outputs: type=docker,dest=/tmp/uv-docker-example.tar

- name: Build and export (multistage)
uses: docker/build-push-action@v6
with:
file: Dockerfile.multistage
tags: uv-docker-example-multistage:latest
cache-from: type=gha,scope=uv-docker-example-multistage
cache-to: type=gha,mode=min,scope=uv-docker-example-multistage
outputs: type=docker,dest=/tmp/uv-docker-example-multistage.tar

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: uv-docker-example
path: /tmp/uv-docker-example.tar

- name: Upload artifact (multistage)
uses: actions/upload-artifact@v4
with:
name: uv-docker-example-multistage
path: /tmp/uv-docker-example-multistage.tar

test:
name: "test image"
runs-on: ubuntu-latest
Expand All @@ -49,9 +64,16 @@ jobs:
name: uv-docker-example
path: /tmp

- name: Load image
- name: Download artifact (multistage)
uses: actions/download-artifact@v4
with:
name: uv-docker-example-multistage
path: /tmp

- name: Load images
run: |
docker load --input /tmp/uv-docker-example.tar
docker load --input /tmp/uv-docker-example-multistage.tar
docker image ls -a
- name: Test command line
Expand All @@ -61,3 +83,6 @@ jobs:
run: |
docker compose up --watch -d
docker compose down
- name: Test command line (multistage)
run: docker run uv-docker-example-multistage:latest hello
29 changes: 29 additions & 0 deletions Dockerfile.multistage
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# An example using multi-stage image builds to create a final image without uv.

# First, build the application in the `/app` directory.
# See `Dockerfile` for details.
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen


# Then, use a final image without uv
FROM python:3.12-slim-bookworm
# It is important to use the image that matches the builder, as the path to the
# Python executable must be the same, e.g., using `python:3.11-slim-bookworm`
# will fail.

# Copy the application from the builder
COPY --from=builder --chown=app:app /app /app

# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"

# Run the FastAPI application by default
CMD ["fastapi", "dev", "--host", "0.0.0.0", "/app/src/uv_docker_example"]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ The [`Dockerfile`](./Dockerfile) defines the image and includes:
- Placing environment executables on the `PATH`
- Running the web application

The [`Dockerfile.multistage`](./Dockerfile.multistage) example extends the `Dockerfile` example to
use multistage builds to reduce the final size of the image.

### Dockerignore file

The [`.dockerignore`](./.dockerignore) file includes an entry for the `.venv` directory to ensure the
Expand Down Expand Up @@ -99,3 +102,9 @@ To build the image without running anything:
```console
$ docker build .
```

To build the multistage image:

```console
$ docker build . --file Dockerfile.multistage
```

0 comments on commit 8b7d86a

Please sign in to comment.