From bb87782f9b3c583df09f62c4609a89c61bf1cc2f Mon Sep 17 00:00:00 2001 From: f Date: Tue, 17 Sep 2019 22:01:34 -0300 Subject: [PATCH 01/10] geminabox --- Dockerfile | 33 ++++++++++++++++++++++++++++++++- Gemfile | 7 +++++++ config.ru | 11 +++++++++++ geminabox.sh | 18 ++++++++++++++++++ monit.conf | 4 ++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 Gemfile create mode 100644 config.ru create mode 100644 geminabox.sh create mode 100644 monit.conf diff --git a/Dockerfile b/Dockerfile index 59c5898..cf4b84c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,33 @@ -FROM sutty/monit:latest +FROM sutty/sdk-ruby:latest AS build MAINTAINER "f " + +RUN install -dm 2750 -o app -g www-data /srv/http + +USER app +WORKDIR /srv/http +COPY --chown=app:www-data ./Gemfile . +COPY --chown=app:www-data ./config.ru . +RUN bundle install --path=./vendor +RUN find ./vendor -name '*.so' | xargs -r strip --strip-unneeded + +FROM sutty/daemonize:latest AS daemonize + +RUN echo /home/builder/packages/home > /etc/apk/repositories +RUN apk add --no-cache daemonize + +FROM sutty/monit +ENV RACK_ENV=production + +RUN addgroup -g 82 -S www-data +RUN adduser -s /bin/sh -G www-data -h /srv/http -D app + +RUN apk add --no-cache ruby ruby-bundler ruby-json +COPY --from=daemonize /usr/sbin/daemonize /usr/sbin/daemonize +COPY ./monit.conf /etc/monit.d/geminabox.conf +COPY ./geminabox.sh /usr/local/bin/geminabox +COPY --from=build /srv/http /srv/http +RUN install -dm 2750 -o app -g www-data /srv/http/geminabox +RUN chmod 755 /usr/local/bin/geminabox + +EXPOSE 9292 +VOLUME /srv/http/geminabox diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..5236acc --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'redis-rack' +gem 'hiredis' +gem 'redis', require: %w[redis redis/connection/hiredis] +gem 'geminabox' +gem 'puma' diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..4173e31 --- /dev/null +++ b/config.ru @@ -0,0 +1,11 @@ +require 'geminabox' +require 'rack/session/redis' + +Geminabox.data = '/srv/http' +Geminabox.rubygems_proxy = true +Geminabox.allow_remote_failure = true + +use Rack::Session::Redis, redis_server: 'redis://redis:6379/2' +use Rack::Protection + +run Geminabox::Server diff --git a/geminabox.sh b/geminabox.sh new file mode 100644 index 0000000..5807572 --- /dev/null +++ b/geminabox.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +dir=/srv/http/geminabox +pid=/tmp/geminabox.pid + +chown -R app:www-data /srv/http +cd ${dir} + +for link in Gemfile Gemfile.lock .bundle config.ru vendor; do + test -e ${link} && continue + ln -s ../${link} . +done + +rm -f ${pid} +daemonize -p ${pid} -l ${pid} -o ${dir}/access.log -e ${dir}/error.log \ + -c ${dir} -a -u app \ + `which bundle` exec rackup diff --git a/monit.conf b/monit.conf new file mode 100644 index 0000000..91829f1 --- /dev/null +++ b/monit.conf @@ -0,0 +1,4 @@ +check process geminabox with pidfile /tmp/geminabox.pid + start program = "/usr/local/bin/geminabox" + stop program = "/bin/sh -c 'cat /tmp/geminabox.pid | xargs kill'" + if failed port 9292 protocol http for 3 times within 5 cycles then restart From a510009ca4ac437e9666afffda784f30c33e3ef0 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 10:19:36 -0300 Subject: [PATCH 02/10] basic auth and store gems --- Dockerfile | 4 ++-- config.ru | 6 ++++++ geminabox.sh | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index cf4b84c..35d3850 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,8 +26,8 @@ COPY --from=daemonize /usr/sbin/daemonize /usr/sbin/daemonize COPY ./monit.conf /etc/monit.d/geminabox.conf COPY ./geminabox.sh /usr/local/bin/geminabox COPY --from=build /srv/http /srv/http -RUN install -dm 2750 -o app -g www-data /srv/http/geminabox +RUN install -dm 2750 -o app -g www-data /srv/gems RUN chmod 755 /usr/local/bin/geminabox EXPOSE 9292 -VOLUME /srv/http/geminabox +VOLUME /srv/gems diff --git a/config.ru b/config.ru index 4173e31..8d3f596 100644 --- a/config.ru +++ b/config.ru @@ -1,10 +1,16 @@ require 'geminabox' require 'rack/session/redis' +require 'securerandom' Geminabox.data = '/srv/http' Geminabox.rubygems_proxy = true Geminabox.allow_remote_failure = true +use Rack::Auth::Basic, 'Gems' do |username, password| + username == ENV.fetch('HTTP_BASIC_USER', SecureRandom.hex) && + password == ENV.fetch('HTTP_BASIC_PASSWORD', SecureRandom.hex) +end + use Rack::Session::Redis, redis_server: 'redis://redis:6379/2' use Rack::Protection diff --git a/geminabox.sh b/geminabox.sh index 5807572..fa40613 100644 --- a/geminabox.sh +++ b/geminabox.sh @@ -1,7 +1,7 @@ #!/bin/sh set -e -dir=/srv/http/geminabox +dir=/srv/gems pid=/tmp/geminabox.pid chown -R app:www-data /srv/http @@ -9,7 +9,7 @@ cd ${dir} for link in Gemfile Gemfile.lock .bundle config.ru vendor; do test -e ${link} && continue - ln -s ../${link} . + ln -s /srv/http/${link} . done rm -f ${pid} From ea42410518ebe3afdd26b0dea528b8427de60235 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 10:46:57 -0300 Subject: [PATCH 03/10] recover ownership --- geminabox.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geminabox.sh b/geminabox.sh index fa40613..c94c01f 100644 --- a/geminabox.sh +++ b/geminabox.sh @@ -4,7 +4,7 @@ set -e dir=/srv/gems pid=/tmp/geminabox.pid -chown -R app:www-data /srv/http +chown -R app:www-data ${dir} cd ${dir} for link in Gemfile Gemfile.lock .bundle config.ru vendor; do From 44c3e728d11ba22fd99e4b4f3644b074d6bf23f9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 11:00:26 -0300 Subject: [PATCH 04/10] public downloads --- config.ru | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/config.ru b/config.ru index 8d3f596..c6074bd 100644 --- a/config.ru +++ b/config.ru @@ -6,9 +6,37 @@ Geminabox.data = '/srv/http' Geminabox.rubygems_proxy = true Geminabox.allow_remote_failure = true -use Rack::Auth::Basic, 'Gems' do |username, password| - username == ENV.fetch('HTTP_BASIC_USER', SecureRandom.hex) && - password == ENV.fetch('HTTP_BASIC_PASSWORD', SecureRandom.hex) +# https://github.com/geminabox/geminabox/wiki/Http-Basic-Auth +Geminabox::Server.helpers do + def protected! + unless authorized? + response['WWW-Authenticate'] = %(Basic realm="Geminabox") + halt 401, "No pushing or deleting without auth.\n" + end + end + + def authorized? + @auth ||= Rack::Auth::Basic::Request.new(request.env) + @auth.provided? && + @auth.basic? && + @auth.credentials && + @auth.credentials == [ENV.fetch('HTTP_BASIC_USER', SecureRandom.hex), + ENV.fetch('HTTP_BASIC_PASSWORD', SecureRandom.hex)] + end +end + +Geminabox::Server.before '/upload' do + protected! +end + +Geminabox::Server.before do + protected! if request.delete? +end + +Geminabox::Server.before '/api/v1/gems' do + unless ENV['HTTP_AUTHORIZATION'] == 'API_KEY' + halt 401, "Access Denied. Api_key invalid or missing.\n" + end end use Rack::Session::Redis, redis_server: 'redis://redis:6379/2' From 47bdebcc0f04bd4b1ec5cf0cfe084822756161ca Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 13:56:54 -0300 Subject: [PATCH 05/10] musl --- Dockerfile | 5 +++++ rubygems-platform-musl.patch | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 rubygems-platform-musl.patch diff --git a/Dockerfile b/Dockerfile index 35d3850..ebc874b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,5 +29,10 @@ COPY --from=build /srv/http /srv/http RUN install -dm 2750 -o app -g www-data /srv/gems RUN chmod 755 /usr/local/bin/geminabox +# https://github.com/rubygems/rubygems/issues/2918 +# https://gitlab.alpinelinux.org/alpine/aports/issues/10808 +COPY ./rubygems-platform-musl.patch /tmp/ +RUN patch -d /usr/lib/ruby/2.5.0 -Np 0 -i /tmp/rubygems-platform-musl.patch + EXPOSE 9292 VOLUME /srv/gems diff --git a/rubygems-platform-musl.patch b/rubygems-platform-musl.patch new file mode 100644 index 0000000..4034704 --- /dev/null +++ b/rubygems-platform-musl.patch @@ -0,0 +1,25 @@ +--- rubygems/platform.rb.orig ++++ rubygems/platform.rb +@@ -89,7 +89,7 @@ + when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ] + when /^dotnet$/ then [ 'dotnet', nil ] + when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] +- when /linux/ then [ 'linux', $1 ] ++ when /linux-?(\w+)?/ then [ 'linux', $1 ] + when /mingw32/ then [ 'mingw32', nil ] + when /(mswin\d+)(\_(\d+))?/ then + os, version = $1, $3 +--- rubygems.rb.orig ++++ rubygems.rb +@@ -764,10 +764,7 @@ + def self.platforms + @platforms ||= [] + if @platforms.empty? +- # XXX: Patched to avoid installing platform-specific gems with binaries +- # linked against glibc. +- @platforms = [Gem::Platform::RUBY] +- #@platforms = [Gem::Platform::RUBY, Gem::Platform.local] ++ @platforms = [Gem::Platform::RUBY, Gem::Platform.local] + end + @platforms + end From a5caa08b64f66f46e9feb93087ae53eb51277322 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 14:03:44 -0300 Subject: [PATCH 06/10] use busybox patch --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ebc874b..c50c0f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN chmod 755 /usr/local/bin/geminabox # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 COPY ./rubygems-platform-musl.patch /tmp/ -RUN patch -d /usr/lib/ruby/2.5.0 -Np 0 -i /tmp/rubygems-platform-musl.patch +RUN cd /usr/lib/ruby/2.5.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch EXPOSE 9292 VOLUME /srv/gems From 6387a8303276fc65546c0e61675c212789a1a90f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 18 Sep 2019 14:41:30 -0300 Subject: [PATCH 07/10] storage --- config.ru | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.ru b/config.ru index c6074bd..13273bd 100644 --- a/config.ru +++ b/config.ru @@ -2,7 +2,7 @@ require 'geminabox' require 'rack/session/redis' require 'securerandom' -Geminabox.data = '/srv/http' +Geminabox.data = '/srv/gems' Geminabox.rubygems_proxy = true Geminabox.allow_remote_failure = true From b15cd673eae49a9ac1619e5a4b74a2c10237640d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 20 Dec 2019 18:49:10 -0300 Subject: [PATCH 08/10] upgrade to ruby 2.6.5 --- Dockerfile | 7 ++++--- Gemfile | 6 +++++- geminabox.sh | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c50c0f3..6feb536 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM sutty/sdk-ruby:latest AS build MAINTAINER "f " +ENV RACK_ENV=production + RUN install -dm 2750 -o app -g www-data /srv/http USER app @@ -8,14 +10,13 @@ WORKDIR /srv/http COPY --chown=app:www-data ./Gemfile . COPY --chown=app:www-data ./config.ru . RUN bundle install --path=./vendor -RUN find ./vendor -name '*.so' | xargs -r strip --strip-unneeded FROM sutty/daemonize:latest AS daemonize RUN echo /home/builder/packages/home > /etc/apk/repositories RUN apk add --no-cache daemonize -FROM sutty/monit +FROM sutty/monit:latest ENV RACK_ENV=production RUN addgroup -g 82 -S www-data @@ -32,7 +33,7 @@ RUN chmod 755 /usr/local/bin/geminabox # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 COPY ./rubygems-platform-musl.patch /tmp/ -RUN cd /usr/lib/ruby/2.5.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch +RUN cd /usr/lib/ruby/2.6.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch EXPOSE 9292 VOLUME /srv/gems diff --git a/Gemfile b/Gemfile index 5236acc..17c9e0e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,8 @@ -source 'https://rubygems.org' +if ENV['RACK_ENV'] == 'production' + source 'https://gems.sutty.nl' +else + source 'https://rubygems.org' +end gem 'redis-rack' gem 'hiredis' diff --git a/geminabox.sh b/geminabox.sh index c94c01f..c0d9153 100644 --- a/geminabox.sh +++ b/geminabox.sh @@ -3,6 +3,7 @@ set -e dir=/srv/gems pid=/tmp/geminabox.pid +log=/tmp/geminabox.log chown -R app:www-data ${dir} cd ${dir} @@ -13,6 +14,6 @@ for link in Gemfile Gemfile.lock .bundle config.ru vendor; do done rm -f ${pid} -daemonize -p ${pid} -l ${pid} -o ${dir}/access.log -e ${dir}/error.log \ +daemonize -p ${pid} -l ${pid} -o ${log} -e ${log} \ -c ${dir} -a -u app \ `which bundle` exec rackup From d78f8601af664dc8c98691fde9d5a839ea86bc14 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 12 Sep 2020 12:05:00 -0300 Subject: [PATCH 09/10] ruby 2.7 --- Dockerfile | 9 ++------- rubygems-platform-musl.patch | 11 ----------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6feb536..9377fb3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,11 +11,6 @@ COPY --chown=app:www-data ./Gemfile . COPY --chown=app:www-data ./config.ru . RUN bundle install --path=./vendor -FROM sutty/daemonize:latest AS daemonize - -RUN echo /home/builder/packages/home > /etc/apk/repositories -RUN apk add --no-cache daemonize - FROM sutty/monit:latest ENV RACK_ENV=production @@ -23,7 +18,7 @@ RUN addgroup -g 82 -S www-data RUN adduser -s /bin/sh -G www-data -h /srv/http -D app RUN apk add --no-cache ruby ruby-bundler ruby-json -COPY --from=daemonize /usr/sbin/daemonize /usr/sbin/daemonize +RUN apk add --no-cache daemonize COPY ./monit.conf /etc/monit.d/geminabox.conf COPY ./geminabox.sh /usr/local/bin/geminabox COPY --from=build /srv/http /srv/http @@ -33,7 +28,7 @@ RUN chmod 755 /usr/local/bin/geminabox # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 COPY ./rubygems-platform-musl.patch /tmp/ -RUN cd /usr/lib/ruby/2.6.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch +RUN apk add --no-cache patch && cd /usr/lib/ruby/2.7.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch && apk del patch EXPOSE 9292 VOLUME /srv/gems diff --git a/rubygems-platform-musl.patch b/rubygems-platform-musl.patch index 4034704..d6db223 100644 --- a/rubygems-platform-musl.patch +++ b/rubygems-platform-musl.patch @@ -1,14 +1,3 @@ ---- rubygems/platform.rb.orig -+++ rubygems/platform.rb -@@ -89,7 +89,7 @@ - when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ] - when /^dotnet$/ then [ 'dotnet', nil ] - when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] -- when /linux/ then [ 'linux', $1 ] -+ when /linux-?(\w+)?/ then [ 'linux', $1 ] - when /mingw32/ then [ 'mingw32', nil ] - when /(mswin\d+)(\_(\d+))?/ then - os, version = $1, $3 --- rubygems.rb.orig +++ rubygems.rb @@ -764,10 +764,7 @@ From c225c497933e8c73f89902d5f8a07472df6a0263 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 12 Sep 2020 12:18:45 -0300 Subject: [PATCH 10/10] back to 2.6 until we can update sutty --- Dockerfile | 26 ++++++++++---------------- rubygems-platform-musl.patch | 11 +++++++++++ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9377fb3..5b749c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,4 @@ -FROM sutty/sdk-ruby:latest AS build -MAINTAINER "f " - -ENV RACK_ENV=production - -RUN install -dm 2750 -o app -g www-data /srv/http - -USER app -WORKDIR /srv/http -COPY --chown=app:www-data ./Gemfile . -COPY --chown=app:www-data ./config.ru . -RUN bundle install --path=./vendor - -FROM sutty/monit:latest +FROM sutty/monit:3.11.6 ENV RACK_ENV=production RUN addgroup -g 82 -S www-data @@ -21,14 +8,21 @@ RUN apk add --no-cache ruby ruby-bundler ruby-json RUN apk add --no-cache daemonize COPY ./monit.conf /etc/monit.d/geminabox.conf COPY ./geminabox.sh /usr/local/bin/geminabox -COPY --from=build /srv/http /srv/http + RUN install -dm 2750 -o app -g www-data /srv/gems RUN chmod 755 /usr/local/bin/geminabox # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 COPY ./rubygems-platform-musl.patch /tmp/ -RUN apk add --no-cache patch && cd /usr/lib/ruby/2.7.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch && apk del patch +RUN cd /usr/lib/ruby/2.6.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch +USER app +WORKDIR /srv/http +COPY --chown=app:www-data ./Gemfile . +COPY --chown=app:www-data ./config.ru . +RUN bundle install --path=./vendor + +USER root EXPOSE 9292 VOLUME /srv/gems diff --git a/rubygems-platform-musl.patch b/rubygems-platform-musl.patch index d6db223..4034704 100644 --- a/rubygems-platform-musl.patch +++ b/rubygems-platform-musl.patch @@ -1,3 +1,14 @@ +--- rubygems/platform.rb.orig ++++ rubygems/platform.rb +@@ -89,7 +89,7 @@ + when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ] + when /^dotnet$/ then [ 'dotnet', nil ] + when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] +- when /linux/ then [ 'linux', $1 ] ++ when /linux-?(\w+)?/ then [ 'linux', $1 ] + when /mingw32/ then [ 'mingw32', nil ] + when /(mswin\d+)(\_(\d+))?/ then + os, version = $1, $3 --- rubygems.rb.orig +++ rubygems.rb @@ -764,10 +764,7 @@