Skip to content

Commit 2895d37

Browse files
committed
Build musl from source
1 parent 8ca053b commit 2895d37

14 files changed

Lines changed: 1743 additions & 62 deletions

src/engines/ruby/2.1/Dockerfile.musl

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# platforms: linux/x86_64
2-
FROM ruby:2.1.10-alpine
1+
# Alpine 3.23
2+
FROM public.ecr.aws/docker/library/alpine:3.23
33

44
# A few RUN actions in Dockerfiles are subject to uncontrollable outside
55
# variability: an identical command would be the same from `docker build`'s
@@ -29,12 +29,143 @@ ARG REPRO_RUN_KEY=0
2929
# updated by changing the `REPRO_RUN_KEY`.
3030
RUN true "${REPRO_RUN_KEY}" && apk update
3131

32-
ENV LANG=en_US.UTF-8
32+
# Skip installing gem documentation
33+
COPY <<GEMRC /usr/local/etc/gemrc
34+
install: --no-document
35+
update: --no-document
36+
GEMRC
3337

34-
## Install a pinned RubyGems and Bundler
35-
RUN gem update --system 2.7.11
36-
RUN gem install bundler --version 1.17.3
38+
ENV LANG="en_US.UTF-8" \
39+
RUBY_MAJOR="2.1" \
40+
RUBY_VERSION="2.1.10" \
41+
RUBY_DOWNLOAD_SHA256="5be9f8d5d29d252cd7f969ab7550e31bbb001feb4a83532301c0dd3b5006e148"
42+
43+
# - Compile Ruby with `--disable-shared`
44+
# - Update gem version
45+
46+
RUN <<SHELL
47+
set -eux
48+
49+
# --- Install compiler and build dependencies ---
50+
# Install packages to keep in the final image
51+
apk add \
52+
curl \
53+
ca-certificates \
54+
git
55+
# Install build-only dependencies as a virtual package for easy cleanup
56+
apk add --virtual .ruby-builddeps \
57+
build-base \
58+
autoconf \
59+
bison \
60+
patch \
61+
xz \
62+
linux-headers \
63+
zlib-dev \
64+
yaml-dev \
65+
gdbm-dev \
66+
readline-dev \
67+
ncurses-dev \
68+
libffi-dev \
69+
perl
70+
71+
# Ruby 2.1 needs OpenSSL 1.0.2u; Alpine 3.23's OpenSSL 3.x is incompatible
72+
OPENSSL_VERSION='1.0.2u'
73+
OPENSSL_SHA256='ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16'
74+
75+
curl -L -o openssl.tar.gz "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
76+
echo "$OPENSSL_SHA256 *openssl.tar.gz" | sha256sum -c -
77+
mkdir -p /usr/src/openssl
78+
tar -xzf openssl.tar.gz -C /usr/src/openssl --strip-components=1
79+
rm openssl.tar.gz
80+
81+
cd /usr/src/openssl
82+
83+
./config \
84+
--prefix=/usr/local/ssl \
85+
--openssldir=/usr/local/ssl \
86+
shared \
87+
zlib
88+
make -j "$(nproc)"
89+
make install
90+
91+
echo "/usr/local/ssl/lib" >> /etc/ld-musl-$(uname -m).path
92+
93+
# point OpenSSL to the system CA certificates so SSL verification works
94+
rm -rf /usr/local/ssl/certs
95+
ln -s /etc/ssl/certs /usr/local/ssl/certs
96+
97+
cd /
98+
rm -r /usr/src/openssl
99+
100+
# --- Build Ruby ---
101+
102+
curl -o ruby.tar.xz "https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz"
103+
echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum -c -
104+
mkdir -p /usr/src/ruby
105+
tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1
106+
rm ruby.tar.xz
107+
108+
cd /usr/src/ruby
109+
110+
# hack in "ENABLE_PATH_CHECK" disabling to suppress:
111+
# warning: Insecure world writable dir
112+
{
113+
echo '#define ENABLE_PATH_CHECK 0'
114+
echo
115+
cat file.c
116+
} > file.c.new
117+
mv file.c.new file.c
118+
119+
autoconf
120+
121+
gnuArch="$(gcc -dumpmachine)"
122+
./configure \
123+
--build="$gnuArch" \
124+
--disable-install-doc \
125+
--disable-shared \
126+
--with-openssl-dir=/usr/local/ssl
127+
make -j "$(nproc)"
128+
make install
129+
130+
cd /
131+
rm -r /usr/src/ruby
132+
133+
# verify ruby is not installed via apk
134+
if apk info -e ruby 2>/dev/null; then exit 1; fi
135+
136+
# update gem version
137+
gem update --system 2.7.11
138+
gem install bundler --version 1.17.3 --force
139+
140+
# rough smoke test
141+
ruby --version
142+
gem --version
143+
bundle --version
144+
145+
# --- Clean up compiler and build dependencies ---
146+
# Find and preserve packages providing shared libraries needed at runtime
147+
runDeps="$( \
148+
find /usr/local -type f \( -executable -o -name '*.so*' \) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \
149+
| tr ',' '\n' \
150+
| sort -u \
151+
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
152+
)"
153+
apk add --virtual .ruby-rundeps $runDeps
154+
apk del --no-network .ruby-builddeps
155+
156+
SHELL
37157

38158
# Install additional gems that are in CRuby but missing from the above
39159
# JRuby install distribution. These are version-pinned for reproducibility.
40-
RUN gem install rake:12.3.3
160+
RUN gem install rake:13.2.1
161+
162+
# don't create ".bundle" in all our apps
163+
ENV GEM_HOME /usr/local/bundle
164+
ENV BUNDLE_SILENCE_ROOT_WARNING=1 \
165+
BUNDLE_APP_CONFIG="$GEM_HOME"
166+
ENV PATH $GEM_HOME/bin:$PATH
167+
168+
# adjust permissions of a few directories for running "gem install" as an arbitrary user
169+
RUN mkdir -p "$GEM_HOME" && chmod 1777 "$GEM_HOME"
170+
171+
CMD [ "irb" ]

src/engines/ruby/2.2/Dockerfile.musl

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# platforms: linux/x86_64
2-
FROM ruby:2.2.10-alpine
1+
# Alpine 3.23
2+
FROM public.ecr.aws/docker/library/alpine:3.23
33

44
# A few RUN actions in Dockerfiles are subject to uncontrollable outside
55
# variability: an identical command would be the same from `docker build`'s
@@ -29,12 +29,143 @@ ARG REPRO_RUN_KEY=0
2929
# updated by changing the `REPRO_RUN_KEY`.
3030
RUN true "${REPRO_RUN_KEY}" && apk update
3131

32-
ENV LANG=en_US.UTF-8
32+
# Skip installing gem documentation
33+
COPY <<GEMRC /usr/local/etc/gemrc
34+
install: --no-document
35+
update: --no-document
36+
GEMRC
3337

34-
## Install a pinned RubyGems and Bundler
35-
RUN gem update --system 2.7.11
36-
RUN gem install bundler --version 1.17.3
38+
ENV LANG="en_US.UTF-8" \
39+
RUBY_MAJOR="2.2" \
40+
RUBY_VERSION="2.2.10" \
41+
RUBY_DOWNLOAD_SHA256="bf77bcb7e6666ccae8d0882ea12b05f382f963f0a9a5285a328760c06a9ab650"
42+
43+
# - Compile Ruby with `--disable-shared`
44+
# - Update gem version
45+
46+
RUN <<SHELL
47+
set -eux
48+
49+
# --- Install compiler and build dependencies ---
50+
# Install packages to keep in the final image
51+
apk add \
52+
curl \
53+
ca-certificates \
54+
git
55+
# Install build-only dependencies as a virtual package for easy cleanup
56+
apk add --virtual .ruby-builddeps \
57+
build-base \
58+
autoconf \
59+
bison \
60+
patch \
61+
xz \
62+
linux-headers \
63+
zlib-dev \
64+
yaml-dev \
65+
gdbm-dev \
66+
readline-dev \
67+
ncurses-dev \
68+
libffi-dev \
69+
perl
70+
71+
# Ruby 2.2 needs OpenSSL 1.0.2u; Alpine 3.23's OpenSSL 3.x is incompatible
72+
OPENSSL_VERSION='1.0.2u'
73+
OPENSSL_SHA256='ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16'
74+
75+
curl -L -o openssl.tar.gz "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
76+
echo "$OPENSSL_SHA256 *openssl.tar.gz" | sha256sum -c -
77+
mkdir -p /usr/src/openssl
78+
tar -xzf openssl.tar.gz -C /usr/src/openssl --strip-components=1
79+
rm openssl.tar.gz
80+
81+
cd /usr/src/openssl
82+
83+
./config \
84+
--prefix=/usr/local/ssl \
85+
--openssldir=/usr/local/ssl \
86+
shared \
87+
zlib
88+
make -j "$(nproc)"
89+
make install
90+
91+
echo "/usr/local/ssl/lib" >> /etc/ld-musl-$(uname -m).path
92+
93+
# point OpenSSL to the system CA certificates so SSL verification works
94+
rm -rf /usr/local/ssl/certs
95+
ln -s /etc/ssl/certs /usr/local/ssl/certs
96+
97+
cd /
98+
rm -r /usr/src/openssl
99+
100+
# --- Build Ruby ---
101+
102+
curl -o ruby.tar.xz "https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz"
103+
echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum -c -
104+
mkdir -p /usr/src/ruby
105+
tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1
106+
rm ruby.tar.xz
107+
108+
cd /usr/src/ruby
109+
110+
# hack in "ENABLE_PATH_CHECK" disabling to suppress:
111+
# warning: Insecure world writable dir
112+
{
113+
echo '#define ENABLE_PATH_CHECK 0'
114+
echo
115+
cat file.c
116+
} > file.c.new
117+
mv file.c.new file.c
118+
119+
autoconf
120+
121+
gnuArch="$(gcc -dumpmachine)"
122+
./configure \
123+
--build="$gnuArch" \
124+
--disable-install-doc \
125+
--disable-shared \
126+
--with-openssl-dir=/usr/local/ssl
127+
make -j "$(nproc)"
128+
make install
129+
130+
cd /
131+
rm -r /usr/src/ruby
132+
133+
# verify ruby is not installed via apk
134+
if apk info -e ruby 2>/dev/null; then exit 1; fi
135+
136+
# update gem version
137+
gem update --system 2.7.11
138+
gem install bundler --version 1.17.3 --force
139+
140+
# rough smoke test
141+
ruby --version
142+
gem --version
143+
bundle --version
144+
145+
# --- Clean up compiler and build dependencies ---
146+
# Find and preserve packages providing shared libraries needed at runtime
147+
runDeps="$( \
148+
find /usr/local -type f \( -executable -o -name '*.so*' \) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \
149+
| tr ',' '\n' \
150+
| sort -u \
151+
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
152+
)"
153+
apk add --virtual .ruby-rundeps $runDeps
154+
apk del --no-network .ruby-builddeps
155+
156+
SHELL
37157

38158
# Install additional gems that are in CRuby but missing from the above
39159
# JRuby install distribution. These are version-pinned for reproducibility.
40-
RUN gem install rake:13.0.6
160+
RUN gem install rake:13.2.1
161+
162+
# don't create ".bundle" in all our apps
163+
ENV GEM_HOME /usr/local/bundle
164+
ENV BUNDLE_SILENCE_ROOT_WARNING=1 \
165+
BUNDLE_APP_CONFIG="$GEM_HOME"
166+
ENV PATH $GEM_HOME/bin:$PATH
167+
168+
# adjust permissions of a few directories for running "gem install" as an arbitrary user
169+
RUN mkdir -p "$GEM_HOME" && chmod 1777 "$GEM_HOME"
170+
171+
CMD [ "irb" ]

0 commit comments

Comments
 (0)