Skip to content

Commit 31dfc6c

Browse files
hsbtclaude
andcommitted
Split Dockerfile into parallel build groups for GitHub Actions
This reduces CI build time from ~3 hours (sequential) to ~30-45 minutes (parallel groups). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d370d65 commit 31dfc6c

2 files changed

Lines changed: 170 additions & 46 deletions

File tree

.github/workflows/build.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Build Docker image
2+
3+
on:
4+
push:
5+
branches: [master]
6+
workflow_dispatch:
7+
8+
env:
9+
REGISTRY: docker.io
10+
IMAGE_NAME: ${{ github.repository }}
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
build-group:
17+
runs-on: ubuntu-latest
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
target:
22+
- group-legacy
23+
- group-a
24+
- group-b
25+
- group-c
26+
- group-d
27+
- group-e
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- uses: docker/setup-buildx-action@v3
32+
33+
- uses: docker/login-action@v3
34+
with:
35+
username: ${{ secrets.DOCKER_USER }}
36+
password: ${{ secrets.DOCKER_PASS }}
37+
38+
- name: Build ${{ matrix.target }}
39+
uses: docker/build-push-action@v6
40+
with:
41+
context: .
42+
target: ${{ matrix.target }}
43+
cache-from: |
44+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-${{ matrix.target }}
45+
cache-to: |
46+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-${{ matrix.target }},mode=max
47+
48+
build-final:
49+
needs: build-group
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@v4
53+
54+
- uses: docker/setup-buildx-action@v3
55+
56+
- uses: docker/login-action@v3
57+
with:
58+
username: ${{ secrets.DOCKER_USER }}
59+
password: ${{ secrets.DOCKER_PASS }}
60+
61+
- name: Build and push final image
62+
uses: docker/build-push-action@v6
63+
with:
64+
context: .
65+
push: true
66+
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
67+
cache-from: |
68+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-legacy
69+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-a
70+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-b
71+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-c
72+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-d
73+
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cache-group-e

Dockerfile

Lines changed: 97 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ ARG variant=-slim
44
ARG mirror=http://deb.debian.org/debian
55
ARG system_ruby=ruby2.7
66

7-
# Build for 0.*, 1.0*, 1.1*, 1.8 and 1.8.5
8-
FROM debian:buster-slim
7+
# rake -j interpret non-numeric argument as number of CPUs plus 3.
8+
ARG j=numcpu_plus_alpha
9+
10+
# =============================================================================
11+
# Base build environment: Debian Buster (for legacy Ruby versions)
12+
# =============================================================================
13+
FROM debian:buster-slim AS builder-buster
914
ENV DEBIAN_FRONTEND=noninteractive
10-
ARG mirror
1115

1216
RUN echo "deb http://archive.debian.org/debian/ buster main contrib non-free" > /etc/apt/sources.list && \
1317
echo "deb http://archive.debian.org/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list && \
@@ -36,20 +40,25 @@ COPY lib/ruby_version.rb /all-ruby/lib/
3640
COPY patch /all-ruby/patch/
3741
RUN rake setup_build
3842

39-
# rake -j interpret non-numeric argument as number of CPUs plus 3.
43+
# =============================================================================
44+
# Group: legacy (0.x, 1.0, 1.1, 1.8.0-1.8.5, 2.0.0) on Debian Buster
45+
# =============================================================================
46+
FROM builder-buster AS group-legacy
4047
ARG j=numcpu_plus_alpha
4148

42-
COPY versions/0.* versions/1.* versions/2.0.0* /all-ruby/versions/
49+
COPY versions/0.* versions/1.0* versions/1.1* versions/1.8.0* versions/1.8.1* versions/1.8.2* versions/1.8.3* versions/1.8.4* versions/1.8.5* versions/2.0.0* /all-ruby/versions/
4350
RUN rake -j ${j} all-0 all-1.0 all-1.1a all-1.1b all-1.1c all-1.1d all-1.8 all-1.8.5
4451
RUN rake -j ${j} all-2.0.0
4552

46-
RUN rm -rf Rakefile versions/ patch/
47-
RUN rm -rf DIST build/*/log build/*/ruby*/
48-
RUN rm -rf build/*/man build/*/share/man build/*/share/doc build/*/share/ri
49-
RUN rm -f build/*/lib/libruby-static.a
50-
RUN rm -f build/*/bin/gcc build/*/bin/cc
53+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
54+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
55+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
56+
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
5157

52-
FROM ${os}:${version}${variant}
58+
# =============================================================================
59+
# Base build environment: Debian Bullseye (for modern Ruby versions)
60+
# =============================================================================
61+
FROM ${os}:${version}${variant} AS builder-bullseye
5362
ENV DEBIAN_FRONTEND=noninteractive
5463
ARG mirror
5564
ARG version
@@ -71,62 +80,88 @@ RUN dpkg --add-architecture i386 \
7180
&& apt-get build-dep ${system_ruby} \
7281
&& rm -rf /var/lib/apt/lists/*
7382

74-
COPY --from=0 /build-all-ruby/ /build-all-ruby
75-
COPY --from=0 /all-ruby/ /all-ruby
76-
7783
WORKDIR /all-ruby
7884

7985
COPY Rakefile /all-ruby/
8086
COPY lib/ruby_version.rb /all-ruby/lib/
8187
COPY patch /all-ruby/patch/
8288
RUN rake setup_build
8389

84-
# rake -j interpret non-numeric argument as number of CPUs plus 3.
90+
# =============================================================================
91+
# Group A: 1.2-1.8.7, 1.9.x
92+
# =============================================================================
93+
FROM builder-bullseye AS group-a
8594
ARG j=numcpu_plus_alpha
8695

87-
COPY versions/1.* versions/2.1* versions/2.2* versions/2.3* versions/2.4* versions/2.5* versions/2.6* versions/2.7* versions/3.0* /all-ruby/versions/
96+
COPY versions/1.2* versions/1.3* versions/1.4* versions/1.6* versions/1.8.6* versions/1.8.7* versions/1.9* /all-ruby/versions/
8897
RUN rake -j ${j} all-1.2 all-1.3 all-1.4 all-1.6 all-1.8.6 all-1.8.7
8998
RUN rake -j ${j} all-1.9.0 all-1.9.1 all-1.9.2
9099
RUN rake -j ${j} all-1.9.3
91-
RUN rake -j ${j} all-2.1
92-
RUN rake -j ${j} all-2.2
93-
RUN rake -j ${j} all-2.3
94-
RUN rake -j ${j} all-2.4
95-
RUN rake -j ${j} all-2.5
96-
RUN rake -j ${j} all-2.6
97-
RUN rake -j ${j} all-2.7
98-
RUN rake -j ${j} all-3.0
99100

100-
COPY versions/3.1* /all-ruby/versions/
101-
RUN rake -j ${j} all-3.1
101+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
102+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
103+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
104+
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
102105

103-
COPY versions/3.2* /all-ruby/versions/
104-
RUN rake -j ${j} all-3.2
106+
# =============================================================================
107+
# Group B: 2.1-2.4
108+
# =============================================================================
109+
FROM builder-bullseye AS group-b
110+
ARG j=numcpu_plus_alpha
105111

106-
COPY versions/3.3* /all-ruby/versions/
107-
RUN rake -j ${j} all-3.3
112+
COPY versions/2.1* versions/2.2* versions/2.3* versions/2.4* /all-ruby/versions/
113+
RUN rake -j ${j} all-2.1 all-2.2 all-2.3 all-2.4
108114

109-
COPY versions/3.4* /all-ruby/versions/
110-
RUN rake -j ${j} all-3.4
115+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
116+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
117+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
118+
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
111119

112-
COPY versions/3.5* /all-ruby/versions/
113-
RUN rake -j ${j} 3.5.0-preview1
120+
# =============================================================================
121+
# Group C: 2.5-2.7
122+
# =============================================================================
123+
FROM builder-bullseye AS group-c
124+
ARG j=numcpu_plus_alpha
114125

115-
COPY versions/4.0* /all-ruby/versions/
116-
RUN rake -j ${j} all-4.0
126+
COPY versions/2.5* versions/2.6* versions/2.7* /all-ruby/versions/
127+
RUN rake -j ${j} all-2.5 all-2.6 all-2.7
117128

118-
COPY lib/* /all-ruby/lib/
119-
COPY all-ruby /all-ruby/
129+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
130+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
131+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
132+
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
133+
134+
# =============================================================================
135+
# Group D: 3.0-3.2
136+
# =============================================================================
137+
FROM builder-bullseye AS group-d
138+
ARG j=numcpu_plus_alpha
120139

121-
RUN rm -rf Rakefile versions/ patch/
122-
RUN rm -rf DIST build/*/log build/*/ruby*/
123-
RUN rm -rf build/*/man build/*/share/man build/*/share/doc build/*/share/ri
124-
RUN rm -f build/*/lib/libruby-static.a
125-
RUN rm -f build/*/bin/gcc build/*/bin/cc
140+
COPY versions/3.0* versions/3.1* versions/3.2* /all-ruby/versions/
141+
RUN rake -j ${j} all-3.0 all-3.1 all-3.2
126142

143+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
144+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
145+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
127146
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
128-
RUN rdfind -makehardlinks true -makeresultsfile false /build-all-ruby
129147

148+
# =============================================================================
149+
# Group E: 3.3-4.0
150+
# =============================================================================
151+
FROM builder-bullseye AS group-e
152+
ARG j=numcpu_plus_alpha
153+
154+
COPY versions/3.3* versions/3.4* versions/3.5* versions/4.0* /all-ruby/versions/
155+
RUN rake -j ${j} all-3.3 all-3.4 3.5.0-preview1 all-4.0
156+
157+
RUN rm -rf Rakefile versions/ patch/ DIST build/*/log build/*/ruby*/ \
158+
build/*/man build/*/share/man build/*/share/doc build/*/share/ri && \
159+
rm -f build/*/lib/libruby-static.a build/*/bin/gcc build/*/bin/cc
160+
RUN find /build-all-ruby -type f \( -name ruby -o -name '*.so' \) -exec sh -c 'file $1 | grep -q "not stripped"' - '{}' \; -print0 | xargs -0 strip
161+
162+
# =============================================================================
163+
# Final: Runtime image
164+
# =============================================================================
130165
FROM ${os}:${version}${variant}
131166
ENV DEBIAN_FRONTEND=noninteractive
132167
ARG mirror
@@ -156,10 +191,26 @@ RUN dpkg --add-architecture i386 \
156191
libssl1.1:amd64 \
157192
zlib1g:amd64 \
158193
gcc \
194+
rdfind \
159195
${system_ruby} \
160196
&& rm -rf /var/lib/apt/lists/*
161197

162-
COPY --from=1 /build-all-ruby/ /build-all-ruby
163-
COPY --from=1 /all-ruby/ /all-ruby
198+
COPY --from=group-legacy /build-all-ruby/ /build-all-ruby/
199+
COPY --from=group-legacy /all-ruby/ /all-ruby/
200+
COPY --from=group-a /build-all-ruby/ /build-all-ruby/
201+
COPY --from=group-a /all-ruby/bin/ /all-ruby/bin/
202+
COPY --from=group-b /build-all-ruby/ /build-all-ruby/
203+
COPY --from=group-b /all-ruby/bin/ /all-ruby/bin/
204+
COPY --from=group-c /build-all-ruby/ /build-all-ruby/
205+
COPY --from=group-c /all-ruby/bin/ /all-ruby/bin/
206+
COPY --from=group-d /build-all-ruby/ /build-all-ruby/
207+
COPY --from=group-d /all-ruby/bin/ /all-ruby/bin/
208+
COPY --from=group-e /build-all-ruby/ /build-all-ruby/
209+
COPY --from=group-e /all-ruby/bin/ /all-ruby/bin/
210+
211+
COPY lib/* /all-ruby/lib/
212+
COPY all-ruby /all-ruby/
213+
214+
RUN rdfind -makehardlinks true -makeresultsfile false /build-all-ruby
164215

165216
WORKDIR /all-ruby

0 commit comments

Comments
 (0)