Skip to content

Conversation

@lukel97
Copy link
Contributor

@lukel97 lukel97 commented Dec 2, 2025

This resolves the conversation at #117 (comment)

Currently we install the build dependencies like g++ (RUN apk add...) in a separate layer. We try and purge them in a later step but this doesn't achieve anything because docker caches everything on a layer by layer basis, i.e. the previous layer will still contain them and hang around.

This fixes it by making sure they are installed and purged in the same layer, which reduces the image size by ~500MB:

$ docker image ls
lnt-old-dockerfile      <none>      76a17f3f65ed   5 seconds ago       797MB
lnt-new-dockerfile      latest      f3e7d5487142   3 minutes ago       232MB

This patch also only copies over the minimal source files required so as to make sure the dependencies layer is invalidated as infrequently as possible. E.g. here is an example of building the image after touching a regular python source file. We no longer need to rebuild or redownload the dependencies, that layer is cached:

$ docker build -f docker/lnt.dockerfile .
[+] Building 6.0s (12/12) FINISHED                                                                                 docker:default
 => [internal] load build definition from lnt.dockerfile                                                                     0.0s
 => => transferring dockerfile: 1.72kB                                                                                       0.0s
 => [internal] load metadata for docker.io/library/python:3.10-alpine                                                        0.7s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => [internal] load build context                                                                                            0.1s
 => => transferring context: 615.05kB                                                                                        0.1s
 => [1/7] FROM docker.io/library/python:3.10-alpine@sha256:63f6d26c66126481336273c8d34a2017729843ac3b2de2897c428f27e066f1be  0.0s
 => CACHED [2/7] COPY pyproject.toml .                                                                                       0.0s
 => CACHED [3/7] COPY lnt/testing/profile lnt/testing/profile                                                                0.0s
 => CACHED [4/7] RUN apk update   && apk add --no-cache --virtual .build-deps g++ postgresql-dev yaml-dev   && apk add --no  0.0s
 => [5/7] COPY . .                                                                                                           0.5s
 => [6/7] RUN pip install .                                                                                                  4.2s
 => [7/7] COPY docker/docker-entrypoint.sh docker/docker-entrypoint-log.sh docker/lnt-wait-db /usr/local/bin/                0.0s 
 => exporting to image                                                                                                       0.4s 
 => => exporting layers                                                                                                      0.4s 
 => => writing image sha256:10a811e65c9d51b111626af2b1735e4df997e2390e8819615ab8d32c63c04559                                 0.0s

We need to copy the cperf ext-module sources over and build that up front while we still have g++, and we need to copy over pyproject.toml to satisfy setuptools_scm. We also need to use a mock version for setuptools_scm, since it looks for a .git folder and we want to avoid copying that. That would cause the layer to be invalidated on every commit.

&& apk add --no-cache libpq
&& apk add --no-cache --virtual .build-deps g++ postgresql-dev yaml-dev \
&& apk add --no-cache git libpq \
&& pip install ".[server]" \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also switched from requirements.server.txt to the dependencies in pyproject.toml in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant