Skip to content

Commit a8a3d62

Browse files
committed
🔧 chore(docker): overhaul precommit Dockerfile to multi-stage build
Signed-off-by: samzong <[email protected]>
1 parent ee6e87e commit a8a3d62

File tree

1 file changed

+120
-28
lines changed

1 file changed

+120
-28
lines changed

‎Dockerfile.precommit‎

Lines changed: 120 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,129 @@
1-
FROM golang:1.24
1+
# =========================================================================
2+
# Nodejs Stage
3+
# =========================================================================
4+
FROM node:20-bookworm-slim AS node_builder
5+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
26

3-
# Install Base env
4-
RUN apt-get update && apt-get install -y \
5-
make \
6-
build-essential \
7-
pkg-config \
8-
python3 \
9-
libssl-dev \
10-
ca-certificates \
11-
python3-pip
7+
RUN set -eux; \
8+
npm install -g markdownlint-cli; \
9+
npm cache clean --force; \
10+
rm -rf /tmp/*
1211

13-
# Install Node.js and npm
14-
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
15-
apt-get install -y nodejs
1612

17-
# Install Rust
18-
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
19-
ENV PATH="/root/.cargo/bin:${PATH}"
13+
# =========================================================================
14+
# Golang Stage
15+
# =========================================================================
16+
FROM golang:1.24-bookworm AS go_builder
17+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
2018

21-
# Markdown
22-
RUN npm install -g markdownlint-cli
19+
ARG GOLANGCI_LINT_VERSION=v2.5.0
2320

24-
# Install pre-commit and tools
25-
RUN pip install --break-system-packages pre-commit
21+
RUN set -eux; \
22+
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}; \
23+
mv /go/bin/golangci-lint /usr/local/bin/golangci-lint; \
24+
strip --strip-unneeded /usr/local/bin/golangci-lint 2>/dev/null || true; \
25+
rm -rf /go/pkg/mod /go/pkg/sumdb
2626

27-
# Yamllint
28-
RUN pip install --break-system-packages yamllint
27+
# prune non-essential Go docs/tests to save some space while keeping stdlib
28+
RUN set -eux; \
29+
rm -rf /usr/local/go/api /usr/local/go/doc /usr/local/go/misc /usr/local/go/test
2930

30-
# CodeSpell
31-
RUN pip install --break-system-packages codespell
31+
# drop Go build cache/obj if present (not needed for gofmt/golangci-lint runtime)
32+
RUN set -eux; \
33+
rm -rf /usr/local/go/pkg/obj || true
3234

33-
# Shellcheck
34-
RUN pip install --break-system-packages shellcheck-py
3535

36-
# Golangci-lint
37-
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
36+
# =========================================================================
37+
# Rust Stage
38+
# =========================================================================
39+
FROM rust:bookworm AS rust_builder
40+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
41+
42+
ARG RUSTUP_MIRROR
43+
44+
ENV RUSTUP_HOME=/usr/local/rustup \
45+
CARGO_HOME=/usr/local/cargo
46+
47+
RUN set -eux; \
48+
if [ -n "${RUSTUP_MIRROR:-}" ]; then \
49+
export RUSTUP_DIST_SERVER="$RUSTUP_MIRROR" RUSTUP_UPDATE_ROOT="$RUSTUP_MIRROR/rustup"; \
50+
fi; \
51+
rustup set profile minimal; \
52+
rustup toolchain install stable --component rustfmt; \
53+
rustup default stable; \
54+
# drop rust docs/manpages to reduce size, keep stdlib/toolchain intact
55+
find ${RUSTUP_HOME}/toolchains -type d \( -name doc -o -name man \) -prune -exec rm -rf {} +; \
56+
rm -rf ${CARGO_HOME}/registry ${CARGO_HOME}/git ${RUSTUP_HOME}/tmp
57+
58+
59+
# =========================================================================
60+
# Python Stage
61+
# =========================================================================
62+
FROM python:3.11-bookworm AS python_builder
63+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
64+
65+
ENV PRE_COMMIT_HOME=/opt/pre-commit
66+
67+
RUN set -eux; \
68+
python -m venv /opt/py-tools; \
69+
/opt/py-tools/bin/pip install --upgrade pip; \
70+
/opt/py-tools/bin/pip install --no-cache-dir pre-commit yamllint codespell; \
71+
/opt/py-tools/bin/pip cache purge >/dev/null 2>&1 || true; \
72+
find /opt/py-tools -type d -name '__pycache__' -prune -exec rm -rf {} +; \
73+
find /opt/py-tools -name '*.pyc' -delete
74+
75+
76+
# =========================================================================
77+
# Final Stage
78+
# =========================================================================
79+
FROM python:3.11-slim-bookworm
80+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
81+
82+
ARG APT_MIRROR
83+
84+
ENV LANG=C.UTF-8 \
85+
RUSTUP_HOME=/usr/local/rustup \
86+
CARGO_HOME=/usr/local/cargo \
87+
PRE_COMMIT_HOME=/opt/pre-commit \
88+
NODE_PATH=/usr/local/lib/node_modules \
89+
PATH=/usr/local/go/bin:/usr/local/cargo/bin:/opt/py-tools/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
90+
91+
92+
RUN set -eux; \
93+
if [ -n "${APT_MIRROR:-}" ]; then \
94+
rm -f /etc/apt/sources.list.d/debian.sources || true; \
95+
SEC_MIRROR="${APT_MIRROR/debian/debian-security}"; \
96+
echo "deb ${APT_MIRROR} bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list; \
97+
echo "deb ${APT_MIRROR} bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list; \
98+
echo "deb ${SEC_MIRROR} bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list; \
99+
fi
100+
101+
RUN set -eux; \
102+
apt-get update; \
103+
apt-get install -y --no-install-recommends \
104+
ca-certificates \
105+
git \
106+
make \
107+
gcc \
108+
g++ \
109+
libc6-dev \
110+
pkg-config \
111+
libssl-dev \
112+
shellcheck; \
113+
rm -rf /var/lib/apt/lists/*
114+
115+
# Copy tools and runtimes from the builder stage
116+
COPY --from=python_builder /opt/py-tools /opt/py-tools
117+
COPY --from=go_builder /usr/local/go /usr/local/go
118+
COPY --from=go_builder /usr/local/bin/golangci-lint /usr/local/bin/golangci-lint
119+
COPY --from=rust_builder /usr/local/rustup /usr/local/rustup
120+
COPY --from=rust_builder /usr/local/cargo /usr/local/cargo
121+
COPY --from=node_builder /usr/local/bin/node /usr/local/bin/node
122+
COPY --from=node_builder /usr/local/lib/node_modules /usr/local/lib/node_modules
123+
124+
RUN set -eux; \
125+
ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm; \
126+
ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx; \
127+
ln -sf /usr/local/lib/node_modules/markdownlint-cli/markdownlint.js /usr/local/bin/markdownlint
128+
129+
WORKDIR /app

0 commit comments

Comments
 (0)