diff --git a/.travis.yml b/.travis.yml index c7171ba7..a5c6de5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: bash services: docker env: + - VERSION=3.4 - VERSION=3.3 - VERSION=3.2 - VERSION=3.1 diff --git a/3.4/Dockerfile b/3.4/Dockerfile new file mode 100644 index 00000000..23ad7eee --- /dev/null +++ b/3.4/Dockerfile @@ -0,0 +1,90 @@ +FROM ruby:2.4-slim + +# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added +RUN groupadd -r redmine && useradd -r -g redmine redmine + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + wget \ + && rm -rf /var/lib/apt/lists/* + +# grab gosu for easy step-down from root +ENV GOSU_VERSION 1.7 +RUN set -x \ + && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ + && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true + +# grab tini for signal processing and zombie killing +ENV TINI_VERSION v0.9.0 +RUN set -x \ + && wget -O /usr/local/bin/tini "https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini" \ + && wget -O /usr/local/bin/tini.asc "https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 6380DC428747F6C393FEACA59A84159D7001A4E5 \ + && gpg --batch --verify /usr/local/bin/tini.asc /usr/local/bin/tini \ + && rm -r "$GNUPGHOME" /usr/local/bin/tini.asc \ + && chmod +x /usr/local/bin/tini \ + && tini -h + +RUN apt-get update && apt-get install -y --no-install-recommends \ + imagemagick \ + libmysqlclient18 \ + libpq5 \ + libsqlite3-0 \ + \ + bzr \ + git \ + mercurial \ + openssh-client \ + subversion \ + && rm -rf /var/lib/apt/lists/* + +ENV RAILS_ENV production +WORKDIR /usr/src/redmine + +ENV REDMINE_VERSION 3.4.1 +ENV REDMINE_DOWNLOAD_MD5 79b07289c0b591e81180d017dbf6ebf4 + +RUN wget -O redmine.tar.gz "https://www.redmine.org/releases/redmine-${REDMINE_VERSION}.tar.gz" \ + && echo "$REDMINE_DOWNLOAD_MD5 redmine.tar.gz" | md5sum -c - \ + && tar -xvf redmine.tar.gz --strip-components=1 \ + && rm redmine.tar.gz files/delete.me log/delete.me \ + && mkdir -p tmp/pdf public/plugin_assets \ + && chown -R redmine:redmine ./ + +RUN buildDeps=' \ + gcc \ + libmagickcore-dev \ + libmagickwand-dev \ + libmysqlclient-dev \ + libpq-dev \ + libsqlite3-dev \ + make \ + patch \ + ' \ + && set -ex \ + && apt-get update && apt-get install -y $buildDeps --no-install-recommends \ + && rm -rf /var/lib/apt/lists/* \ + && bundle install --without development test \ + && for adapter in mysql2 postgresql sqlite3; do \ + echo "$RAILS_ENV:" > ./config/database.yml; \ + echo " adapter: $adapter" >> ./config/database.yml; \ + bundle install --without development test; \ + done \ + && rm ./config/database.yml \ + && apt-get purge -y --auto-remove $buildDeps + + +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/3.4/docker-entrypoint.sh b/3.4/docker-entrypoint.sh new file mode 100755 index 00000000..6c70881c --- /dev/null +++ b/3.4/docker-entrypoint.sh @@ -0,0 +1,130 @@ +#!/bin/bash +set -e + +# 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" +} + +case "$1" in + rails|rake|passenger) + if [ ! -f './config/database.yml' ]; then + file_env 'REDMINE_DB_MYSQL' + file_env 'REDMINE_DB_POSTGRES' + + 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' + else + echo >&2 + echo >&2 'warning: missing REDMINE_DB_MYSQL or REDMINE_DB_POSTGRES 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")" + chown -R redmine:redmine "$(dirname "$REDMINE_DB_DATABASE")" + 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 + echo " $var: \"$val\"" >> config/database.yml + done + fi + + # ensure the right database adapter is active in the Gemfile.lock + bundle install --without development test + + if [ ! -s config/secrets.yml ]; then + file_env 'REDMINE_SECRET_KEY_BASE' + if [ "$REDMINE_SECRET_KEY_BASE" ]; then + cat > 'config/secrets.yml' <<-YML + $RAILS_ENV: + secret_key_base: "$REDMINE_SECRET_KEY_BASE" + YML + elif [ ! -f /usr/src/redmine/config/initializers/secret_token.rb ]; then + rake generate_secret_token + fi + fi + if [ "$1" != 'rake' -a -z "$REDMINE_NO_DB_MIGRATE" ]; then + gosu redmine rake db:migrate + fi + + # https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-8-File-system-permissions + chown -R redmine:redmine files log public/plugin_assets + chmod -R 755 files log tmp public/plugin_assets + + if [ "$1" != 'rake' -a -n "$REDMINE_PLUGINS_MIGRATE" ]; then + gosu redmine rake redmine:plugins:migrate + fi + + # remove PID file to enable restarting the container + rm -f /usr/src/redmine/tmp/pids/server.pid + + if [ "$1" = 'passenger' ]; then + # Don't fear the reaper. + set -- tini -- "$@" + fi + + set -- gosu redmine "$@" + ;; +esac + +exec "$@" diff --git a/3.4/passenger/Dockerfile b/3.4/passenger/Dockerfile new file mode 100644 index 00000000..28f2e88e --- /dev/null +++ b/3.4/passenger/Dockerfile @@ -0,0 +1,18 @@ +FROM redmine:3.4 + +ENV PASSENGER_VERSION 5.1.5 + +RUN buildDeps=' \ + make \ + ' \ + && set -x \ + && apt-get update && apt-get install -y --no-install-recommends $buildDeps && rm -rf /var/lib/apt/lists/* \ + && gem install passenger --version "$PASSENGER_VERSION" \ + && apt-get purge -y --auto-remove $buildDeps + +# pre-download the PassengerAgent and the NGINX engine +RUN set -x \ + && passenger-config install-agent \ + && passenger-config download-nginx-engine + +CMD ["passenger", "start"] diff --git a/Dockerfile.template b/Dockerfile.template index 9b81bba2..087a0447 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -1,4 +1,4 @@ -FROM ruby:2.2-slim +FROM ruby:%%RUBY_VERSION%%-slim # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added RUN groupadd -r redmine && useradd -r -g redmine redmine diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index 352f79d4..9554ed60 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -2,8 +2,7 @@ set -eu declare -A aliases=( - [3.3]='3 latest' - [2.6]='2' + [3.4]='3 latest' ) self="$(basename "$BASH_SOURCE")" @@ -12,6 +11,9 @@ cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" versions=( */ ) versions=( "${versions[@]%/}" ) +# sort version numbers with highest first +IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -rV) ); unset IFS + # get the most recent commit which modified any of "$@" fileCommit() { git log -1 --format='format:%H' HEAD -- "$@" diff --git a/update.sh b/update.sh index 2d24c151..3bcf6fda 100755 --- a/update.sh +++ b/update.sh @@ -1,6 +1,14 @@ #!/bin/bash set -eo pipefail +# see https://www.redmine.org/projects/redmine/wiki/redmineinstall +defaultRubyVersion='2.4' +declare -A rubyVersions=( + [3.3]='2.2' + [3.2]='2.2' + [3.1]='2.2' +) + cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" versions=( "$@" ) @@ -18,17 +26,24 @@ travisEnv= for version in "${versions[@]}"; do fullVersion="$(echo $versionsPage | sed -r "s/.*($version\.[0-9]+)\.tar\.gz[^.].*/\1/" | sort -V | tail -1)" md5="$(curl -fsSL "$relasesUrl/redmine-$fullVersion.tar.gz.md5" | cut -d' ' -f1)" - + + rubyVersion="${rubyVersions[$version]:-$defaultRubyVersion}" + ( set -x - + cp docker-entrypoint.sh "$version/" - sed 's/%%REDMINE_DOWNLOAD_MD5%%/'"$md5"'/; s/%%REDMINE_VERSION%%/'"$fullVersion"'/' Dockerfile.template > "$version/Dockerfile" - + sed -e 's/%%REDMINE_VERSION%%/'"$fullVersion"'/' \ + -e 's/%%RUBY_VERSION%%/'"$rubyVersion"'/' \ + -e 's/%%REDMINE_DOWNLOAD_MD5%%/'"$md5"'/' \ + Dockerfile.template > "$version/Dockerfile" + mkdir -p "$version/passenger" - sed 's/%%REDMINE%%/redmine:'"$version"'/; s/%%PASSENGER_VERSION%%/'"$passenger"'/' Dockerfile-passenger.template > "$version/passenger/Dockerfile" + sed -e 's/%%REDMINE%%/redmine:'"$version"'/' \ + -e 's/%%PASSENGER_VERSION%%/'"$passenger"'/' \ + Dockerfile-passenger.template > "$version/passenger/Dockerfile" ) - + travisEnv='\n - VERSION='"$version$travisEnv" done