diff --git a/.github/workflows/build-unstable-branch.yml b/.github/workflows/build-unstable-branch.yml index e7eb08f..24afdd3 100644 --- a/.github/workflows/build-unstable-branch.yml +++ b/.github/workflows/build-unstable-branch.yml @@ -14,17 +14,20 @@ jobs: fetch-depth: 0 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build image and push to GitHub Container Registry - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v5 with: context: . push: true tags: 'ghcr.io/mlibrary/dromedary/dromedary-unstable:${{ github.sha }}' file: ./Dockerfile + target: production + build-args: + - RAILS_RELATIVE_URL_ROOT=/m/middle-english-dictionary diff --git a/.gitignore b/.gitignore index c3f4c06..dd859a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /.bundle /.cache +/.local /data /db/*.sqlite3 /log @@ -7,4 +8,4 @@ **/tmp !**/.keep .byebug_history -/solr_logs \ No newline at end of file +/solr_logs diff --git a/Dockerfile b/Dockerfile index d701627..0ef5766 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,69 +1,135 @@ -FROM ruby:2.7 AS app +ARG RUBY_VERSION=2.7.8 +ARG RUBY_SLIM="-slim" +FROM ruby:${RUBY_VERSION}${RUBY_SLIM} AS base ARG UNAME=app ARG UID=1000 ARG GID=1000 -#ARG UID 502 -#ARG GID 20 ARG ARCH=amd64 -RUN curl https://deb.nodesource.com/setup_16.x | bash -RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list - -RUN apt-get update -yqq && \ - apt-get install -yqq --no-install-recommends \ - vim nodejs yarn apt-transport-https \ +ARG BUNDLER_VERSION=2.4.22 +ARG NODE_VERSION=20 + +RUN rm -f /etc/apt/apt.conf.d/docker-clean && \ + echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \ + > /etc/apt/apt.conf.d/keep-cache +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt update && apt-get --no-install-recommends install -yq \ + apt-transport-https \ + build-essential \ + curl \ + git \ + unzip \ + libpq-dev \ + ##### FIXME: remove these once useless gems are trimmed \ + libmariadb-dev \ + libsqlite3-dev \ + ##### What is netcat here for??? netcat +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + curl -SLO https://deb.nodesource.com/nsolid_setup_deb.sh && \ + chmod 500 nsolid_setup_deb.sh && \ + ./nsolid_setup_deb.sh ${NODE_VERSION} && \ + apt-get install nodejs -yq + +RUN gem install bundler:${BUNDLER_VERSION} + RUN groupadd -g $GID -o $UNAME RUN useradd -m -d /opt/app -u $UID -g $GID -o -s /bin/bash $UNAME -RUN chown $UID:$GID /opt/app +ENV RAILS_LOG_TO_STDOUT true -RUN mkdir /opt/app/data -RUN chown $UID:$GID /opt/app/data -RUN touch /opt/app/data/.keep +WORKDIR /opt/app +COPY Gemfile* . + +############# +FROM base AS base-dev + +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + apt-get --no-install-recommends install -yq \ + fd-find \ + less \ + ripgrep \ + vim-tiny + +############ +FROM base AS gems-prod + +RUN --mount=type=cache,id=med-bundle-prod,sharing=locked,target=/vendor/bundle \ + --mount=type=cache,sharing=locked,target=/vendor/cache \ + bundle config set path /vendor/bundle && \ + bundle config set cache_path /vendor/cache && \ + bundle config set cache_all true && \ + bundle config set without 'development test' && \ + bundle config build.sassc --disable-march-tune-native && \ + bundle cache --no-install && \ + bundle install --local && \ + bundle clean && \ + bundle config unset cache_path && \ + bundle config set path /gems && \ + mkdir -p /gems && \ + cp -ar /vendor/bundle/* /gems + + +############# +FROM base-dev AS gems-dev + +RUN --mount=type=cache,id=med-bundle-dev,sharing=locked,target=/vendor/bundle \ + --mount=type=cache,sharing=locked,target=/vendor/cache \ + bundle config set path /vendor/bundle && \ + bundle config set cache_path /vendor/cache && \ + bundle config set cache_all true && \ + bundle cache --no-install && \ + bundle config build.sassc --disable-march-tune-native && \ + bundle install --local && \ + bundle clean && \ + bundle config unset cache_path && \ + bundle config set path /gems && \ + mkdir -p /gems && \ + cp -ar /vendor/bundle/* /gems + + +############# +FROM gems-prod AS production + +ARG RAILS_RELATIVE_URL_ROOT + +COPY . . +RUN chown -R ${UID}:${GID} /gems && chown -R ${UID}:${GID} /opt/app + + +EXPOSE 3000 +USER $UNAME + +### temporarily required to start up/precompile +ENV SOLR_ROOT=bogus +ENV SOLR_COLLECTION=bogus +### -RUN mkdir /gems -RUN chown $UID:$GID /gems -RUN touch /gems/.keep +ENV RAILS_ENV production +ENV RAILS_SERVE_STATIC_FILES true +ENV SECRET_KEY_BASE 121222bccca +ENV RAILS_RELATIVE_URL_ROOT=${RAILS_RELATIVE_URL_ROOT} -COPY --chown=$UID:$GID . /opt/app +RUN bin/rails assets:precompile -ENV BUNDLE_VERSION 2.4.22 -ENV BUNDLE_PATH /gems -RUN gem install bundler:2.4.22 +CMD ["bin/rails", "s", "-b", "0.0.0.0"] -USER ${UID}:${GID} -WORKDIR /opt/app -ENV RAILS_RELATIVE_URL_ROOT /m/middle-english-dictionary -ENV RAILS_LOG_TO_STDOUT true -ENV RAILS_ENV production +############ +FROM gems-dev AS development -# This can be anything but must be set. -ENV SECRET_KEY_BASE 121222bccca +COPY . . +RUN chown -R ${UID}:${GID} /gems && chown -R ${UID}:${GID} /opt/app RUN bundle config build.sassc --disable-march-tune-native RUN bundle config set path /gems -RUN #bundle config set without 'test development' -RUN bundle install -j 4 +EXPOSE 3000 +USER $UNAME -# Asset precompilation -# Because of...I don't know why...it wants the SOLR stuff defined -ENV SOLR_ROOT http://solr:8983/ -ENV SOLR_COLLECTION med-preview -ENV RAILS_ROOT /m/middle-english-dictionary -RUN RAILS_ENV=production bin/rails assets:precompile - -#CMD ["sleep", "infinity"] -ENV RAILS_ENV production CMD ["bin/rails", "s", "-b", "0.0.0.0"] - -#FROM nginx:mainline AS assets -#ENV NGINX_PORT=80 -#ENV NGINX_PREFIX=/ -#COPY --from=app /opt/app/nginx/assets.nginx /etc/nginx/templates/default.conf.template -#COPY --from=app /opt/app/public /usr/share/nginx/html/ \ No newline at end of file diff --git a/Gemfile b/Gemfile index 213fa33..6de5f59 100644 --- a/Gemfile +++ b/Gemfile @@ -5,8 +5,9 @@ git_source(:github) do |repo_name| "https://github.com/#{repo_name}.git" end +# GitHub Packages requires tokens, even for public repositories; so we use git for now # source "https://rubygems.pkg.github.com/mlibrary" do -# gem "middle_english_dictionary", "1.9.0" +# gem "middle_english_dictionary", "1.9.1" # end gem "middle_english_dictionary", git: "https://github.com/mlibrary/middle_english_dictionary", tag: "v1.9.1" diff --git a/compose.yml b/compose.yml index af4cc08..4f7caf5 100644 --- a/compose.yml +++ b/compose.yml @@ -8,8 +8,11 @@ services: build: dockerfile: Dockerfile context: . + args: + UID: ${UID:-1000} + GID: ${GID:-1000} ports: - - "3000:3000" # Rails + - "127.0.0.1:3000:3000" # Rails - "1111:1111" - "1234:1234" # RubyMine - "26162:26162" # RubyMine @@ -21,16 +24,9 @@ services: - SOLR_PASSWORD=SolrRocks - DATA_ROOT=/mec/data - BUILD_ROOT=/mec/data/build - - RAILS_ROOT=/m/middle-english-dictionary volumes: - .:/opt/app - data:/mec/data - - gems:/opt/app/gems - command: - - bin/rails - - s - - -b - - 0.0.0.0 db: image: postgres:12-alpine @@ -92,7 +88,6 @@ volumes: type: none device: ${PWD}/data o: bind - gems: db: solr: driver_opts: diff --git a/config.ru b/config.ru index 2b6bdfc..c3e74c9 100644 --- a/config.ru +++ b/config.ru @@ -2,8 +2,6 @@ require_relative "config/environment" -run Rails.application -# this is in the routes now -# map Dromedary.config.relative_url_root || "/" do -# run Rails.application -# end +map Dromedary.config.relative_url_root || "/" do + run Rails.application +end diff --git a/config/application.rb b/config/application.rb index d17596e..357b5ee 100644 --- a/config/application.rb +++ b/config/application.rb @@ -30,6 +30,7 @@ class Application < Rails::Application config.relative_url_root = Dromedary::Services[:relative_url_root] config.action_controller.relative_url_root = config.relative_url_root + # config.assets.prefix = Dromedary::Services[:relative_url_root] # config.relative_url_root = '/' # config.action_controller.relative_url_root = '/' diff --git a/config/environments/production.rb b/config/environments/production.rb index 5611833..3b058da 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -33,8 +33,7 @@ # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.asset_host = ENV["CDN_HOST"] # Rails 7+ use the short version of this option - config.action_controller.asset_host = ENV["CDN_HOST"] + config.asset_host = ENV["CDN_HOST"] # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache diff --git a/config/load_local_config.rb b/config/load_local_config.rb index 7a1e6c5..e0a8de0 100644 --- a/config/load_local_config.rb +++ b/config/load_local_config.rb @@ -49,7 +49,8 @@ def underlying_real_collection_name(coll: Dromedary::Services[:solr_current_col end def collection_creation_date(coll: Dromedary::Services[:solr_current_collection]) - return @collection_creation_date if defined? @collection_creation_date + return @collection_creation_date if defined?(@collection_creation_date) && !@collection_creation_date.nil? + real_collection_name = underlying_real_collection_name(coll: coll) m = /(\d{4})(\d{2})(\d{2})\d{4}\Z/.match(real_collection_name) @collection_creation_date = Time.parse(m[1..3].join("-")) diff --git a/config/routes.rb b/config/routes.rb index de67e1b..ac8b358 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,8 +5,9 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - scope Dromedary::Services[:relative_url_root] do - mount Blacklight::Engine => Dromedary.config.relative_url_root + # This scope should go away. The production prefix is managed at the Rack level. + scope "/" do + mount Blacklight::Engine => "/" # config/routes.rb, at any priority that suits you mount OkComputer::Engine, at: "/status"