diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..90ec81cf7c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/*/**/Dockerfile linguist-generated +/Dockerfile*.template linguist-language=Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..9e33b8bfa1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +name: GitHub CI + +on: + pull_request: + push: + workflow_dispatch: + schedule: + - cron: 0 0 * * 0 + +defaults: + run: + shell: 'bash -Eeuo pipefail -x {0}' + +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + + generate-jobs: + name: Generate Jobs + runs-on: ubuntu-latest + outputs: + strategy: ${{ steps.generate-jobs.outputs.strategy }} + steps: + - uses: actions/checkout@v4 + - uses: docker-library/bashbrew@HEAD + - id: generate-jobs + name: Generate Jobs + run: | + strategy="$("$BASHBREW_SCRIPTS/github-actions/generate.sh")" + + EOF="EOF-$RANDOM-$RANDOM-$RANDOM" + echo "strategy<<$EOF" >> "$GITHUB_OUTPUT" + jq <<<"$strategy" . | tee -a "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + + test: + needs: generate-jobs + strategy: ${{ fromJson(needs.generate-jobs.outputs.strategy) }} + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Prepare Environment + run: ${{ matrix.runs.prepare }} + - name: Pull Dependencies + run: ${{ matrix.runs.pull }} + - name: Build ${{ matrix.name }} + run: ${{ matrix.runs.build }} + - name: History ${{ matrix.name }} + run: ${{ matrix.runs.history }} + - name: Test ${{ matrix.name }} + run: ${{ matrix.runs.test }} + - name: '"docker images"' + run: ${{ matrix.runs.images }} diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml new file mode 100644 index 0000000000..6a874b7bfa --- /dev/null +++ b/.github/workflows/update.yml @@ -0,0 +1,275 @@ +name: Update + +# Bump an image to a freshly released Ruby version as soon as upstream releases it. +# +# This is triggered by Ruby's own release workflow (ruby/ruby's .github/workflows/publish.yml) via +# POST /repos/docker-library/ruby/actions/workflows/update.yml/dispatches +# {"ref": "master", "inputs": {"version": "4.0.9"}} +# and does the same thing as the "update.sh" Jenkins job (https://doi-janky.infosiftr.net/job/update.sh/job/ruby/), +# just sooner: run "./update.sh", commit, build + test the result on amd64, then push it to master. +# If the Jenkins job gets there first, this finds nothing to do (and vice versa). +# +# Ruby usually releases several versions at once (e.g. 3.3.x, 3.4.x and 4.0.x on the same day), so each +# version runs as its own workflow run; whichever one pushes first wins, and the others replay their +# (already tested) commit on top of it. + +on: + workflow_dispatch: + inputs: + version: + description: 'Released Ruby version (e.g. "4.0.9" or "4.1.0-preview1")' + required: true + type: string + +defaults: + run: + shell: 'bash -Eeuo pipefail -x {0}' + +concurrency: + group: update-${{ inputs.version }} + cancel-in-progress: false + +permissions: + contents: read + +jobs: + + update: + name: Update ${{ inputs.version }} + runs-on: ubuntu-latest + timeout-minutes: 150 + outputs: + key: ${{ steps.targets.outputs.key }} + targets: ${{ steps.targets.outputs.targets }} + base: ${{ steps.commit.outputs.base }} + commit: ${{ steps.commit.outputs.commit }} + strategy: ${{ steps.generate-jobs.outputs.strategy }} + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Resolve versions.json keys + id: targets + env: + RUBY_VERSION: ${{ inputs.version }} + run: | + if [[ ! "$RUBY_VERSION" =~ ^([1-9][0-9]*)\.([0-9]+)\.([0-9]+)(-(preview|rc)[1-9][0-9]*)?$ ]]; then + echo "::error::Invalid Ruby version: $RUBY_VERSION" + exit 1 + fi + majorMinor="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}" + if [ -n "${BASH_REMATCH[4]}" ]; then + key="$majorMinor-rc" + targets=( "$key" ) + else + key="$majorMinor" + targets=( "$key" ) + # a GA release replaces its pre-release ("update.sh" removes "X.Y-rc" once "X.Y" exists upstream) + if jq -e --arg rc "$majorMinor-rc" 'has($rc)' versions.json > /dev/null; then + targets+=( "$majorMinor-rc" ) + fi + fi + if ! jq -e --arg key "$key" 'has($key)' versions.json > /dev/null; then + echo "::error::'$key' is not in versions.json; new release series are added by hand" + exit 1 + fi + echo "key=$key" >> "$GITHUB_OUTPUT" + echo "targets=${targets[*]}" >> "$GITHUB_OUTPUT" + + - name: Wait for ${{ inputs.version }} in www.ruby-lang.org releases.yml + env: + RUBY_VERSION: ${{ inputs.version }} + KEY: ${{ steps.targets.outputs.key }} + run: | + # "versions.sh" reads https://github.com/ruby/www.ruby-lang.org/raw/master/_data/releases.yml, which can land a while after the release itself + for (( i = 0; i < 240; i++ )); do + # (transient network errors shouldn't end the wait early) + ./versions.sh "$KEY" || : + found="$(jq -r --arg key "$KEY" '.[$key].version // empty' versions.json || :)" + git checkout -- versions.json + if [ "$found" = "$RUBY_VERSION" ]; then + exit 0 + fi + sleep 30 + done + echo "::error::$RUBY_VERSION did not show up in releases.yml (latest for $KEY: ${found:-none})" + exit 1 + + - name: Update and commit + id: commit + env: + TARGETS: ${{ steps.targets.outputs.targets }} + run: | + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + + base="$(git rev-parse HEAD)" + echo "base=$base" >> "$GITHUB_OUTPUT" + + # same commit messages as the Jenkins job ("Update 4.0 to 4.0.9", "Update 3.4 to 3.4.12, rustup 1.28.2", etc) + # https://github.com/docker-library/oi-janky-groovy/blob/master/update.sh/versions-pipeline.groovy + version_components() { + jq -r ' + .[env.version] // {} | [ + .version // empty, + ( + to_entries[] + | select(.value | type == "object" and has("version")) + | .key + " " + .value.version + ) + ] | join("\n") + ' versions.json + } + for version in $TARGETS; do + export version + componentsBefore="$(version_components)" + ./update.sh "$version" + componentsAfter="$(version_components)" + componentsChanged="$(comm -13 --nocheck-order <(echo "$componentsBefore") <(echo "$componentsAfter"))" + commitMessage="Update $version" + if [ -n "$componentsChanged" ]; then + components="$(jq <<<"$componentsChanged" -rRs 'rtrimstr("\n") | split("\n") | join(", ")')" + commitMessage+=" to $components" + fi + git add -A . + git commit -m "$commitMessage" || : + done + + commit="$(git rev-parse HEAD)" + if [ "$commit" = "$base" ]; then + echo 'Nothing to update (already up to date)' + exit 0 + fi + git log --stat -p "$base..HEAD" + git bundle create "$RUNNER_TEMP/update.bundle" "$base..HEAD" + echo "commit=$commit" >> "$GITHUB_OUTPUT" + + - uses: actions/upload-artifact@v4 + if: steps.commit.outputs.commit + with: + name: update-bundle + path: ${{ runner.temp }}/update.bundle + retention-days: 7 + + - uses: docker-library/bashbrew@HEAD + if: steps.commit.outputs.commit + - name: Generate Jobs + id: generate-jobs + if: steps.commit.outputs.commit + env: + TARGETS: ${{ steps.targets.outputs.targets }} + run: | + # only test the versions that changed (and still exist; "X.Y-rc" goes away on GA) + versions=() + for version in $TARGETS; do + if jq -e --arg v "$version" '.[$v].version' versions.json > /dev/null; then + versions+=( "$version" ) + fi + done + export GENERATE_STACKBREW_LIBRARY="./generate-stackbrew-library.sh ${versions[*]}" + strategy="$("$BASHBREW_SCRIPTS/github-actions/generate.sh")" + + EOF="EOF-$RANDOM-$RANDOM-$RANDOM" + echo "strategy<<$EOF" >> "$GITHUB_OUTPUT" + jq <<<"$strategy" . | tee -a "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + + test: + needs: update + if: needs.update.outputs.commit + strategy: ${{ fromJson(needs.update.outputs.strategy) }} + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.update.outputs.base }} + persist-credentials: false + - uses: actions/download-artifact@v4 + with: + name: update-bundle + path: ${{ runner.temp }} + - name: Check out ${{ needs.update.outputs.commit }} + env: + COMMIT: ${{ needs.update.outputs.commit }} + run: | + git fetch "$RUNNER_TEMP/update.bundle" HEAD + git checkout --detach "$COMMIT" + - name: Prepare Environment + run: ${{ matrix.runs.prepare }} + - name: Pull Dependencies + run: ${{ matrix.runs.pull }} + - name: Build ${{ matrix.name }} + run: ${{ matrix.runs.build }} + - name: History ${{ matrix.name }} + run: ${{ matrix.runs.history }} + - name: Test ${{ matrix.name }} + run: ${{ matrix.runs.test }} + - name: '"docker images"' + run: ${{ matrix.runs.images }} + + push: + needs: [ update, test ] + if: needs.update.outputs.commit && github.ref == 'refs/heads/master' + name: Push to master + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.update.outputs.base }} + fetch-depth: 0 + - uses: actions/download-artifact@v4 + with: + name: update-bundle + path: ${{ runner.temp }} + - name: Push + env: + RUBY_VERSION: ${{ inputs.version }} + KEY: ${{ needs.update.outputs.key }} + TARGETS: ${{ needs.update.outputs.targets }} + BASE: ${{ needs.update.outputs.base }} + COMMIT: ${{ needs.update.outputs.commit }} + run: | + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + git fetch "$RUNNER_TEMP/update.bundle" HEAD + + for (( attempt = 1; attempt <= 5; attempt++ )); do + git fetch origin master + master="$(git rev-parse FETCH_HEAD)" + + if [ "$master" = "$BASE" ]; then + push="$COMMIT" + else + # master moved while we were building (another version's run of this workflow, or the Jenkins job) + + # if it already has this release, there's nothing left to do + if [ "$(git show "$master:versions.json" | jq -r --arg key "$KEY" '.[$key].version // empty')" = "$RUBY_VERSION" ]; then + echo "master already has $RUBY_VERSION" + exit 0 + fi + + # otherwise, replay our commits on top of it, and make sure that what we're about to push is + # still exactly what we tested (for our versions) and exactly what "update.sh" would generate + git checkout --quiet --detach "$master" + git cherry-pick "$BASE..$COMMIT" + for target in $TARGETS; do + git diff --exit-code "$COMMIT" HEAD -- "$target/" + diff <(git show "$COMMIT:versions.json" | jq --arg key "$target" '.[$key]') <(jq --arg key "$target" '.[$key]' versions.json) + done + ./update.sh $TARGETS + git diff --exit-code + push="$(git rev-parse HEAD)" + fi + + # not a force push: if master moved again in the meantime, this fails and we start over + if git push origin "$push:refs/heads/master"; then + exit 0 + fi + sleep "$(( attempt * 10 ))" + done + echo "::error::Gave up pushing $RUBY_VERSION to master" + exit 1 diff --git a/.github/workflows/verify-templating.yml b/.github/workflows/verify-templating.yml new file mode 100644 index 0000000000..e822ba6bb9 --- /dev/null +++ b/.github/workflows/verify-templating.yml @@ -0,0 +1,19 @@ +name: Verify Templating + +on: + pull_request: + push: + workflow_dispatch: + +defaults: + run: + shell: 'bash -Eeuo pipefail -x {0}' + +jobs: + apply-templates: + name: Check For Uncomitted Changes + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: ./apply-templates.sh + - run: git diff --exit-code diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..da4ffd7830 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.jq-template.awk +.yq* diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 604138190b..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -language: bash -services: docker - -env: - - VERSION=2.3 VARIANT= - - VERSION=2.3 VARIANT=slim - - VERSION=2.3 VARIANT=alpine - - VERSION=2.2 VARIANT= - - VERSION=2.2 VARIANT=slim - - VERSION=2.2 VARIANT=alpine - - VERSION=2.1 VARIANT= - - VERSION=2.1 VARIANT=slim - - VERSION=2.1 VARIANT=alpine - -install: - - git clone https://github.com/docker-library/official-images.git ~/official-images - -before_script: - - env | sort - - cd "$VERSION" - - image="$(awk '$1 == "FROM" { print $2; exit }' onbuild/Dockerfile)${VARIANT:+-$VARIANT}" - -script: - - docker build -t "$image" "${VARIANT:-.}" - - ~/official-images/test/run.sh "$image" -# the "onbuild" variant has to happen with the base variant because it's FROM it - - true && [ "$VARIANT" ] || docker build -t "${image}-onbuild" onbuild - -after_script: - - docker images - -# vim:set et ts=2 sw=2: diff --git a/2.1/Dockerfile b/2.1/Dockerfile deleted file mode 100644 index ee7f12bc35..0000000000 --- a/2.1/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -FROM buildpack-deps:jessie - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.1 -ENV RUBY_VERSION 2.1.10 -ENV RUBY_DOWNLOAD_SHA256 fb2e454d7a5e5a39eb54db0ec666f53eeb6edc593d1d2b970ae4d150b831dd20 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - bison \ - libgdbm-dev \ - ruby \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.1/alpine/Dockerfile b/2.1/alpine/Dockerfile deleted file mode 100644 index d887ed029d..0000000000 --- a/2.1/alpine/Dockerfile +++ /dev/null @@ -1,107 +0,0 @@ -FROM alpine:3.4 - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.1 -ENV RUBY_VERSION 2.1.10 -ENV RUBY_DOWNLOAD_SHA256 fb2e454d7a5e5a39eb54db0ec666f53eeb6edc593d1d2b970ae4d150b831dd20 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -# readline-dev vs libedit-dev: https://bugs.ruby-lang.org/issues/11869 and https://github.com/docker-library/ruby/issues/75 -RUN set -ex \ - \ - && apk add --no-cache --virtual .ruby-builddeps \ - autoconf \ - bison \ - bzip2 \ - bzip2-dev \ - ca-certificates \ - coreutils \ - gcc \ - gdbm-dev \ - glib-dev \ - libc-dev \ - libffi-dev \ - libxml2-dev \ - libxslt-dev \ - linux-headers \ - make \ - ncurses-dev \ - openssl \ - openssl-dev \ - procps \ - readline-dev \ - ruby \ - tar \ - yaml-dev \ - zlib-dev \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ -# the configure script does not detect isnan/isinf as macros - && ac_cv_func_isnan=yes ac_cv_func_isinf=yes \ - ./configure --disable-install-doc \ - && make -j"$(getconf _NPROCESSORS_ONLN)" \ - && make install \ - \ - && runDeps="$( \ - scanelf --needed --nobanner --recursive /usr/local \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --virtual .ruby-rundeps $runDeps \ - bzip2 \ - ca-certificates \ - libffi-dev \ - openssl-dev \ - yaml-dev \ - procps \ - zlib-dev \ - && apk del .ruby-builddeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.1/onbuild/Dockerfile b/2.1/onbuild/Dockerfile deleted file mode 100644 index 9a9bdb7b6b..0000000000 --- a/2.1/onbuild/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ruby:2.1 - -# throw errors if Gemfile has been modified since Gemfile.lock -RUN bundle config --global frozen 1 - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app - -ONBUILD COPY Gemfile /usr/src/app/ -ONBUILD COPY Gemfile.lock /usr/src/app/ -ONBUILD RUN bundle install - -ONBUILD COPY . /usr/src/app diff --git a/2.1/slim/Dockerfile b/2.1/slim/Dockerfile deleted file mode 100644 index f9b0f5e15f..0000000000 --- a/2.1/slim/Dockerfile +++ /dev/null @@ -1,94 +0,0 @@ -FROM debian:jessie - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bzip2 \ - ca-certificates \ - libffi-dev \ - libgdbm3 \ - libssl-dev \ - libyaml-dev \ - procps \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.1 -ENV RUBY_VERSION 2.1.10 -ENV RUBY_DOWNLOAD_SHA256 fb2e454d7a5e5a39eb54db0ec666f53eeb6edc593d1d2b970ae4d150b831dd20 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - autoconf \ - bison \ - gcc \ - libbz2-dev \ - libgdbm-dev \ - libglib2.0-dev \ - libncurses-dev \ - libreadline-dev \ - libxml2-dev \ - libxslt-dev \ - make \ - ruby \ - wget \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.2/Dockerfile b/2.2/Dockerfile deleted file mode 100644 index 585c517cac..0000000000 --- a/2.2/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -FROM buildpack-deps:jessie - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.2 -ENV RUBY_VERSION 2.2.5 -ENV RUBY_DOWNLOAD_SHA256 30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - bison \ - libgdbm-dev \ - ruby \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.2/alpine/Dockerfile b/2.2/alpine/Dockerfile deleted file mode 100644 index 4e71ff9f60..0000000000 --- a/2.2/alpine/Dockerfile +++ /dev/null @@ -1,107 +0,0 @@ -FROM alpine:3.4 - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.2 -ENV RUBY_VERSION 2.2.5 -ENV RUBY_DOWNLOAD_SHA256 30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -# readline-dev vs libedit-dev: https://bugs.ruby-lang.org/issues/11869 and https://github.com/docker-library/ruby/issues/75 -RUN set -ex \ - \ - && apk add --no-cache --virtual .ruby-builddeps \ - autoconf \ - bison \ - bzip2 \ - bzip2-dev \ - ca-certificates \ - coreutils \ - gcc \ - gdbm-dev \ - glib-dev \ - libc-dev \ - libffi-dev \ - libxml2-dev \ - libxslt-dev \ - linux-headers \ - make \ - ncurses-dev \ - openssl \ - openssl-dev \ - procps \ - readline-dev \ - ruby \ - tar \ - yaml-dev \ - zlib-dev \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ -# the configure script does not detect isnan/isinf as macros - && ac_cv_func_isnan=yes ac_cv_func_isinf=yes \ - ./configure --disable-install-doc \ - && make -j"$(getconf _NPROCESSORS_ONLN)" \ - && make install \ - \ - && runDeps="$( \ - scanelf --needed --nobanner --recursive /usr/local \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --virtual .ruby-rundeps $runDeps \ - bzip2 \ - ca-certificates \ - libffi-dev \ - openssl-dev \ - yaml-dev \ - procps \ - zlib-dev \ - && apk del .ruby-builddeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.2/onbuild/Dockerfile b/2.2/onbuild/Dockerfile deleted file mode 100644 index 1c90bfd92d..0000000000 --- a/2.2/onbuild/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ruby:2.2 - -# throw errors if Gemfile has been modified since Gemfile.lock -RUN bundle config --global frozen 1 - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app - -ONBUILD COPY Gemfile /usr/src/app/ -ONBUILD COPY Gemfile.lock /usr/src/app/ -ONBUILD RUN bundle install - -ONBUILD COPY . /usr/src/app diff --git a/2.2/slim/Dockerfile b/2.2/slim/Dockerfile deleted file mode 100644 index 1d0a0fb2bf..0000000000 --- a/2.2/slim/Dockerfile +++ /dev/null @@ -1,94 +0,0 @@ -FROM debian:jessie - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bzip2 \ - ca-certificates \ - libffi-dev \ - libgdbm3 \ - libssl-dev \ - libyaml-dev \ - procps \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.2 -ENV RUBY_VERSION 2.2.5 -ENV RUBY_DOWNLOAD_SHA256 30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3 -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - autoconf \ - bison \ - gcc \ - libbz2-dev \ - libgdbm-dev \ - libglib2.0-dev \ - libncurses-dev \ - libreadline-dev \ - libxml2-dev \ - libxslt-dev \ - make \ - ruby \ - wget \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.3/Dockerfile b/2.3/Dockerfile deleted file mode 100644 index 82096aea7d..0000000000 --- a/2.3/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -FROM buildpack-deps:jessie - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.3 -ENV RUBY_VERSION 2.3.1 -ENV RUBY_DOWNLOAD_SHA256 b87c738cb2032bf4920fef8e3864dc5cf8eae9d89d8d523ce0236945c5797dcd -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - bison \ - libgdbm-dev \ - ruby \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.3/alpine/Dockerfile b/2.3/alpine/Dockerfile deleted file mode 100644 index 28ba9ed6b2..0000000000 --- a/2.3/alpine/Dockerfile +++ /dev/null @@ -1,107 +0,0 @@ -FROM alpine:3.4 - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.3 -ENV RUBY_VERSION 2.3.1 -ENV RUBY_DOWNLOAD_SHA256 b87c738cb2032bf4920fef8e3864dc5cf8eae9d89d8d523ce0236945c5797dcd -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -# readline-dev vs libedit-dev: https://bugs.ruby-lang.org/issues/11869 and https://github.com/docker-library/ruby/issues/75 -RUN set -ex \ - \ - && apk add --no-cache --virtual .ruby-builddeps \ - autoconf \ - bison \ - bzip2 \ - bzip2-dev \ - ca-certificates \ - coreutils \ - gcc \ - gdbm-dev \ - glib-dev \ - libc-dev \ - libffi-dev \ - libxml2-dev \ - libxslt-dev \ - linux-headers \ - make \ - ncurses-dev \ - openssl \ - openssl-dev \ - procps \ - readline-dev \ - ruby \ - tar \ - yaml-dev \ - zlib-dev \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ -# the configure script does not detect isnan/isinf as macros - && ac_cv_func_isnan=yes ac_cv_func_isinf=yes \ - ./configure --disable-install-doc \ - && make -j"$(getconf _NPROCESSORS_ONLN)" \ - && make install \ - \ - && runDeps="$( \ - scanelf --needed --nobanner --recursive /usr/local \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --virtual .ruby-rundeps $runDeps \ - bzip2 \ - ca-certificates \ - libffi-dev \ - openssl-dev \ - yaml-dev \ - procps \ - zlib-dev \ - && apk del .ruby-builddeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/2.3/onbuild/Dockerfile b/2.3/onbuild/Dockerfile deleted file mode 100644 index 7accb9c596..0000000000 --- a/2.3/onbuild/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ruby:2.3 - -# throw errors if Gemfile has been modified since Gemfile.lock -RUN bundle config --global frozen 1 - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app - -ONBUILD COPY Gemfile /usr/src/app/ -ONBUILD COPY Gemfile.lock /usr/src/app/ -ONBUILD RUN bundle install - -ONBUILD COPY . /usr/src/app diff --git a/2.3/slim/Dockerfile b/2.3/slim/Dockerfile deleted file mode 100644 index 0a64581494..0000000000 --- a/2.3/slim/Dockerfile +++ /dev/null @@ -1,94 +0,0 @@ -FROM debian:jessie - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bzip2 \ - ca-certificates \ - libffi-dev \ - libgdbm3 \ - libssl-dev \ - libyaml-dev \ - procps \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR 2.3 -ENV RUBY_VERSION 2.3.1 -ENV RUBY_DOWNLOAD_SHA256 b87c738cb2032bf4920fef8e3864dc5cf8eae9d89d8d523ce0236945c5797dcd -ENV RUBYGEMS_VERSION 2.6.7 - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - autoconf \ - bison \ - gcc \ - libbz2-dev \ - libgdbm-dev \ - libglib2.0-dev \ - libncurses-dev \ - libreadline-dev \ - libxml2-dev \ - libxslt-dev \ - make \ - ruby \ - wget \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION 1.13.5 - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/3.3/alpine3.23/Dockerfile b/3.3/alpine3.23/Dockerfile new file mode 100644 index 0000000000..2b3e8dfac0 --- /dev/null +++ b/3.3/alpine3.23/Dockerfile @@ -0,0 +1,147 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.23 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.3/alpine3.24/Dockerfile b/3.3/alpine3.24/Dockerfile new file mode 100644 index 0000000000..2b3060c46c --- /dev/null +++ b/3.3/alpine3.24/Dockerfile @@ -0,0 +1,147 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.24 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.3/bookworm/Dockerfile b/3.3/bookworm/Dockerfile new file mode 100644 index 0000000000..4376360f2d --- /dev/null +++ b/3.3/bookworm/Dockerfile @@ -0,0 +1,114 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:bookworm + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.3/slim-bookworm/Dockerfile b/3.3/slim-bookworm/Dockerfile new file mode 100644 index 0000000000..e8e3b7e481 --- /dev/null +++ b/3.3/slim-bookworm/Dockerfile @@ -0,0 +1,139 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:bookworm-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + rm -rf /var/lib/apt/lists/* + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.3/slim-trixie/Dockerfile b/3.3/slim-trixie/Dockerfile new file mode 100644 index 0000000000..15c5e18898 --- /dev/null +++ b/3.3/slim-trixie/Dockerfile @@ -0,0 +1,139 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:trixie-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + apt-get dist-clean + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.3/trixie/Dockerfile b/3.3/trixie/Dockerfile new file mode 100644 index 0000000000..522377e059 --- /dev/null +++ b/3.3/trixie/Dockerfile @@ -0,0 +1,114 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:trixie + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-3-13-released/ +ENV RUBY_VERSION 3.3.13 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz +ENV RUBY_DOWNLOAD_SHA256 6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/alpine3.23/Dockerfile b/3.4/alpine3.23/Dockerfile new file mode 100644 index 0000000000..e27c47a3c8 --- /dev/null +++ b/3.4/alpine3.23/Dockerfile @@ -0,0 +1,147 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.23 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/alpine3.24/Dockerfile b/3.4/alpine3.24/Dockerfile new file mode 100644 index 0000000000..2ec9abb992 --- /dev/null +++ b/3.4/alpine3.24/Dockerfile @@ -0,0 +1,147 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.24 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/bookworm/Dockerfile b/3.4/bookworm/Dockerfile new file mode 100644 index 0000000000..42e3e725e3 --- /dev/null +++ b/3.4/bookworm/Dockerfile @@ -0,0 +1,114 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:bookworm + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/slim-bookworm/Dockerfile b/3.4/slim-bookworm/Dockerfile new file mode 100644 index 0000000000..e2892bd9df --- /dev/null +++ b/3.4/slim-bookworm/Dockerfile @@ -0,0 +1,139 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:bookworm-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + rm -rf /var/lib/apt/lists/* + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/slim-trixie/Dockerfile b/3.4/slim-trixie/Dockerfile new file mode 100644 index 0000000000..ca241516a0 --- /dev/null +++ b/3.4/slim-trixie/Dockerfile @@ -0,0 +1,139 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:trixie-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + apt-get dist-clean + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/3.4/trixie/Dockerfile b/3.4/trixie/Dockerfile new file mode 100644 index 0000000000..3f4442fc71 --- /dev/null +++ b/3.4/trixie/Dockerfile @@ -0,0 +1,114 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:trixie + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-3-4-12-released/ +ENV RUBY_VERSION 3.4.12 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz +ENV RUBY_DOWNLOAD_SHA256 db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/alpine3.23/Dockerfile b/4.0/alpine3.23/Dockerfile new file mode 100644 index 0000000000..1649222d04 --- /dev/null +++ b/4.0/alpine3.23/Dockerfile @@ -0,0 +1,148 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.23 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/alpine3.24/Dockerfile b/4.0/alpine3.24/Dockerfile new file mode 100644 index 0000000000..de4dca0fc1 --- /dev/null +++ b/4.0/alpine3.24/Dockerfile @@ -0,0 +1,148 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.24 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/bookworm/Dockerfile b/4.0/bookworm/Dockerfile new file mode 100644 index 0000000000..eb5dfa1dab --- /dev/null +++ b/4.0/bookworm/Dockerfile @@ -0,0 +1,115 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:bookworm + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/slim-bookworm/Dockerfile b/4.0/slim-bookworm/Dockerfile new file mode 100644 index 0000000000..9541069ef8 --- /dev/null +++ b/4.0/slim-bookworm/Dockerfile @@ -0,0 +1,140 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:bookworm-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + rm -rf /var/lib/apt/lists/* + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/slim-trixie/Dockerfile b/4.0/slim-trixie/Dockerfile new file mode 100644 index 0000000000..e7ac0a4f66 --- /dev/null +++ b/4.0/slim-trixie/Dockerfile @@ -0,0 +1,140 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:trixie-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + apt-get dist-clean + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.0/trixie/Dockerfile b/4.0/trixie/Dockerfile new file mode 100644 index 0000000000..ce2c7e431e --- /dev/null +++ b/4.0/trixie/Dockerfile @@ -0,0 +1,115 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:trixie + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/23/ruby-4-0-9-released/ +ENV RUBY_VERSION 4.0.9 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz +ENV RUBY_DOWNLOAD_SHA256 a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/alpine3.23/Dockerfile b/4.1-rc/alpine3.23/Dockerfile new file mode 100644 index 0000000000..dedf2a0100 --- /dev/null +++ b/4.1-rc/alpine3.23/Dockerfile @@ -0,0 +1,148 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.23 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/alpine3.24/Dockerfile b/4.1-rc/alpine3.24/Dockerfile new file mode 100644 index 0000000000..90768f2282 --- /dev/null +++ b/4.1-rc/alpine3.24/Dockerfile @@ -0,0 +1,148 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.24 + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ + \ + rustArch=; \ + apkArch="$(apk --print-arch)"; \ + case "$apkArch" in \ + 'x86_64') rustArch='x86_64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init'; rustupSha256='e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2' ;; \ + 'aarch64') rustArch='aarch64-unknown-linux-musl'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init'; rustupSha256='a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/bookworm/Dockerfile b/4.1-rc/bookworm/Dockerfile new file mode 100644 index 0000000000..942b4017b4 --- /dev/null +++ b/4.1-rc/bookworm/Dockerfile @@ -0,0 +1,115 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:bookworm + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/slim-bookworm/Dockerfile b/4.1-rc/slim-bookworm/Dockerfile new file mode 100644 index 0000000000..1e4c6091b6 --- /dev/null +++ b/4.1-rc/slim-bookworm/Dockerfile @@ -0,0 +1,140 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:bookworm-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + rm -rf /var/lib/apt/lists/* + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/slim-trixie/Dockerfile b/4.1-rc/slim-trixie/Dockerfile new file mode 100644 index 0000000000..14ee84d9e8 --- /dev/null +++ b/4.1-rc/slim-trixie/Dockerfile @@ -0,0 +1,140 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:trixie-slim + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + apt-get dist-clean + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/4.1-rc/trixie/Dockerfile b/4.1-rc/trixie/Dockerfile new file mode 100644 index 0000000000..6bad32da89 --- /dev/null +++ b/4.1-rc/trixie/Dockerfile @@ -0,0 +1,115 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM buildpack-deps:trixie + +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2026/10/12/ruby-4-1-0-preview1-released/ +ENV RUBY_VERSION 4.1.0-preview1 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz +ENV RUBY_DOWNLOAD_SHA256 b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8 + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.91.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ${rustArch:+--enable-zjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + apt-get dist-clean; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template deleted file mode 100644 index 7c7e4f5a44..0000000000 --- a/Dockerfile-alpine.template +++ /dev/null @@ -1,107 +0,0 @@ -FROM alpine:3.4 - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR %%VERSION%% -ENV RUBY_VERSION %%FULL_VERSION%% -ENV RUBY_DOWNLOAD_SHA256 %%SHA256%% -ENV RUBYGEMS_VERSION %%RUBYGEMS%% - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -# readline-dev vs libedit-dev: https://bugs.ruby-lang.org/issues/11869 and https://github.com/docker-library/ruby/issues/75 -RUN set -ex \ - \ - && apk add --no-cache --virtual .ruby-builddeps \ - autoconf \ - bison \ - bzip2 \ - bzip2-dev \ - ca-certificates \ - coreutils \ - gcc \ - gdbm-dev \ - glib-dev \ - libc-dev \ - libffi-dev \ - libxml2-dev \ - libxslt-dev \ - linux-headers \ - make \ - ncurses-dev \ - openssl \ - openssl-dev \ - procps \ - readline-dev \ - ruby \ - tar \ - yaml-dev \ - zlib-dev \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ -# the configure script does not detect isnan/isinf as macros - && ac_cv_func_isnan=yes ac_cv_func_isinf=yes \ - ./configure --disable-install-doc \ - && make -j"$(getconf _NPROCESSORS_ONLN)" \ - && make install \ - \ - && runDeps="$( \ - scanelf --needed --nobanner --recursive /usr/local \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --virtual .ruby-rundeps $runDeps \ - bzip2 \ - ca-certificates \ - libffi-dev \ - openssl-dev \ - yaml-dev \ - procps \ - zlib-dev \ - && apk del .ruby-builddeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION %%BUNDLER%% - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/Dockerfile-onbuild.template b/Dockerfile-onbuild.template deleted file mode 100644 index 3664cae175..0000000000 --- a/Dockerfile-onbuild.template +++ /dev/null @@ -1,13 +0,0 @@ -FROM ruby:%%VERSION%% - -# throw errors if Gemfile has been modified since Gemfile.lock -RUN bundle config --global frozen 1 - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app - -ONBUILD COPY Gemfile /usr/src/app/ -ONBUILD COPY Gemfile.lock /usr/src/app/ -ONBUILD RUN bundle install - -ONBUILD COPY . /usr/src/app diff --git a/Dockerfile-slim.template b/Dockerfile-slim.template deleted file mode 100644 index 74774ab9f0..0000000000 --- a/Dockerfile-slim.template +++ /dev/null @@ -1,94 +0,0 @@ -FROM debian:jessie - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bzip2 \ - ca-certificates \ - libffi-dev \ - libgdbm3 \ - libssl-dev \ - libyaml-dev \ - procps \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc - -ENV RUBY_MAJOR %%VERSION%% -ENV RUBY_VERSION %%FULL_VERSION%% -ENV RUBY_DOWNLOAD_SHA256 %%SHA256%% -ENV RUBYGEMS_VERSION %%RUBYGEMS%% - -# some of ruby's build scripts are written in ruby -# we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ - \ - && buildDeps=' \ - autoconf \ - bison \ - gcc \ - libbz2-dev \ - libgdbm-dev \ - libglib2.0-dev \ - libncurses-dev \ - libreadline-dev \ - libxml2-dev \ - libxslt-dev \ - make \ - ruby \ - wget \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ - \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ - \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ - \ - && cd /usr/src/ruby \ - \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ - \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ - \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ - \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION %%BUNDLER%% - -RUN gem install bundler --version "$BUNDLER_VERSION" - -# install things globally, for great justice -# and don't create ".bundle" in all our apps -ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -CMD [ "irb" ] diff --git a/Dockerfile.template b/Dockerfile.template index 90b0b1fbb8..3f1eeebdf0 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -1,72 +1,269 @@ -FROM buildpack-deps:jessie +{{ + def is_alpine: + env.variant | startswith("alpine") + ; + def is_slim: + env.variant | startswith("slim-") + ; + def clean_apt: + # TODO once bookworm is EOL, remove this and just hard-code "apt-get dist-clean" instead + if env.variant | contains("bookworm") then + "rm -rf /var/lib/apt/lists/*" + else "apt-get dist-clean" end +-}} +{{ if is_alpine then ( -}} +FROM alpine:{{ env.variant | ltrimstr("alpine") }} +{{ ) elif is_slim then ( -}} +FROM debian:{{ env.variant | ltrimstr("slim-") }}-slim +{{ ) else ( -}} +FROM buildpack-deps:{{ env.variant }} +{{ ) end -}} -# skip installing gem documentation -RUN mkdir -p /usr/local/etc \ - && { \ - echo 'install: --no-document'; \ - echo 'update: --no-document'; \ - } >> /usr/local/etc/gemrc +{{ if is_slim then ( -}} +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + ; \ + {{ clean_apt }} -ENV RUBY_MAJOR %%VERSION%% -ENV RUBY_VERSION %%FULL_VERSION%% -ENV RUBY_DOWNLOAD_SHA256 %%SHA256%% -ENV RUBYGEMS_VERSION %%RUBYGEMS%% +{{ ) else "" end -}} +# skip installing gem documentation with `gem install`/`gem update` +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + echo 'gem: --no-document' >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/{{ .post | ltrimstr("/") }} +ENV RUBY_VERSION {{ .version }} +ENV RUBY_DOWNLOAD_URL {{ .url.xz }} +ENV RUBY_DOWNLOAD_SHA256 {{ .sha256.xz }} # some of ruby's build scripts are written in ruby # we purge system ruby later to make sure our final image uses what we just built -RUN set -ex \ +RUN set -eux; \ \ - && buildDeps=' \ - bison \ +{{ if is_alpine then ( -}} + apk add --no-cache --virtual .ruby-builddeps \ + autoconf \ + bzip2 \ + bzip2-dev \ + ca-certificates \ + coreutils \ + dpkg-dev dpkg \ + g++ \ + gcc \ + gdbm-dev \ + glib-dev \ + gmp-dev \ + libc-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + ncurses-dev \ + openssl \ + openssl-dev \ + patch \ + procps \ + yaml-dev \ + zlib-dev \ + ruby \ + tar \ + xz \ + yaml-dev \ + zlib-dev \ + ; \ +{{ ) else ( -}} + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ libgdbm-dev \ ruby \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -rf /var/lib/apt/lists/* \ +{{ if is_slim then ( -}} + autoconf \ + bzip2 \ + g++ \ + gcc \ + libbz2-dev \ + libffi-dev \ + libgdbm-compat-dev \ + libglib2.0-dev \ + libgmp-dev \ + libncurses-dev \ + libssl-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + make \ + wget \ + xz-utils \ + zlib1g-dev \ +{{ ) else "" end -}} + ; \ +{{ ) end -}} \ - && wget -O ruby.tar.gz "https://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ - && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ + rustArch=; \ +{{ def archVar: if is_alpine then "apkArch" else "dpkgArch" end -}} + {{ archVar }}="$({{ if is_alpine then "apk --print-arch" else "dpkg --print-architecture" end }})"; \ + case "${{ archVar }}" in \ +{{ + ( + .rustup.arches + | (if is_alpine then "musl" else "glibc" end) as $libcKey + | to_entries + | map( + .key as $bashbrewArch + | ( + if is_alpine then + { + amd64: "x86_64", + arm32v6: "armhf", + arm32v7: "armv7", + arm64v8: "aarch64", + i386: "x86", + ppc64le: "ppc64le", + riscv64: "riscv64", + s390x: "s390x", + } + else + { + amd64: "amd64", + arm32v5: "armel", + arm32v7: "armhf", + arm64v8: "arm64", + i386: "i386", + mips64le: "mips64el", + ppc64le: "ppc64el", + riscv64: "riscv64", + s390x: "s390x", + } + end + )[$bashbrewArch] as $distroArch + | select($distroArch) + | .value + | select(has($libcKey)) + | .[$libcKey] + | ( +-}} + {{ $distroArch | @sh }}) rustArch={{ .arch | @sh }}; rustupUrl={{ .url | @sh }}; rustupSha256={{ .sha256 | @sh }} ;; \ +{{ + ) + ) + | join("") + ) +-}} + esac; \ \ - && mkdir -p /usr/src/ruby \ - && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ - && rm ruby.tar.gz \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain {{ .rust.version | @sh }} --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ \ - && cd /usr/src/ruby \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ \ -# hack in "ENABLE_PATH_CHECK" disabling to suppress: -# warning: Insecure world writable dir - && { \ - echo '#define ENABLE_PATH_CHECK 0'; \ - echo; \ - cat file.c; \ - } > file.c.new \ - && mv file.c.new file.c \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ \ - && autoconf \ - && ./configure --disable-install-doc \ - && make -j"$(nproc)" \ - && make install \ + cd /usr/src/ruby; \ \ - && apt-get purge -y --auto-remove $buildDeps \ - && cd / \ - && rm -r /usr/src/ruby \ +{{ if is_alpine then ( -}} +# https://github.com/docker-library/ruby/issues/196 +# https://bugs.ruby-lang.org/issues/14387#note-13 (patch source) +# https://bugs.ruby-lang.org/issues/14387#note-16 ("Therefore ncopa's patch looks good for me in general." -- only breaks glibc which doesn't matter here) + wget -O 'thread-stack-fix.patch' 'https://bugs.ruby-lang.org/attachments/download/7081/0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch'; \ + echo '3ab628a51d92fdf0d2b5835e93564857aea73e0c1de00313864a94a6255cb645 *thread-stack-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i thread-stack-fix.patch; \ + rm thread-stack-fix.patch; \ \ - && gem update --system "$RUBYGEMS_VERSION" - -ENV BUNDLER_VERSION %%BUNDLER%% - -RUN gem install bundler --version "$BUNDLER_VERSION" +{{ ) else "" end -}} + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ +# full RELRO: "-z now" disables lazy binding so the loader can map the GOT read-only at startup +# https://github.com/docker-library/ruby/pull/529 +# https://salsa.debian.org/ruby-team/ruby/-/blob/8a55ab83e2c1783d80d0117fecbda533ac75f3e3/debian/rules#L63-67 (Debian's "hardening=+bindnow" produces the same flags) + export LDFLAGS='-Wl,-z,relro -Wl,-z,now'; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ +{{ if env.version | IN("3.3", "3.4") then "" else ( -}} + ${rustArch:+--enable-zjit} \ +{{ ) end -}} + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ +{{ if is_alpine then ( -}} + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .ruby-rundeps $runDeps; \ + apk del --no-network .ruby-builddeps; \ +{{ ) else ( -}} + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ +# https://manpages.debian.org/bookworm/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file) + | awk 'sub(":$", "", $1) { print $1 }' \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + {{ clean_apt }}; \ +{{ ) end -}} + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed +{{ if is_alpine then ( -}} + if \ + apk --no-network list --installed \ + | grep -v '^[.]ruby-' \ + | grep -i ruby \ + ; then \ + exit 1; \ + fi; \ +{{ ) else ( -}} + if dpkg -l | grep -i ruby; then exit 1; fi; \ +{{ ) end -}} + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version -# install things globally, for great justice -# and don't create ".bundle" in all our apps +# don't create ".bundle" in all our apps ENV GEM_HOME /usr/local/bundle -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ - && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" +ENV PATH $GEM_HOME/bin:$PATH +RUN set -eux; \ + mkdir "$GEM_HOME"; \ +# adjust permissions of GEM_HOME for running "gem install" as an arbitrary user + chmod 1777 "$GEM_HOME" CMD [ "irb" ] diff --git a/LICENSE b/LICENSE index b384c6e51b..fbb62238dc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2014-2015 Docker, Inc. All rights reserved. +Copyright (C) 2014 Docker, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/README.md b/README.md index b658ffd98d..76e88e3e13 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,15 @@ -# About this Repo +# https://github.com/docker-library/ruby -This is the Git repo of the Docker [official image](https://docs.docker.com/docker-hub/official_repos/) for [ruby](https://registry.hub.docker.com/_/ruby/). See [the Docker Hub page](https://registry.hub.docker.com/_/ruby/) for the full readme on how to use this Docker image and for information regarding contributing and issues. +## Maintained by: [the Docker Community](https://github.com/docker-library/ruby) -The full readme is generated over in [docker-library/docs](https://github.com/docker-library/docs), specifically in [docker-library/docs/ruby](https://github.com/docker-library/docs/tree/master/ruby). +This is the Git repo of the [Docker "Official Image"](https://github.com/docker-library/official-images#what-are-official-images) for [`ruby`](https://hub.docker.com/_/ruby/) (not to be confused with any official `ruby` image provided by `ruby` upstream). See [the Docker Hub page](https://hub.docker.com/_/ruby/) for the full readme on how to use this Docker image and for information regarding contributing and issues. -See a change merged here that doesn't show up on the Docker Hub yet? Check [the "library/ruby" manifest file in the docker-library/official-images repo](https://github.com/docker-library/official-images/blob/master/library/ruby), especially [PRs with the "library/ruby" label on that repo](https://github.com/docker-library/official-images/labels/library%2Fruby). For more information about the official images process, see the [docker-library/official-images readme](https://github.com/docker-library/official-images/blob/master/README.md). +The [full image description on Docker Hub](https://hub.docker.com/_/ruby/) is generated/maintained over in [the docker-library/docs repository](https://github.com/docker-library/docs), specifically in [the `ruby` directory](https://github.com/docker-library/docs/tree/master/ruby). ---- +## See a change merged here that doesn't show up on Docker Hub yet? -- [Travis CI: - ![build status badge](https://img.shields.io/travis/docker-library/ruby/master.svg)](https://travis-ci.org/docker-library/ruby/branches) -- [Automated `update.sh`: - ![build status badge](https://doi-janky.infosiftr.net/job/update.sh/job/ruby/badge/icon)](https://doi-janky.infosiftr.net/job/update.sh/job/ruby) +For more information about the full official images change lifecycle, see [the "An image's source changed in Git, now what?" FAQ entry](https://github.com/docker-library/faq#an-images-source-changed-in-git-now-what). + +For outstanding `ruby` image PRs, check [PRs with the "library/ruby" label on the official-images repository](https://github.com/docker-library/official-images/labels/library%2Fruby). For the current "source of truth" for [`ruby`](https://hub.docker.com/_/ruby/), see [the `library/ruby` file in the official-images repository](https://github.com/docker-library/official-images/blob/master/library/ruby). diff --git a/apply-templates.sh b/apply-templates.sh new file mode 100755 index 0000000000..9ed389b588 --- /dev/null +++ b/apply-templates.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +[ -f versions.json ] # run "versions.sh" first + +jqt='.jq-template.awk' +if [ -n "${BASHBREW_SCRIPTS:-}" ]; then + jqt="$BASHBREW_SCRIPTS/jq-template.awk" +elif [ "$BASH_SOURCE" -nt "$jqt" ]; then + # https://github.com/docker-library/bashbrew/blob/master/scripts/jq-template.awk + wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/9f6a35772ac863a0241f147c820354e4008edf38/scripts/jq-template.awk' +fi + +if [ "$#" -eq 0 ]; then + versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" + eval "set -- $versions" +fi + +generated_warning() { + cat <<-EOH + # + # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" + # + # PLEASE DO NOT EDIT IT DIRECTLY. + # + + EOH +} + +for version; do + export version + + rm -rf "$version/" + + if jq -e '.[env.version] | not' versions.json > /dev/null; then + echo "deleting $version ..." + continue + fi + + variants="$(jq -r '.[env.version].variants | map(@sh) | join(" ")' versions.json)" + eval "variants=( $variants )" + + for variant in "${variants[@]}"; do + export variant + + dir="$version/$variant" + mkdir -p "$dir" + + echo "processing $dir ..." + + { + generated_warning + gawk -f "$jqt" Dockerfile.template + } > "$dir/Dockerfile" + done +done diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index 1b86b6189c..88621d90ca 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -1,15 +1,16 @@ -#!/bin/bash -set -eu - -declare -A aliases=( - [2.3]='2 latest' -) +#!/usr/bin/env bash +set -Eeuo pipefail self="$(basename "$BASH_SOURCE")" cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" -versions=( */ ) -versions=( "${versions[@]%/}" ) +if [ "$#" -eq 0 ]; then + versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" + eval "set -- $versions" +fi + +# sort version numbers with highest first +IFS=$'\n'; set -- $(sort -rV <<<"$*"); unset IFS # get the most recent commit which modified any of "$@" fileCommit() { @@ -21,18 +22,40 @@ dirCommit() { local dir="$1"; shift ( cd "$dir" - fileCommit \ - Dockerfile \ - $(git show HEAD:./Dockerfile | awk ' + files="$( + git show HEAD:./Dockerfile | awk ' toupper($1) == "COPY" { for (i = 2; i < NF; i++) { + if ($i ~ /^--from=/) { + next + } print $i } } - ') + ' + )" + fileCommit Dockerfile $files ) } +getArches() { + local repo="$1"; shift + local officialImagesBase="${BASHBREW_LIBRARY:-https://github.com/docker-library/official-images/raw/HEAD/library}/" + + local parentRepoToArchesStr + parentRepoToArchesStr="$( + find -name 'Dockerfile' -exec awk -v officialImagesBase="$officialImagesBase" ' + toupper($1) == "FROM" && $2 !~ /^('"$repo"'|scratch|.*\/.*)(:|$)/ { + printf "%s%s\n", officialImagesBase, $2 + } + ' '{}' + \ + | sort -u \ + | xargs -r bashbrew cat --format '["{{ .RepoName }}:{{ .TagName }}"]="{{ join " " .TagEntry.Architectures }}"' + )" + eval "declare -g -A parentRepoToArches=( $parentRepoToArchesStr )" +} +getArches 'ruby' + cat <<-EOH # this file is generated via https://github.com/docker-library/ruby/blob/$(fileCommit "$self")/$self @@ -48,37 +71,82 @@ join() { echo "${out#$sep}" } -for version in "${versions[@]}"; do - commit="$(dirCommit "$version")" +declare -A latest=( + #[3]='3.2' + #[latest]='3.2' +) + +for version; do + export version + + if ! fullVersion="$(jq -er '.[env.version] | if . then .version else empty end' versions.json)"; then + continue + fi - fullVersion="$(git show "$commit":"$version/Dockerfile" | awk '$1 == "ENV" && $2 == "RUBY_VERSION" { print $3; exit }')" + variants="$(jq -r '.[env.version].variants | map(@sh) | join(" ")' versions.json)" + eval "variants=( $variants )" versionAliases=( $fullVersion $version - ${aliases[$version]:-} ) - echo - cat <<-EOE - Tags: $(join ', ' "${versionAliases[@]}") - GitCommit: $commit - Directory: $version - EOE - - for variant in slim alpine onbuild; do - [ -f "$version/$variant/Dockerfile" ] || continue - - commit="$(dirCommit "$version/$variant")" + if [ "$version" = "${version%-rc}" ]; then + for a in "${version%%.*}" latest; do # "3", "latest" + if [ -z "${latest[$a]:-}" ]; then + latest[$a]="$version" + versionAliases+=( "$a" ) + fi + done + fi + + defaultDebianVariant="$(jq -r ' + .[env.version].variants + | map(select( + startswith("alpine") + or startswith("slim-") + | not + )) + | .[0] + ' versions.json)" + defaultAlpineVariant="$(jq -r ' + .[env.version].variants + | map(select( + startswith("alpine") + )) + | .[0] + ' versions.json)" + + for v in "${variants[@]}"; do + dir="$version/$v" + [ -f "$dir/Dockerfile" ] || continue + variant="$(basename "$v")" + + commit="$(dirCommit "$dir")" variantAliases=( "${versionAliases[@]/%/-$variant}" ) + case "$variant" in + "$defaultDebianVariant") + variantAliases+=( "${versionAliases[@]}" ) + ;; + *-"$defaultDebianVariant") + variantAliases+=( "${versionAliases[@]/%/-${variant%-$defaultDebianVariant}}" ) + ;; + "$defaultAlpineVariant") + variantAliases+=( "${versionAliases[@]/%/-alpine}" ) + ;; + esac variantAliases=( "${variantAliases[@]//latest-/}" ) + variantParent="$(awk 'toupper($1) == "FROM" { print $2 }' "$dir/Dockerfile")" + variantArches="${parentRepoToArches[$variantParent]}" + echo cat <<-EOE Tags: $(join ', ' "${variantAliases[@]}") + Architectures: $(join ', ' $variantArches) GitCommit: $commit - Directory: $version/$variant + Directory: $dir EOE done done diff --git a/rust.json b/rust.json new file mode 100644 index 0000000000..d2517f8ff9 --- /dev/null +++ b/rust.json @@ -0,0 +1,83 @@ +{ + "rust": { + "version": "1.91.1" + }, + "rustup": { + "arches": { + "amd64": { + "glibc": { + "arch": "x86_64-unknown-linux-gnu", + "sha256": "20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "x86_64-unknown-linux-musl", + "sha256": "e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init" + } + }, + "arm32v5": { + "glibc": { + "arch": "arm-unknown-linux-gnueabi", + "sha256": "3ec755aaa801bdca4caba35cfe3d1657c9c117d87e2e4dd355ab98539115ad45", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/arm-unknown-linux-gnueabi/rustup-init" + } + }, + "arm32v6": { + "glibc": { + "arch": "arm-unknown-linux-gnueabihf", + "sha256": "231a2a004e6e446a1944f957d0eaed858fb9a549264db8dd00a30f491fc67eb8", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/arm-unknown-linux-gnueabihf/rustup-init" + } + }, + "arm32v7": { + "glibc": { + "arch": "armv7-unknown-linux-gnueabihf", + "sha256": "3b8daab6cc3135f2cd4b12919559e6adaee73a2fbefb830fadf0405c20231d61", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/armv7-unknown-linux-gnueabihf/rustup-init" + } + }, + "arm64v8": { + "glibc": { + "arch": "aarch64-unknown-linux-gnu", + "sha256": "e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "aarch64-unknown-linux-musl", + "sha256": "a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init" + } + }, + "i386": { + "glibc": { + "arch": "i686-unknown-linux-gnu", + "sha256": "a5db2c4b29d23e9b318b955dd0337d6b52e93933608469085c924e0d05b1df1f", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/i686-unknown-linux-gnu/rustup-init" + } + }, + "mips64le": { + "glibc": { + "arch": "mips64el-unknown-linux-gnuabi64", + "sha256": "644cec63e594707a6098585038cf47e28546c2abe0dde7149cde71d79a0be674", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/mips64el-unknown-linux-gnuabi64/rustup-init" + } + }, + "ppc64le": { + "glibc": { + "arch": "powerpc64le-unknown-linux-gnu", + "sha256": "acd89c42b47c93bd4266163a7b05d3f26287d5148413c0d47b2e8a7aa67c9dc0", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/powerpc64le-unknown-linux-gnu/rustup-init" + } + }, + "s390x": { + "glibc": { + "arch": "s390x-unknown-linux-gnu", + "sha256": "726b7fd5d8805e73eab4a024a2889f8859d5a44e36041abac0a2436a52d42572", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/s390x-unknown-linux-gnu/rustup-init" + } + } + }, + "version": "1.28.2" + } +} diff --git a/rust.sh b/rust.sh new file mode 100755 index 0000000000..f26615b953 --- /dev/null +++ b/rust.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +rustupVersion="$(curl -fsSL 'https://static.rust-lang.org/rustup/release-stable.toml')" +rustupVersion="$(awk <<<"$rustupVersion" -F "[ ='\"]+" '$1 == "version" { print $2; exit }')" +[ -n "$rustupVersion" ] +export rustupVersion +echo "rustup: $rustupVersion" + +json="$(jq -nc ' + { + rustup: { + version: env.rustupVersion, + arches: ( + [ + # https://github.com/rust-lang/rustup/blob/1.25.1/doc/src/installation/other.md + # (filtering out windows, darwin, bsd, illumos, android, etc - just linux gnu and musl) + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "armv7-unknown-linux-gnueabihf", + "i686-unknown-linux-gnu", + "mips-unknown-linux-gnu", + "mips64-unknown-linux-gnuabi64", + "mips64el-unknown-linux-gnuabi64", + "mipsel-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + # TODO find a good source for scraping these instead of hard-coding them + empty # trailing comma + ] + | map( + split("-") as $split + | $split[0] as $arch + | $split[-1] as $libc + | { + "aarch64": "arm64v8", + "arm": ("arm32v" + if ($libc | endswith("hf")) then "6" else "5" end), + "armv7": "arm32v7", + "i686": "i386", + "mips64el": "mips64le", + "powerpc64le": "ppc64le", + "s390x": "s390x", + "x86_64": "amd64", + # TODO windows? (we do not compile on/for Windows right now) + }[$arch] as $bashbrewArch + | select($bashbrewArch) + | { + ($bashbrewArch): { + (if $libc == "musl" then "musl" else "glibc" end): ({ + "arch": ., + "url": "https://static.rust-lang.org/rustup/archive/\(env.rustupVersion)/\(.)/rustup-init", + } | .sha256 = .url + ".sha256"), + }, + } + ) + | reduce .[] as $map ({}; . * $map) + ), + }, + } +')" + +urls="$(jq <<<"$json" -r '[ .. | .sha256? | select(. and startswith("http")) | @sh ] | join(" ")')" +eval "urls=( $urls )" +for url in "${urls[@]}"; do + sha256="$(curl -fsSL "$url")" + sha256="${sha256%% *}" + [ -n "$sha256" ] + export url sha256 + json="$(jq <<<"$json" -c 'walk(if . == env.url then env.sha256 else . end)')" +done + +# TODO https://static.rust-lang.org/dist/channel-rust-1.66.toml -> scrape stable to know which version is stable but we can scrape other minors to get the latest patch if we needed an older one for some reason (like an older version of Ruby needing an older Rust or a newer Rust no longer working on our older distros, etc) + +rustVersion="$(curl -fsSL 'https://static.rust-lang.org/dist/channel-rust-stable.toml' | grep -E '^(\[|(version|(xz_)?(url|hash|available))[[:space:]]*=)')" +rustVersion="$(awk <<<"$rustVersion" -F "[ ='\"]+" ' + /^\[/ { pkg = $0; next } + pkg == "[pkg.rust]" && $1 == "version" { print $2; exit } +')" +[ -n "$rustVersion" ] +export rustVersion +echo "rust: $rustVersion" +# TODO also scrape available "[pkg.rust.target.*-linux-*]" so we can cross-reference available target arches with rustup + +json="$(jq <<<"$json" -c '.rust = { version: env.rustVersion }')" + +jq <<<"$json" -S . > rust.json diff --git a/update.sh b/update.sh index 70a1b03f04..bac2d7581c 100755 --- a/update.sh +++ b/update.sh @@ -1,61 +1,7 @@ -#!/bin/bash -set -e +#!/usr/bin/env bash +set -Eeuo pipefail cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" -versions=( "$@" ) -if [ ${#versions[@]} -eq 0 ]; then - versions=( */ ) -fi -versions=( "${versions[@]%/}" ) -shaPage=$(curl -fsSL 'https://www.ruby-lang.org/en/downloads/' | tr '\r\n' ' ') - -latest_gem_version() { - curl -sSL "https://rubygems.org/api/v1/gems/$1.json" | sed -r 's/^.*"version":"([^"]+)".*$/\1/' -} - -rubygems="$(latest_gem_version rubygems-update)" -bundler="$(latest_gem_version bundler)" - -travisEnv= -for version in "${versions[@]}"; do - IFS=$'\n'; allVersions=( - $(curl -sSL --compressed "https://cache.ruby-lang.org/pub/ruby/$version/" \ - | grep -E '&2 "warning: cannot determine sha for $version (tried all of ${allVersions[*]}); skipping" - continue - fi - shaVal="$(echo "$shaPage" | sed -r "s/.*Ruby ${fullVersion}<\/a>
\s*sha256: ([^<]+).*/\1/")" - - sedStr=" - s!%%VERSION%%!$version!g; - s!%%FULL_VERSION%%!$fullVersion!g; - s!%%SHA256%%!$shaVal!g; - s!%%RUBYGEMS%%!$rubygems!g; - s!%%BUNDLER%%!$bundler!g; - " - for variant in alpine slim onbuild ''; do - [ -d "$version/$variant" ] || continue - sed -r "$sedStr" "Dockerfile${variant:+-$variant}.template" > "$version/$variant/Dockerfile" - if [ "$variant" != 'onbuild' ]; then - travisEnv='\n - VERSION='"$version VARIANT=$variant$travisEnv" - fi - done -done - -travis="$(awk -v 'RS=\n\n' '$1 == "env:" { $0 = "env:'"$travisEnv"'" } { printf "%s%s", $0, RS }' .travis.yml)" -echo "$travis" > .travis.yml +./versions.sh "$@" +./apply-templates.sh "$@" diff --git a/versions.json b/versions.json new file mode 100644 index 0000000000..48c47b7d04 --- /dev/null +++ b/versions.json @@ -0,0 +1,289 @@ +{ + "3.3": { + "version": "3.3.13", + "date": "2026-10-23", + "post": "/en/news/2026/10/23/ruby-3-3-13-released/", + "url": { + "gz": "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.gz", + "zip": "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.zip", + "xz": "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.13.tar.xz" + }, + "size": { + "gz": 21497008, + "zip": 26961541, + "xz": 15878972 + }, + "sha1": { + "gz": "e89379c35cd61b23c7fef6cff9c5bbece4e2c391", + "zip": "4536403d0c1feaa6290fc7d94e65db4bc2b7f0ed", + "xz": "61e8a88d601ca7a4e9f9c30428fa46be0fdf690d" + }, + "sha256": { + "gz": "4cae72e971bd1cdb20ca87d299111182417c5276c162de8ead0ab0531426cd61", + "zip": "8cf1c468af6dbcaa2c48270cc4c951325dabe5fd84b609641d4bd7b89c9d5766", + "xz": "6bd764359992373a96556b45fb7dfe6b6170da34a0a2fd0b7e1be7932fea982b" + }, + "sha512": { + "gz": "0536341f6f612a1eb0128f7d18eed081b09264c695e6a159a5456ba3050464849791ae26e33a7ea384406fa9e19b98bf194c89638dfe2940d3dbeed5b3126c92", + "zip": "622c8b60b2202aea1aa4caed00cee5984109926793ee57c86a9cc39b1628855f51a26d07258aa85aacc679c6186efc4ebf20b5a51f199de7cdd6fcc98a212d10", + "xz": "906e270e2629b44e469265e08d693f996b467a3fc165fbdb9b8f6f7b37effe4fdae9d4968e72a809d1381e35279cb10b6630d40fac31a634981deb4c30ff325c" + }, + "variants": [ + "trixie", + "slim-trixie", + "bookworm", + "slim-bookworm", + "alpine3.24", + "alpine3.23" + ], + "rust": { + "version": "1.91.1" + }, + "rustup": { + "arches": { + "amd64": { + "glibc": { + "arch": "x86_64-unknown-linux-gnu", + "sha256": "20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "x86_64-unknown-linux-musl", + "sha256": "e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init" + } + }, + "arm64v8": { + "glibc": { + "arch": "aarch64-unknown-linux-gnu", + "sha256": "e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "aarch64-unknown-linux-musl", + "sha256": "a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init" + } + } + }, + "version": "1.28.2" + } + }, + "3.4": { + "version": "3.4.12", + "date": "2026-10-23", + "post": "/en/news/2026/10/23/ruby-3-4-12-released/", + "url": { + "gz": "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.gz", + "zip": "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.zip", + "xz": "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.xz" + }, + "size": { + "gz": 22498017, + "zip": 27719665, + "xz": 16732860 + }, + "sha1": { + "gz": "8ead0b008d7cdeb543282489e7574324ab62939f", + "zip": "c4381ce52fba1af02944cedb35eac569976bfdb8", + "xz": "bf42a4909e1517a2fee26eebbd840bbef3181c61" + }, + "sha256": { + "gz": "5e5d85ad93b0adcccbad47733680f4892bd0078e3342437f7babce01c1872479", + "zip": "b1bec4f3a2b0c47f349a102b013f1c8f345b9991388e75368d1178ac4f9cfc0e", + "xz": "db6c147940d7ad0b706823d42c8e6713c36dec70a1f83f635f1d3a7f0599ec90" + }, + "sha512": { + "gz": "7d4fcf4b57f94974091df406e159ccfd8460e75bd7593993d9d4172a8ad673388bb8505ddb41377014dce4df6d358e019d4fa4098b535aa705e790f65962f1cd", + "zip": "21573c2ba656984c006c8f499f3498c5208eba17d862d93269221c1e7295ace4e5034a53b23931d6b9585c4fc98ecd9b1196b81c2b58543d83550ea60fdc014e", + "xz": "7866ed652921f9f0d601e1e323d29fddee3506cfd89e258cab7601786bffec8a17245468d517d246ecfa7fa9a982b73cfff0aaf6534444753e8b6add297bfbd3" + }, + "variants": [ + "trixie", + "slim-trixie", + "bookworm", + "slim-bookworm", + "alpine3.24", + "alpine3.23" + ], + "rust": { + "version": "1.91.1" + }, + "rustup": { + "arches": { + "amd64": { + "glibc": { + "arch": "x86_64-unknown-linux-gnu", + "sha256": "20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "x86_64-unknown-linux-musl", + "sha256": "e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init" + } + }, + "arm64v8": { + "glibc": { + "arch": "aarch64-unknown-linux-gnu", + "sha256": "e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "aarch64-unknown-linux-musl", + "sha256": "a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init" + } + } + }, + "version": "1.28.2" + } + }, + "4.0": { + "version": "4.0.9", + "date": "2026-10-23", + "post": "/en/news/2026/10/23/ruby-4-0-9-released/", + "url": { + "gz": "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.gz", + "zip": "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.zip", + "xz": "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.9.tar.xz" + }, + "size": { + "gz": 23946524, + "zip": 29263242, + "xz": 17996144 + }, + "sha1": { + "gz": "39f31360bc0c03bde9eec4177e443f6298481e2e", + "zip": "9e2d496d0f3663918c3183b8671c7f4b78aa185e", + "xz": "630cf1e7a4c522f49a2fec383805627691500b54" + }, + "sha256": { + "gz": "c35350682ff050b79702d57ade4516e7336063f510155d19fb2fb5b3f3909511", + "zip": "8242fbb2354cb71811cb2ff4d5e149b7a0ecb700e6c61a897710204ac36f866b", + "xz": "a8057adb39f51ad6dc3106237504c93dd792bb515837b4fe7817ae21ed7e51f4" + }, + "sha512": { + "gz": "9adb0069a07ee1348a04b627d8af1c9f2b6537bdea5dce0b57423659626d9ae3cc04955eae7167014c56bd0f4c7c9d1aa0e4fcfc666eda738b1b0c35a3674114", + "zip": "29422739ea9b5189c24354f6c689f40485c4dc8945e735c38240094195a637dbc6807f4fe295a1579b27ca930e1eb6b2ad7fe1970dad38d0800e049863e8288b", + "xz": "7160b1c6fb61b0e369cddccb29eadae85390d86777c875efc18a56de390b1fe1ff47d6e37ccaf39d2ed477c9811f1224cbb3d2f54a0cbd5d5daf418b1cf2557e" + }, + "variants": [ + "trixie", + "slim-trixie", + "bookworm", + "slim-bookworm", + "alpine3.24", + "alpine3.23" + ], + "rust": { + "version": "1.91.1" + }, + "rustup": { + "arches": { + "amd64": { + "glibc": { + "arch": "x86_64-unknown-linux-gnu", + "sha256": "20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "x86_64-unknown-linux-musl", + "sha256": "e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init" + } + }, + "arm64v8": { + "glibc": { + "arch": "aarch64-unknown-linux-gnu", + "sha256": "e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "aarch64-unknown-linux-musl", + "sha256": "a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init" + } + } + }, + "version": "1.28.2" + } + }, + "4.1": null, + "4.1-rc": { + "version": "4.1.0-preview1", + "date": "2026-10-12", + "post": "/en/news/2026/10/12/ruby-4-1-0-preview1-released/", + "tag": "v4.1.0-preview1", + "stats": { + "files_changed": 6116, + "insertions": 311387, + "deletions": 219997 + }, + "url": { + "gz": "https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.gz", + "zip": "https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.zip", + "xz": "https://cache.ruby-lang.org/pub/ruby/4.1/ruby-4.1.0-preview1.tar.xz" + }, + "size": { + "gz": 26550186, + "zip": 32429495, + "xz": 20218640 + }, + "sha1": { + "gz": "4f04a63c2e65945a4f4f7a6d1372783b60e68c5a", + "zip": "199cf5247f7fc55ff225b3fe6928a39a522000d0", + "xz": "3e6c6919bbdb178fd7d6210e3e960889094fac3c" + }, + "sha256": { + "gz": "fb530bb88e90de3ae91c1310a27ae090e6bd989b8726de50ef12a890a85b88ef", + "zip": "2f1ea85203801c24e64ddf02fc2600f582a2544ef8c84d198111e56b0873b125", + "xz": "b81f20bf2bc72aa360785eb77ffa0c9f15343ac7316637fbf347500fc3e2e3a8" + }, + "sha512": { + "gz": "f5628830685d0ce4ffb26294089c31c452e2e5a0bdcc6a5e0c670f335e52fb33eaaea7df3b834778db1fdde89cd2656d94743f6efa672c3bff6e89d64d5b7539", + "zip": "fd32a7b544ec73f0e642202531170bf8fa4454b2c7ff069748b2bf8e530fc8ae4124572e570c4c56606cc90aeeb723d35cab152978b28ee36b4bb06c798529df", + "xz": "b58bc71a8734ceb38c9c301e0201ecd28559c97a3b93caa1d49e07ff34d51565b0b6ed98f05be41868cc09513784bd3e8b5340574fec37116a4ffcb218d396e4" + }, + "variants": [ + "trixie", + "slim-trixie", + "bookworm", + "slim-bookworm", + "alpine3.24", + "alpine3.23" + ], + "rust": { + "version": "1.91.1" + }, + "rustup": { + "arches": { + "amd64": { + "glibc": { + "arch": "x86_64-unknown-linux-gnu", + "sha256": "20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "x86_64-unknown-linux-musl", + "sha256": "e6599a1c7be58a2d8eaca66a80e0dc006d87bbcf780a58b7343d6e14c1605cb2", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/x86_64-unknown-linux-musl/rustup-init" + } + }, + "arm64v8": { + "glibc": { + "arch": "aarch64-unknown-linux-gnu", + "sha256": "e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-gnu/rustup-init" + }, + "musl": { + "arch": "aarch64-unknown-linux-musl", + "sha256": "a97c8f56d7462908695348dd8c71ea6740c138ce303715793a690503a94fc9a9", + "url": "https://static.rust-lang.org/rustup/archive/1.28.2/aarch64-unknown-linux-musl/rustup-init" + } + } + }, + "version": "1.28.2" + } + } +} diff --git a/versions.sh b/versions.sh new file mode 100755 index 0000000000..8cd12f4b88 --- /dev/null +++ b/versions.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" + +versions=( "$@" ) +if [ ${#versions[@]} -eq 0 ]; then + versions=( */ ) + json='{}' +else + json="$(< versions.json)" +fi +versions=( "${versions[@]%/}" ) + +yq='./.yq' +# https://github.com/mikefarah/yq/releases +# TODO detect host architecture +yqUrl='https://github.com/mikefarah/yq/releases/download/v4.40.5/yq_linux_amd64' +yqSha256='0d6aaf1cf44a8d18fbc7ed0ef14f735a8df8d2e314c4cc0f0242d35c0a440c95' +if command -v yq &> /dev/null; then + # TODO verify that the "yq" in PATH is https://github.com/mikefarah/yq, not the python-based version you'd get from "apt-get install yq" somehow? maybe they're compatible enough for our needs that it doesn't matter? + yq='yq' +elif [ ! -x "$yq" ] || ! sha256sum <<<"$yqSha256 *$yq" --quiet --strict --check; then + wget -qO "$yq.new" "$yqUrl" + sha256sum <<<"$yqSha256 *$yq.new" --quiet --strict --check + chmod +x "$yq.new" + "$yq.new" --version + mv "$yq.new" "$yq" +fi + +releases="$( + wget -qO- 'https://github.com/ruby/www.ruby-lang.org/raw/master/_data/releases.yml' \ + | "$yq" -r '@json' # this *should* work on both the Go-based "yq" we download and the Python-based "yq" available from Debian's APT repo +)" + +for version in "${versions[@]}"; do + rcGrepV='-v' + rcVersion="${version%-rc}" + if [ "$rcVersion" != "$version" ]; then + rcGrepV= + fi + export version rcVersion + + doc="$(jq <<<"$releases" -c ' + map( + select( + .version + # exact versions ("3.1.0-preview1") should match exactly but "X.Y" or "X.Y-rc" should fuzzy match appropriately + | . == env.version or ( + ( + startswith(env.rcVersion + ".") + or startswith(env.rcVersion + "-") + ) and ( + contains("preview") or contains("rc") + | if env.version == env.rcVersion then not else . end + ) + ) + ) + ) + | first // empty + ')" + + if [ -z "$doc" ]; then + echo >&2 "warning: skipping/removing '$version' (does not appear to exist upstream)" + json="$(jq <<<"$json" -c '.[env.version] = null')" + continue + fi + + fullVersion="$(jq <<<"$doc" -r '.version')" + echo "$version: $fullVersion" + + if [ "$rcVersion" != "$version" ] && gaFullVersion="$(jq <<<"$json" -er '.[env.rcVersion] | if . then .version else empty end')"; then + # Ruby pre-releases have only been for .0 since ~2011, so if our pre-release now has a relevant GA, it should go away 👀 + # just in case, we'll also do a version comparison to make sure we don't have a pre-release that's newer than the relevant GA + latestVersion="$({ echo "$fullVersion"; echo "$gaFullVersion"; } | sort -V | tail -1)" + if [[ "$fullVersion" == "$gaFullVersion"* ]] || [ "$latestVersion" = "$gaFullVersion" ]; then + # "x.y.z-rc1" == x.y.z* + json="$(jq <<<"$json" -c 'del(.[env.version])')" + continue + fi + fi + + doc="$(jq <<<"$doc" -c ' + .variants = [ + ( + "trixie", + "bookworm", + empty # trailing comma hack + | ., "slim-" + .), # https://github.com/docker-library/ruby/pull/142#issuecomment-320012893 + ( + "3.24", + "3.23", + empty # trailing comma hack + | "alpine" + .) + ] + ')" + + # YJIT + doc="$(jq <<<"$doc" -sc ' + .[1][].arches? |= if . then with_entries(select(.key | IN( + # https://github.com/ruby/ruby/blob/ruby_4_0/doc/jit/yjit.md ("currently only supports ... x86-64 and arm64/aarch64 CPUs") + # https://github.com/ruby/ruby/blob/ruby_4_0/configure.ac#L3903-L3906 + "amd64", + "arm64v8", + empty # trailing comma + ))) else empty end + | add + ' - rust.json)" + + json="$(jq <<<"$json" -c --argjson doc "$doc" '.[env.version] = $doc')" + + # make sure pre-release versions have a placeholder for GA + if [ "$version" != "$rcVersion" ]; then + json="$(jq <<<"$json" -c '.[env.rcVersion] //= null')" + fi +done + +jq <<<"$json" 'to_entries | sort_by(.key) | from_entries' > versions.json