| 1 | # syntax=docker/dockerfile:1 |
| 2 | # check=error=true |
| 3 | |
| 4 | # This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: |
| 5 | # docker build -t sigitsi . |
| 6 | # docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name sigitsi sigitsi |
| 7 | |
| 8 | # For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html |
| 9 | |
| 10 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version |
| 11 | ARG RUBY_VERSION=3.4.2 |
| 12 | FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base |
| 13 | |
| 14 | # Rails app lives here |
| 15 | WORKDIR /rails |
| 16 | |
| 17 | # Install base packages. librsvg2-2 + a base font give libvips SVG-with-text |
| 18 | # rasterization for the Open Graph share cards (OgImageService). |
| 19 | RUN apt-get update -qq && \ |
| 20 | apt-get install --no-install-recommends -y curl libjemalloc2 libvips librsvg2-2 fonts-dejavu-core postgresql-client && \ |
| 21 | ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \ |
| 22 | rm -rf /var/lib/apt/lists /var/cache/apt/archives |
| 23 | |
| 24 | # Set production environment variables and enable jemalloc for reduced memory usage and latency. |
| 25 | ENV RAILS_ENV="production" \ |
| 26 | BUNDLE_DEPLOYMENT="1" \ |
| 27 | BUNDLE_PATH="/usr/local/bundle" \ |
| 28 | BUNDLE_WITHOUT="development" \ |
| 29 | LD_PRELOAD="/usr/local/lib/libjemalloc.so" |
| 30 | |
| 31 | # Throw-away build stage to reduce size of final image |
| 32 | FROM base AS build |
| 33 | |
| 34 | # Install packages needed to build gems |
| 35 | RUN apt-get update -qq && \ |
| 36 | apt-get install --no-install-recommends -y build-essential git libpq-dev libvips libyaml-dev pkg-config && \ |
| 37 | rm -rf /var/lib/apt/lists /var/cache/apt/archives |
| 38 | |
| 39 | # Install application gems |
| 40 | COPY vendor/* ./vendor/ |
| 41 | COPY Gemfile Gemfile.lock ./ |
| 42 | |
| 43 | RUN bundle install && \ |
| 44 | rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ |
| 45 | # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495 |
| 46 | bundle exec bootsnap precompile -j 1 --gemfile |
| 47 | |
| 48 | # Copy application code |
| 49 | COPY . . |
| 50 | |
| 51 | # Precompile bootsnap code for faster boot times. |
| 52 | # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495 |
| 53 | RUN bundle exec bootsnap precompile -j 1 app/ lib/ |
| 54 | |
| 55 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY |
| 56 | RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 | # Final stage for app image |
| 62 | FROM base |
| 63 | |
| 64 | # Run and own only the runtime files as a non-root user for security |
| 65 | RUN groupadd --system --gid 1000 rails && \ |
| 66 | useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash |
| 67 | USER 1000:1000 |
| 68 | |
| 69 | # Copy built artifacts: gems, application |
| 70 | COPY --chown=rails:rails --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" |
| 71 | COPY --chown=rails:rails --from=build /rails /rails |
| 72 | |
| 73 | # Entrypoint prepares the database. |
| 74 | ENTRYPOINT ["/rails/bin/docker-entrypoint"] |
| 75 | |
| 76 | # Start server via Thruster by default, this can be overwritten at runtime |
| 77 | EXPOSE 80 |
| 78 | CMD ["./bin/thrust", "./bin/rails", "server"] |