9.1 The dev image installs every group
Read the tutorial. Build it yourself is the other way to read this part.
This walk goes through rahuldave/cheesecracker on GitHub. This part starts from the code at step-08. The code before this part
To look at this code on your machine, run these commands. The first one makes a clone, if this folder has none:
[ -d cheesecracker ] || git clone https://github.com/rahuldave/cheesecracker
cd cheesecracker
git fetch --quiet --tags --force origin
git switch --detach step-08just setupThe whole tutorial then adds the system tests, and the recipe just test-system. The dev image is for working on the
project, so it installs every group.
9.1 the dev image, to work on the project in Linux
The dev image is a fourth stage of the Dockerfile, dev. It takes uv from the stage uv, and nothing from the
run image.
± See the change to Dockerfile
The stage dev installs git and curl, copies uv, and installs just as a package of PyPI. It installs every group of
uv.lock into /opt/venv, copies the project into /work, and starts a shell. /opt/venv is outside /work, so a
.venv of this machine in a mounted folder is never used.
docker build --target dev --tag cheesecracker-dev .Near the end, the line naming to docker.io/library/cheesecracker-dev names the image.
docker image ls cheesecracker-devThe image is about 353 MB, twice the run image, because it has every tool.
What changed
Dockerfile: the stagedev, and its lines in the comment at the top. 26 lines added. The file- look at
FROM python:3.12-slim-bookworm AS dev
- look at
The diff of Dockerfile
@@ -2,6 +2,8 @@
#
# docker build --target run --tag cheesecracker-run .
# the production image: Python, the dependencies of the server and its code. It starts the server
+# docker build --target dev --tag cheesecracker-dev .
+# the development image: every dependency group, uv, just and git. It starts a shell
#
# The environment lives in /opt/venv, never in the project folder.
@@ -32,3 +34,27 @@ USER app
EXPOSE 9000
# Four workers, and no restart on a change: the server as it runs in production
CMD ["uvicorn", "api.service:app", "--host", "0.0.0.0", "--port", "9000", "--workers", "4"]
+
+# The dev image: the whole project with every dependency group, and uv, just and git to work in it
+FROM python:3.12-slim-bookworm AS dev
+# hadolint ignore=DL3008
+RUN apt-get update \
+ && apt-get install --yes --no-install-recommends ca-certificates curl git \
+ && rm -rf /var/lib/apt/lists/*
+COPY --from=uv /uv /uvx /usr/local/bin/
+ENV UV_PROJECT_ENVIRONMENT=/opt/venv \
+ UV_PYTHON_DOWNLOADS=never \
+ UV_LINK_MODE=copy \
+ UV_NO_CACHE=1 \
+ UV_TOOL_BIN_DIR=/usr/local/bin \
+ PATH=/opt/venv/bin:$PATH \
+ PYTHONUNBUFFERED=1
+# just, as a wheel from PyPI. git refuses a folder that another user owns, and a mounted folder
+# belongs to the user of the host, so every folder is safe
+RUN uv tool install "rust-just==1.50.0" \
+ && git config --system --add safe.directory '*'
+WORKDIR /work
+COPY pyproject.toml uv.lock .python-version ./
+RUN uv sync --locked
+COPY . .
+CMD ["bash"]This part ends at the code at ccf62d330f28, partway through step-09. The code after this part