Skip to content

Commit

Permalink
Big combo! Rail 7.2 Dockerfile used for Dockerfile.prod, plus bump R… (
Browse files Browse the repository at this point in the history
…#1058)

Embracing Dockerfile for prod deploy that ships with Rails 7.2, saving 1 GB of image space.  Updates to Rails 7.2, and by removing JavaScript minification, our first step on #nobuild journey, we reduce what we need in our production image..
  • Loading branch information
epugh authored Oct 4, 2024
1 parent 2ead96d commit 4e00ebe
Show file tree
Hide file tree
Showing 37 changed files with 538 additions and 246 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: cimg/ruby:3.3.2-browsers
- image: cimg/ruby:3.3.5-browsers
environment: # environment variables for primary container
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
Expand Down
61 changes: 55 additions & 6 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,66 @@
# Rails logs
log/
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.

# Ignore git directory.
/.git/
/.gitignore

# Ignore bundler config.
/.bundle

# Ignore all environment files (except templates).
/.env*
!/.env*.erb

# Ignore all default key files.
/config/master.key
/config/credentials/*.key

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/.keep

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/.keep

# Ignore assets.
/node_modules/
/app/assets/builds/*
!/app/assets/builds/.keep
/public/assets

# Ignore CI service files.
/.github

# Ignore development files
/.devcontainer

# Ignore Docker-related files
/.dockerignore
/Dockerfile*



# Quepid docs
docs/
tmp/

# Rails generated artifacts
coverage/

# Files used by Docker to build images
docker-compose*.yml
Dockerfile*
.env

# GitHub and CircleCI configuration
.github/**/*
.github
# CircleCI configuration
.circleci/**/*
.circleci

Expand Down
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Temporary files generated by your text editor or operating system
# belong in git's global ignore instead:
# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore`

venv
/tmp/storage/*
!/tmp/storage/
Expand Down
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.2
3.3.5
2 changes: 1 addition & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:3.3.2-bullseye
FROM ruby:3.3.5-bullseye

LABEL maintainer="[email protected]"

Expand Down
139 changes: 72 additions & 67 deletions Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -1,81 +1,86 @@
FROM node:20-bullseye AS build-dep
WORKDIR /srv/app
COPY package.json yarn.lock ./
RUN yarn install --production=true
# syntax = docker/dockerfile:1

FROM ruby:3.3.2-bullseye
# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t my-app .
# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY=<value from config/master.key> my-app

LABEL maintainer="[email protected]"
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.3.5
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

ARG QUEPID_VERSION_VARIABLE
ENV QUEPID_VERSION=$QUEPID_VERSION_VARIABLE
# Rails app lives here
WORKDIR /rails

# Must have packages
RUN apt-get update -qq && apt-get install -y --no-install-recommends vim curl netcat \
&& rm -rf /var/lib/apt/lists/*
# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl default-mysql-client libjemalloc2 libvips && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Node Only
RUN apt-get update -qq \
&& apt-get install -y --no-install-recommends ca-certificates 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 \
&& NODE_MAJOR=20 \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update -qq \
&& apt-get install --no-install-recommends -y nodejs \
&& apt remove yarn \
&& rm -rf /var/lib/apt/lists/*
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"

# Install dependencies
WORKDIR /srv/app
COPY Gemfile Gemfile.lock ./
# 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 build-essential default-libmysqlclient-dev git node-gyp pkg-config python-is-python3 && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install JavaScript dependencies
ARG NODE_VERSION=18.17.0
ARG YARN_VERSION=
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master

# Install application gems
RUN gem install foreman
RUN gem install bundler:2.5.11

# Clean up Bundle
RUN bundle config set without 'development test'
RUN bundle config set deployment true
RUN bundle install --jobs 4 && \
bundle clean --force && \
rm -rf /app/.bundle/cache && \
rm -rf /app/vendor/bundle/ruby/*/cache

COPY --from=build-dep /srv/app/node_modules ./node_modules/
#COPY . .
COPY ./app ./app
COPY ./app.json ./app.json
COPY ./babel.config.js ./babel.config.js
COPY ./bin ./bin
COPY ./config ./config
COPY ./config.ru ./config.ru
COPY ./db ./db
COPY ./Gemfile ./Gemfile
COPY ./Gemfile.lock ./Gemfile.lock
COPY ./lib ./lib
COPY ./LICENSE ./LICENSE
COPY ./package.json ./package.json
COPY ./postcss.config.js ./postcss.config.js
COPY ./Procfile ./Procfile

# Exclude the /public/notebook directory
COPY ./public/images ./public/images
COPY ./public/javascripts ./public/javascripts
COPY ./public/*.html ./public
COPY ./public/robots.txt ./public

COPY ./Rakefile ./Rakefile
COPY ./README.md ./README.md
COPY ./vendor ./vendor
COPY ./yarn.lock ./yarn.lock
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

# Install node modules
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

ADD https://github.com/o19s/quepid-jupyterlite/releases/latest/download/jupyter-lite-build.tgz ./notebooks.gz

RUN mkdir -p tmp/pids
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile


RUN rm -rf node_modules


# Final stage for app image
FROM base

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Also unpacks the ./notebooks.gz file
RUN RAILS_ENV=production SECRET_KEY_BASE=fake_out_devise bundle exec rake assets:precompile
# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER 1000:1000

# Remove some files not needed in resulting image
RUN rm package.json yarn.lock
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["foreman", "s", "-f", "Procfile"]
18 changes: 10 additions & 8 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

source 'https://rubygems.org'

ruby '3.3.2'
ruby '3.3.5'

gem 'activerecord-import', '>= 1.0.7'
gem 'active_storage_db'
Expand All @@ -23,6 +23,7 @@ gem 'devise_invitable', '~> 2.0'
# Using this as it wires in via Sprockets and I can't get npm version to work with the main app.
# Had no luck with js/svg approach ;-(
gem 'font-awesome-sass'
gem 'foreman'
gem 'gabba'
gem 'importmap-rails', '~> 2.0'
gem 'intercom-rails'
Expand All @@ -40,7 +41,7 @@ gem 'postmark-rails'
gem 'prophet-rb', '~> 0.5.0'
gem 'puma'
gem 'pundit'
gem 'rails', '~> 7.1.2'
gem 'rails', '~> 7.2.1'
gem 'rails-healthcheck', '~> 1.4'
gem 'rails-html-sanitizer'
gem 'rack-cors', '~> 2.0'
Expand All @@ -51,12 +52,13 @@ gem 'rubyzip', '~> 2.3.0' # 3.0 will be breaking
gem 'sassc-rails', '~> 2.1'
gem 'sidekiq'
gem 'sidekiq-limit_fetch', '~> 4.4'
gem 'terser'
gem 'thor'
gem 'turbo-rails', '~> 2.0', '>= 2.0.5'
gem 'vega', '~> 0.3.0'

group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem 'debug', platforms: [ :mri, :windows ], require: 'debug/prelude'
gem 'annotate'
gem 'bullet'
gem 'memory_profiler'
Expand All @@ -66,12 +68,12 @@ group :development do
# Use console on exceptions pages [https://github.com/rails/web-console]
gem 'web-console'

# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
# Add me back in when Ruby 3.2.X comes out https://github.com/ruby/debug/issues/898
# gem 'debug', platforms: [ :mri, :mingw, :x64_mingw ]

# this was commented out in the default build, so doing the same..
# Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]
gem 'rack-mini-profiler'
# gem 'rack-mini-profiler'

# # Highlight the fine-grained location where an error occurred [https://github.com/ruby/error_highlight]
gem 'error_highlight', '>= 0.4.0', platforms: [ :ruby ]

gem 'derailed_benchmarks'
gem 'letter_opener'
Expand Down
Loading

0 comments on commit 4e00ebe

Please sign in to comment.