From eb3e633eeda47f78c845ce610be504d4c9d7d868 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 25 Sep 2025 15:18:41 -0700 Subject: [PATCH 1/3] Enable CI for i386 so we can catch non-amd64-non-arm64 failures sooner (This commit should fail CI - I'll send a follow-up which should fix it.) --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4c0ead..e039afc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,7 @@ jobs: name: Generate Jobs run: | strategy="$("$BASHBREW_SCRIPTS/github-actions/generate.sh")" + strategy="$("$BASHBREW_SCRIPTS/github-actions/munge-i386.sh" -c <<<"$strategy")" echo "strategy=$strategy" >> "$GITHUB_OUTPUT" jq . <<<"$strategy" # sanity check / debugging aid From 782887eb82bfea15a4a6ea05569b81b323dd25cc Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 25 Sep 2025 15:23:05 -0700 Subject: [PATCH 2/3] Add `rust` and `libclang` to dependencies installed during build to fix i386 builds (and hopefully others) --- 6.1/alpine3.21/Dockerfile | 2 ++ 6.1/alpine3.22/Dockerfile | 2 ++ 6.1/bookworm/Dockerfile | 2 ++ 6.1/trixie/Dockerfile | 2 ++ Dockerfile.template | 13 ++++++++++++- 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/6.1/alpine3.21/Dockerfile b/6.1/alpine3.21/Dockerfile index cf17681..9daa738 100644 --- a/6.1/alpine3.21/Dockerfile +++ b/6.1/alpine3.21/Dockerfile @@ -86,6 +86,8 @@ RUN set -eux; \ RUN set -eux; \ apk add --no-cache --virtual .build-deps \ + cargo \ + clang19-dev \ coreutils \ freetds-dev \ gcc \ diff --git a/6.1/alpine3.22/Dockerfile b/6.1/alpine3.22/Dockerfile index 9da1d07..c51a84a 100644 --- a/6.1/alpine3.22/Dockerfile +++ b/6.1/alpine3.22/Dockerfile @@ -86,6 +86,8 @@ RUN set -eux; \ RUN set -eux; \ apk add --no-cache --virtual .build-deps \ + cargo \ + clang19-dev \ coreutils \ freetds-dev \ gcc \ diff --git a/6.1/bookworm/Dockerfile b/6.1/bookworm/Dockerfile index 849fcea..2658af6 100644 --- a/6.1/bookworm/Dockerfile +++ b/6.1/bookworm/Dockerfile @@ -92,9 +92,11 @@ RUN set -eux; \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends \ + cargo \ default-libmysqlclient-dev \ freetds-dev \ gcc \ + libclang-dev \ libpq-dev \ libsqlite3-dev \ libxml2-dev \ diff --git a/6.1/trixie/Dockerfile b/6.1/trixie/Dockerfile index 2dfa281..8a9dde5 100644 --- a/6.1/trixie/Dockerfile +++ b/6.1/trixie/Dockerfile @@ -90,9 +90,11 @@ RUN set -eux; \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends \ + cargo \ default-libmysqlclient-dev \ freetds-dev \ gcc \ + libclang-dev \ libpq-dev \ libsqlite3-dev \ libxml2-dev \ diff --git a/Dockerfile.template b/Dockerfile.template index 2923338..2e880b4 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -163,7 +163,12 @@ ENV BUNDLE_FORCE_RUBY_PLATFORM 1 "ttf2ufm", "zlib-dev", empty - else empty end, + else + # 6.1+ needs to compile some extensions on non-amd64-non-arm64 architectures + "cargo", + "clang19-dev", # TODO the dep needing libclang.so doesn't seem to care what version, so maybe there's a more generic dep we could use here? + empty + end, empty else # debian packages @@ -175,6 +180,12 @@ ENV BUNDLE_FORCE_RUBY_PLATFORM 1 "libyaml-dev", "pkgconf", "xz-utils", + if IN(env.version; "5.1", "6.0") then empty else + # 6.1+ needs to compile some extensions on non-amd64-non-arm64 architectures + "cargo", + "libclang-dev", + empty + end, empty end ] | sort | ( From 4257a57a87ad770cd349ac1fbf9e3c33c6031936 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 25 Sep 2025 16:25:24 -0700 Subject: [PATCH 3/3] Remove bookworm from 6.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 😇 --- 6.1/bookworm/Dockerfile | 152 -------------------------- 6.1/bookworm/docker-entrypoint.sh | 173 ------------------------------ versions.json | 1 - versions.sh | 4 + 4 files changed, 4 insertions(+), 326 deletions(-) delete mode 100644 6.1/bookworm/Dockerfile delete mode 100755 6.1/bookworm/docker-entrypoint.sh diff --git a/6.1/bookworm/Dockerfile b/6.1/bookworm/Dockerfile deleted file mode 100644 index 2658af6..0000000 --- a/6.1/bookworm/Dockerfile +++ /dev/null @@ -1,152 +0,0 @@ -# -# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" -# -# PLEASE DO NOT EDIT IT DIRECTLY. -# - -FROM ruby:3.4-slim-bookworm - -# explicitly set uid/gid to guarantee that it won't change in the future -# the values 999:999 are identical to the current user/group id assigned -RUN groupadd -r -g 999 redmine && useradd -r -g redmine -u 999 redmine - -RUN set -eux; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - bzr \ - ca-certificates \ - ghostscript \ - git \ - gsfonts \ - imagemagick \ - mercurial \ - openssh-client \ - subversion \ - tini \ - wget \ - ; \ -# allow imagemagick to use ghostscript for PDF -> PNG thumbnail conversion (4.1+) - sed -ri 's/(rights)="none" (pattern="PDF")/\1="read" \2/' /etc/ImageMagick-6/policy.xml; \ - rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -# https://github.com/tianon/gosu/releases -ENV GOSU_VERSION 1.19 -RUN set -eux; \ - \ - savedAptMark="$(apt-mark showmanual)"; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - gnupg \ - ; \ - rm -rf /var/lib/apt/lists/*; \ - \ - dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ - wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ - wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ - export GNUPGHOME="$(mktemp -d)"; \ - gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ - gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ - gpgconf --kill all; \ - rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ - \ - apt-mark auto '.*' > /dev/null; \ - apt-mark manual $savedAptMark > /dev/null; \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ - \ -# smoke test - chmod +x /usr/local/bin/gosu; \ - gosu --version; \ - gosu nobody true - -ENV RAILS_ENV production -WORKDIR /usr/src/redmine - -# https://github.com/docker-library/redmine/issues/138#issuecomment-438834176 -# (bundler needs this for running as an arbitrary user) -ENV HOME /home/redmine -RUN set -eux; \ - [ ! -d "$HOME" ]; \ - mkdir -p "$HOME"; \ - chown redmine:redmine "$HOME"; \ - chmod 1777 "$HOME" - -ENV REDMINE_VERSION 6.1.0 -ENV REDMINE_DOWNLOAD_URL https://www.redmine.org/releases/redmine-6.1.0.tar.gz -ENV REDMINE_DOWNLOAD_SHA256 bc483da195f2444491d870e40f7fc909ae750f7ba8d0e28831e6d6c478812b88 -ENV RAILS_LOG_TO_STDOUT true - -RUN set -eux; \ - wget -O redmine.tar.gz "$REDMINE_DOWNLOAD_URL"; \ - echo "$REDMINE_DOWNLOAD_SHA256 *redmine.tar.gz" | sha256sum -c -; \ - tar -xf redmine.tar.gz --strip-components=1; \ - rm redmine.tar.gz files/delete.me log/delete.me; \ - # https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-8-File-system-permissions - mkdir -p log public/assets public/plugin_assets sqlite tmp/pdf tmp/pids; \ - chown -R redmine:redmine ./; \ -# fix permissions for running as an arbitrary user - chmod -R ugo=rwX config db sqlite; \ - find log tmp -type d -exec chmod 1777 '{}' + - -RUN set -eux; \ - savedAptMark="$(apt-mark showmanual)"; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - cargo \ - default-libmysqlclient-dev \ - freetds-dev \ - gcc \ - libclang-dev \ - libpq-dev \ - libsqlite3-dev \ - libxml2-dev \ - libxslt-dev \ - libyaml-dev \ - make \ - patch \ - pkgconf \ - xz-utils \ - ; \ - rm -rf /var/lib/apt/lists/*; \ - \ - gosu redmine bundle config --local without 'development test'; \ -# https://github.com/redmine/redmine/commit/23dc108e70a0794f444803ac827a690085dcd557 -# ("gem puma" already exists in the Gemfile, but under "group :test" and we want it all the time) - puma="$(grep -E "^[[:space:]]*gem [:'\"]puma['\",[:space:]].*\$" Gemfile)"; \ - { echo; echo "$puma"; } | sed -re 's/^[[:space:]]+//' >> Gemfile; \ -# fill up "database.yml" with bogus entries so the redmine Gemfile will pre-install all database adapter dependencies -# https://github.com/redmine/redmine/blob/e9f9767089a4e3efbd73c35fc55c5c7eb85dd7d3/Gemfile#L50-L79 - echo '# the following entries only exist to force `bundle install` to pre-install all database adapter dependencies -- they can be safely removed/ignored' > ./config/database.yml; \ - for adapter in mysql2 postgresql sqlserver sqlite3; do \ - echo "$adapter:" >> ./config/database.yml; \ - echo " adapter: $adapter" >> ./config/database.yml; \ - done; \ -# nokogiri's vendored libxml2 + libxslt do not build on mips64le, so use the apt packages when building - gosu redmine bundle config build.nokogiri --use-system-libraries; \ - gosu redmine bundle install --jobs "$(nproc)"; \ - rm ./config/database.yml; \ -# fix permissions for running as an arbitrary user - chmod -R ugo=rwX Gemfile.lock "$GEM_HOME"; \ - rm -rf ~redmine/.bundle; \ - \ -# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies - apt-mark auto '.*' > /dev/null; \ - [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ - find /usr/local -type f -executable -exec ldd '{}' ';' \ - | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ - | sort -u \ - | xargs -rt dpkg-query --search \ -# https://manpages.debian.org/trixie/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 - -VOLUME /usr/src/redmine/files - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] - -EXPOSE 3000 -CMD ["rails", "server", "-b", "0.0.0.0"] diff --git a/6.1/bookworm/docker-entrypoint.sh b/6.1/bookworm/docker-entrypoint.sh deleted file mode 100755 index 0bcee63..0000000 --- a/6.1/bookworm/docker-entrypoint.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash -set -Eeo pipefail -# TODO add "-u" - -# usage: file_env VAR [DEFAULT] -# ie: file_env 'XYZ_DB_PASSWORD' 'example' -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) -file_env() { - local var="$1" - local fileVar="${var}_FILE" - local def="${2:-}" - if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then - echo >&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -isLikelyRedmine= -case "$1" in - rails | rake ) isLikelyRedmine=1 ;; - bundle ) if [ "${2:-}" = 'exec' ]; then isLikelyRedmine=1; fi ;; # https://github.com/docker-library/redmine/pull/386 - "bundle exec sidekiq" -esac - -_fix_permissions() { - # https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-8-File-system-permissions - local dirs=( config log public/assets public/plugin_assets tmp ) args=() - if [ "$(id -u)" = '0' ]; then - args+=( ${args[@]:+,} '(' '!' -user redmine -exec chown redmine:redmine '{}' + ')' ) - - # https://github.com/docker-library/redmine/issues/268 - scanning "files" might be *really* expensive, so we should skip it if it seems like it's "already correct" - local filesOwnerMode - filesOwnerMode="$(stat -c '%U:%a' files)" - if [ "$filesOwnerMode" != 'redmine:755' ]; then - dirs+=( files ) - fi - fi - # directories 755, files 644: - args+=( ${args[@]:+,} '(' -type d '!' -perm 755 -exec sh -c 'chmod 755 "$@" 2>/dev/null || :' -- '{}' + ')' ) - args+=( ${args[@]:+,} '(' -type f '!' -perm 644 -exec sh -c 'chmod 644 "$@" 2>/dev/null || :' -- '{}' + ')' ) - find "${dirs[@]}" "${args[@]}" -} - -# allow the container to be started with `--user` -if [ -n "$isLikelyRedmine" ] && [ "$(id -u)" = '0' ]; then - _fix_permissions - exec gosu redmine "$BASH_SOURCE" "$@" -fi - -if [ -n "$isLikelyRedmine" ]; then - _fix_permissions - if [ ! -f './config/database.yml' ]; then - file_env 'REDMINE_DB_MYSQL' - file_env 'REDMINE_DB_POSTGRES' - file_env 'REDMINE_DB_SQLSERVER' - - if [ "$MYSQL_PORT_3306_TCP" ] && [ -z "$REDMINE_DB_MYSQL" ]; then - export REDMINE_DB_MYSQL='mysql' - elif [ "$POSTGRES_PORT_5432_TCP" ] && [ -z "$REDMINE_DB_POSTGRES" ]; then - export REDMINE_DB_POSTGRES='postgres' - fi - - if [ "$REDMINE_DB_MYSQL" ]; then - adapter='mysql2' - host="$REDMINE_DB_MYSQL" - file_env 'REDMINE_DB_PORT' '3306' - file_env 'REDMINE_DB_USERNAME' "${MYSQL_ENV_MYSQL_USER:-root}" - file_env 'REDMINE_DB_PASSWORD' "${MYSQL_ENV_MYSQL_PASSWORD:-${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - file_env 'REDMINE_DB_DATABASE' "${MYSQL_ENV_MYSQL_DATABASE:-${MYSQL_ENV_MYSQL_USER:-redmine}}" - file_env 'REDMINE_DB_ENCODING' '' - elif [ "$REDMINE_DB_POSTGRES" ]; then - adapter='postgresql' - host="$REDMINE_DB_POSTGRES" - file_env 'REDMINE_DB_PORT' '5432' - file_env 'REDMINE_DB_USERNAME' "${POSTGRES_ENV_POSTGRES_USER:-postgres}" - file_env 'REDMINE_DB_PASSWORD' "${POSTGRES_ENV_POSTGRES_PASSWORD}" - file_env 'REDMINE_DB_DATABASE' "${POSTGRES_ENV_POSTGRES_DB:-${REDMINE_DB_USERNAME:-}}" - file_env 'REDMINE_DB_ENCODING' 'utf8' - elif [ "$REDMINE_DB_SQLSERVER" ]; then - adapter='sqlserver' - host="$REDMINE_DB_SQLSERVER" - file_env 'REDMINE_DB_PORT' '1433' - file_env 'REDMINE_DB_USERNAME' '' - file_env 'REDMINE_DB_PASSWORD' '' - file_env 'REDMINE_DB_DATABASE' '' - file_env 'REDMINE_DB_ENCODING' '' - else - echo >&2 - echo >&2 'warning: missing REDMINE_DB_MYSQL, REDMINE_DB_POSTGRES, or REDMINE_DB_SQLSERVER environment variables' - echo >&2 - echo >&2 '*** Using sqlite3 as fallback. ***' - echo >&2 - - adapter='sqlite3' - host='localhost' - file_env 'REDMINE_DB_PORT' '' - file_env 'REDMINE_DB_USERNAME' 'redmine' - file_env 'REDMINE_DB_PASSWORD' '' - file_env 'REDMINE_DB_DATABASE' 'sqlite/redmine.db' - file_env 'REDMINE_DB_ENCODING' 'utf8' - - mkdir -p "$(dirname "$REDMINE_DB_DATABASE")" - if [ "$(id -u)" = '0' ]; then - find "$(dirname "$REDMINE_DB_DATABASE")" \! -user redmine -exec chown redmine '{}' + - fi - fi - - REDMINE_DB_ADAPTER="$adapter" - REDMINE_DB_HOST="$host" - echo "$RAILS_ENV:" > config/database.yml - for var in \ - adapter \ - host \ - port \ - username \ - password \ - database \ - encoding \ - ; do - env="REDMINE_DB_${var^^}" - val="${!env}" - [ -n "$val" ] || continue - if [ "$var" != 'adapter' ]; then - # https://github.com/docker-library/redmine/issues/353 🙃 - val='"'"$val"'"' - # (only add double quotes to every value *except* `adapter: xxx`) - fi - echo " $var: $val" >> config/database.yml - done - fi - - # install additional gems for Gemfile.local and plugins - bundle check || bundle install - - file_env 'REDMINE_SECRET_KEY_BASE' - # just use the rails variable rather than trying to put it into a yml file - # https://github.com/rails/rails/blob/6-1-stable/railties/lib/rails/application.rb#L438 - # https://github.com/rails/rails/blob/1aa9987169213ce5ce43c20b2643bc64c235e792/railties/lib/rails/application.rb#L484 (rails 7.1-stable) - if [ -n "${SECRET_KEY_BASE}" ] && [ -n "${REDMINE_SECRET_KEY_BASE}" ]; then - echo >&2 - echo >&2 'warning: both SECRET_KEY_BASE and REDMINE_SECRET_KEY_BASE{_FILE} set, only SECRET_KEY_BASE will apply' - echo >&2 - fi - : "${SECRET_KEY_BASE:=$REDMINE_SECRET_KEY_BASE}" - export SECRET_KEY_BASE - # generate SECRET_KEY_BASE if not set; this is not recommended unless the secret_token.rb is saved when container is recreated - if [ -z "$SECRET_KEY_BASE" ] && [ ! -f config/initializers/secret_token.rb ]; then - echo >&2 'warning: no *SECRET_KEY_BASE set; running `rake generate_secret_token` to create one in "config/initializers/secret_token.rb"' - unset SECRET_KEY_BASE # just in case - rake generate_secret_token - fi - - if [ "$1" != 'rake' -a -z "$REDMINE_NO_DB_MIGRATE" ]; then - rake db:migrate - fi - - if [ "$1" != 'rake' -a -n "$REDMINE_PLUGINS_MIGRATE" ]; then - rake redmine:plugins:migrate - fi - - # remove PID file to enable restarting the container - rm -f tmp/pids/server.pid -fi - -exec "$@" diff --git a/versions.json b/versions.json index 1c89e2d..3d6cda9 100644 --- a/versions.json +++ b/versions.json @@ -41,7 +41,6 @@ "sha256": "bc483da195f2444491d870e40f7fc909ae750f7ba8d0e28831e6d6c478812b88", "variants": [ "trixie", - "bookworm", "alpine3.22", "alpine3.21" ], diff --git a/versions.sh b/versions.sh index d2f3285..9875737 100755 --- a/versions.sh +++ b/versions.sh @@ -88,6 +88,10 @@ for version in "${versions[@]}"; do get_version "$version" for suite in "${supportedDebianSuites[@]}"; do + if [ "$suite" = 'bookworm' ] && [ "$version" != '5.1' ] && [ "$version" != '6.0' ]; then + # https://github.com/docker-library/redmine/pull/393 (6.1+ deps need newer rust on other arches and just isn't worth the trouble) + continue + fi export suite doc="$(jq <<<"$doc" -c ' .variants += [ env.suite ]