Skip to content

Commit d51692f

Browse files
committed
Dockerfile: Maintenance
All temporary files need to be deleted in every `RUN` command to avoid adding it in a layer. Removing them in a later `RUN` command will still make them bloat the final image. Instead of copying files temporarily they should be mounted in the `RUN` command where they are needed. This avoids the need to delete them at the end of the command. Environment variables that are intended only for when the container is built should be prepended on the lines where they are needed to avoid polluting the environment in the running container. We should strive to have as few layers as possible, but still enough to simplify debugging the container image. When you only have 1 layer it is not possible to create intermediate images and inspect the state of the image.
1 parent 3f985c7 commit d51692f

File tree

2 files changed

+52
-58
lines changed

2 files changed

+52
-58
lines changed

.containerversion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
47
1+
48

Dockerfile

+51-57
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,23 @@
1919
# $ docker run --privileged --rm tonistiigi/binfmt --install arm64
2020

2121
FROM ubuntu:22.04
22-
ENV DEBIAN_FRONTEND noninteractive
2322

2423
# These are automatically provided by docker (no need for --build-arg)
2524
ARG TARGETPLATFORM
2625
ARG TARGETARCH
2726

28-
RUN apt-get update && apt-get upgrade -y && apt-get install -y wget nano rsync curl gnupg2 jq unzip bzip2 xz-utils
27+
RUN export DEBIAN_FRONTEND=noninteractive; \
28+
apt-get update && \
29+
apt-get upgrade -y && \
30+
apt-get install -y wget nano rsync curl gnupg2 jq unzip bzip2 xz-utils && \
31+
rm -rf /var/lib/apt/lists/*
32+
2933

30-
# for clang-*-15, see https://apt.llvm.org/
3134
RUN echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" >> /etc/apt/sources.list && \
3235
echo "deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" >> /etc/apt/sources.list && \
33-
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
36+
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
37+
rm /root/.wget-hsts
3438

35-
# Install gcc8-arm-none-eabi
3639
RUN if [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
3740
GNU_TOOLCHAIN=https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-aarch64-arm-none-eabi.tar.xz \
3841
GNU_TOOLCHAIN_HASH=c8824bffd057afce2259f7618254e840715f33523a3d4e4294f471208f976764 \
@@ -42,13 +45,13 @@ RUN if [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
4245
GNU_TOOLCHAIN_HASH=fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52 \
4346
GNU_TOOLCHAIN_FORMAT=bz2; \
4447
fi; \
45-
wget -O gcc.tar.${GNU_TOOLCHAIN_FORMAT} ${GNU_TOOLCHAIN} &&\
46-
echo "$GNU_TOOLCHAIN_HASH gcc.tar.${GNU_TOOLCHAIN_FORMAT}" | sha256sum -c &&\
47-
tar -xvf gcc.tar.${GNU_TOOLCHAIN_FORMAT} -C /usr/local --strip-components=1 &&\
48-
rm -f gcc.tar.${GNU_TOOLCHAIN_FORMAT}
48+
wget -O gcc.tar.${GNU_TOOLCHAIN_FORMAT} ${GNU_TOOLCHAIN} && \
49+
echo "$GNU_TOOLCHAIN_HASH gcc.tar.${GNU_TOOLCHAIN_FORMAT}" | sha256sum -c && \
50+
tar -xvf gcc.tar.${GNU_TOOLCHAIN_FORMAT} -C /usr/local --strip-components=1 && \
51+
rm -f gcc.tar.${GNU_TOOLCHAIN_FORMAT} /root/.wget-hsts
4952

50-
# Tools for building
51-
RUN apt-get update && apt-get install -y \
53+
RUN export DEBIAN_FRONTEND=noninteractive; \
54+
apt-get update && apt-get install -y \
5255
make \
5356
llvm-18 \
5457
gcc-10 \
@@ -80,36 +83,38 @@ RUN update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-10 100
8083

8184
# Tools for CI
8285
RUN apt-get update && apt-get install -y \
86+
libhidapi-dev \
8387
python3 \
8488
python3-pip \
89+
doxygen \
90+
graphviz \
8591
clang-format-18 \
86-
clang-tidy-18
92+
clang-tidy-18 \
93+
bash-completion \
94+
&& rm -rf /var/lib/apt/lists/*
8795

88-
RUN python3 -m pip install --upgrade pip
96+
# Set gcc-10 as the default gcc
97+
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 && \
98+
update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-10 100 && \
99+
rm /var/log/alternatives.log
89100

90101
# Python modules
91-
COPY py/bitbox02 /tmp/bitbox02
92-
RUN python3 -m pip install /tmp/bitbox02
93-
RUN rm -r /tmp/bitbox02
94-
COPY py/requirements.txt /tmp
95-
RUN python3 -m pip install --upgrade --requirement /tmp/requirements.txt
96-
RUN rm /tmp/requirements.txt
97-
98-
# Python modules for CI
99-
RUN python3 -m pip install --upgrade \
102+
RUN --mount=source=py,target=/mnt,rw \
103+
python3 -m pip install --no-compile --no-cache-dir /mnt/bitbox02 && \
104+
python3 -m pip install --no-compile --no-cache-dir --upgrade --requirement /mnt/requirements.txt && \
105+
python3 -m pip install --no-compile --no-cache-dir --upgrade \
100106
pylint==2.13.9 \
101107
pylint-protobuf==0.20.2 \
102108
black==22.3.0 \
103109
mypy==0.960 \
104-
mypy-protobuf==3.2.0
105-
106-
# Python modules for packaging
107-
RUN python3 -m pip install --upgrade \
110+
mypy-protobuf==3.2.0 \
108111
setuptools==41.2.0 \
109112
wheel==0.33.6 \
110-
twine==1.15.0
113+
twine==1.15.0 \
114+
gcovr==7.2
111115

112116
#Install protoc from release, because the version available on the repo is too old
117+
ENV PATH /opt/protoc/bin:$PATH
113118
RUN if [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
114119
PROTOC_URL=https://github.com/protocolbuffers/protobuf/releases/download/v21.2/protoc-21.2-linux-aarch_64.zip; \
115120
else \
@@ -119,47 +124,36 @@ RUN if [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
119124
curl -L0 ${PROTOC_URL} -o /tmp/protoc-21.2.zip && \
120125
unzip /tmp/protoc-21.2.zip -d /opt/protoc && \
121126
rm /tmp/protoc-21.2.zip
122-
ENV PATH /opt/protoc/bin:$PATH
123-
124-
# Developer tools
125-
RUN apt-get update && apt-get install -y \
126-
bash-completion
127-
# Install gcovr from PIP to get a newer version than in apt repositories
128-
RUN python3 -m pip install gcovr
129127

130128
# Install Go, used for the tools in tools/go and for test/gounittest
131-
ENV GOPATH /opt/go
132-
ENV GOROOT /opt/go_dist/go
133-
ENV PATH $GOROOT/bin:$GOPATH/bin:$PATH
129+
ENV PATH=/opt/go_dist/go/bin:/opt/go/bin:$PATH GOPATH=/opt/go GOROOT=/opt/go_dist/go
134130
RUN mkdir -p /opt/go_dist && \
135131
curl https://dl.google.com/go/go1.19.3.linux-${TARGETARCH}.tar.gz | tar -xz -C /opt/go_dist
136132

137133
# Install lcov from release (the one from the repos is too old).
138-
RUN cd /opt && wget https://github.com/linux-test-project/lcov/releases/download/v1.14/lcov-1.14.tar.gz && tar -xf lcov-1.14.tar.gz
139-
ENV PATH /opt/lcov-1.14/bin:$PATH
134+
ENV PATH=/opt/lcov-1.14/bin:$PATH
135+
RUN curl -L https://github.com/linux-test-project/lcov/releases/download/v1.14/lcov-1.14.tar.gz | tar -xz -C /opt
140136

141137
# Install rust compiler
142-
ENV PATH /opt/cargo/bin:$PATH
143-
ENV RUSTUP_HOME=/opt/rustup
144-
COPY src/rust/rust-toolchain.toml /tmp/rust-toolchain.toml
145-
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | CARGO_HOME=/opt/cargo sh -s -- --default-toolchain $(grep -oP '(?<=channel = ")[^"]+' /tmp/rust-toolchain.toml) -y
146-
RUN rustup target add thumbv7em-none-eabi
147-
RUN rustup component add rustfmt
148-
RUN rustup component add clippy
149-
RUN rustup component add rust-src
150-
RUN CARGO_HOME=/opt/cargo cargo install cbindgen --version 0.28.0 --locked
151-
RUN CARGO_HOME=/opt/cargo cargo install bindgen-cli --version 0.71.1 --locked
138+
# Since bindgen embeds information about its target directory, use a deterministic path for it.
139+
ENV PATH=/opt/cargo/bin:$PATH RUSTUP_HOME=/opt/rustup
140+
RUN --mount=source=tools/prost-build-proto,target=/mnt/prost-build-proto,rw \
141+
--mount=source=src/rust/rust-toolchain.toml,target=/mnt/rust-toolchain.toml \
142+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
143+
CARGO_HOME=/opt/cargo sh -s -- --default-toolchain $(grep -oP '(?<=channel = ")[^"]+' /mnt/rust-toolchain.toml) -y && \
144+
rustup target add thumbv7em-none-eabi && \
145+
rustup component add rustfmt && \
146+
rustup component add clippy && \
147+
rustup component add rust-src && \
148+
CARGO_HOME=/opt/cargo cargo install cbindgen --version 0.28.0 --locked && \
149+
CARGO_HOME=/opt/cargo cargo install bindgen-cli --version 0.71.1 --locked --target-dir=/tmp/bindgen-target && \
150+
CARGO_HOME=/opt/cargo cargo install --path /mnt/prost-build-proto --locked && \
151+
rm -r /tmp/bindgen-target /opt/cargo/registry/index /opt/cargo/.global-cache
152152

153153
# Until cargo vendor supports vendoring dependencies of the rust std libs we
154154
# need a copy of this file next to the toml file. It also has to be world
155155
# writable so that invocations of `cargo vendor` can update it. Below is the
156156
# tracking issue for `cargo vendor` to support rust std libs.
157157
# https://github.com/rust-lang/wg-cargo-std-aware/issues/23
158-
RUN cp "$(rustc --print=sysroot)/lib/rustlib/src/rust/library/Cargo.lock" "$(rustc --print=sysroot)/lib/rustlib/src/rust/library/test/"
159-
RUN chmod 777 $(rustc --print=sysroot)/lib/rustlib/src/rust/library/test/Cargo.lock
160-
161-
COPY tools/prost-build-proto prost-build-proto
162-
RUN CARGO_HOME=/opt/cargo cargo install --path prost-build-proto --locked
163-
164-
# Clean temporary files to reduce image size
165-
RUN rm -rf /var/lib/apt/lists/*
158+
RUN cp "$(rustc --print=sysroot)/lib/rustlib/src/rust/library/Cargo.lock" "$(rustc --print=sysroot)/lib/rustlib/src/rust/library/test/" && \
159+
chmod 777 $(rustc --print=sysroot)/lib/rustlib/src/rust/library/test/Cargo.lock

0 commit comments

Comments
 (0)