diff --git a/Dockerfile b/Dockerfile index a641847ac3..8a8a862135 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,80 @@ -FROM ruby:2.7.8-bullseye as builder -LABEL maintainer="nabeta@fastmail.fm" +# syntax = docker/dockerfile:1 -ARG http_proxy -ARG https_proxy +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=2.7.8 +FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base -COPY Gemfile / -COPY Gemfile.lock / -RUN apt-get update -qq && apt-get install -y libpq-dev && bundle install +# Rails app lives here +WORKDIR /enju -FROM ruby:2.7.8-bullseye -LABEL maintainer="nabeta@fastmail.fm" +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" -ARG http_proxy -ARG https_proxy + +# Throw-away build stage to reduce size of final image +FROM base as build + +# Install packages needed to build gems +RUN apt-get update -qq && apt-get install --no-install-recommends -y curl gnupg && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor -o /etc/apt/keyrings/yarnkey.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + echo "deb [signed-by=/etc/apt/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list && \ + apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config nodejs yarn shared-mime-info + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile && \ + yarn install + +# Copy application code +COPY . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ + +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +# RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + +# Final stage for app image +FROM base ARG UID=1000 ARG GID=1000 +ARG http_proxy +ARG https_proxy -RUN groupadd --gid ${GID} enju && useradd -m --uid ${UID} --gid ${GID} enju -RUN apt-get update -qq && curl -sL https://deb.nodesource.com/setup_16.x | bash - && \ - apt-get install -y nodejs postgresql-client imagemagick poppler-utils ffmpeg && npm install -g yarn -RUN mkdir /enju && chown -R enju:enju /enju -USER enju -WORKDIR /enju -ADD package.json yarn.lock ./ -RUN yarn install --frozen-lockfile -COPY --from=builder /usr/local/bundle /usr/local/bundle -COPY . /enju/ +# Install packages needed for deployment +RUN apt-get update -qq && apt-get install --no-install-recommends -y curl gnupg && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor -o /etc/apt/keyrings/yarnkey.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + echo "deb [signed-by=/etc/apt/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list && \ + apt-get update -qq && \ + apt-get install --no-install-recommends -y libvips postgresql-client nodejs yarn file imagemagick poppler-utils ffmpeg && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Copy built artifacts: gems, application +COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build /enju /enju + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --gid ${GID} enju && \ + useradd enju --uid ${UID} --gid ${GID} --create-home --shell /bin/bash && \ + chown -R enju:enju db log storage tmp +USER enju:enju + +# Entrypoint prepares the database. +ENTRYPOINT ["/enju/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server"] diff --git a/Gemfile.lock b/Gemfile.lock index 12cd2e9c70..9b3b589897 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GEM caxlsx (>= 3.0) climate_control (0.2.0) cocoon (1.2.15) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) crack (1.0.0) bigdecimal rexml @@ -237,7 +237,7 @@ GEM mini_magick (4.13.2) mini_mime (1.1.5) mini_portile2 (2.8.7) - minitest (5.24.1) + minitest (5.25.0) mono_logger (1.1.2) msgpack (1.7.2) multi_json (1.15.0) @@ -272,7 +272,7 @@ GEM terrapin (~> 0.6.0) paperclip-meta (3.1.0) paperclip (>= 5.0) - parallel (1.26.1) + parallel (1.26.3) parallel_tests (4.7.1) parallel pg (1.4.6) @@ -367,7 +367,7 @@ GEM typesafe_enum (~> 0.1, >= 0.1.5) xml-mapping (~> 0.10) xml-mapping_extensions (~> 0.4, >= 0.4.8) - rexml (3.3.4) + rexml (3.3.5) strscan rsolr (2.6.0) builder (>= 2.1.2) @@ -380,7 +380,7 @@ GEM rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.1.3) + rspec-rails (6.1.4) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000000..67ef493142 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If running the rails server then create or migrate existing database +if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index 33da6460b5..ceb618ad90 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -4,7 +4,7 @@ class MediaTypeSpoofDetector def type_from_file_command begin Paperclip.run("LANG=C file", "-b --mime-type :file", :file => @file.path) - rescue Cocaine::CommandLineError + rescue Terrapin::CommandLineError "" end end diff --git a/docker-compose.yml b/docker-compose.yml index 59f3cfeeab..4c461eb941 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ x-app: &app services: web: <<: *app - command: bash -c "rm -f tmp/pids/server.pid && rails s -b 0.0.0.0" + command: bash -c "rm -f tmp/pids/server.pid && bin/rails s -b 0.0.0.0" environment: - WEBPACKER_DEV_SERVER_HOST=webpacker expose: