Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save joshRpowell/6f5eb13e630a3a427e4ed020953b52bd to your computer and use it in GitHub Desktop.
Save joshRpowell/6f5eb13e630a3a427e4ed020953b52bd to your computer and use it in GitHub Desktop.
Speedup Docker Image building using multi stage build

Dockerfile

# Build rarely changed system libraries
FROM phusion/passenger-ruby27:1.0.16 AS builder

ENV RAILS_ENV=${RAILS_ENV:-production}
ENV NODE_ENV=${RAILS_ENV:-production}
ENV RACK_ENV=${RAILS_ENV:-production}
ENV PASSENGER_APP_ENV=${RAILS_ENV:-production}

# Enable Nginx
RUN rm -f /etc/service/nginx/down

RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get install -y nodejs libpq-dev
RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg > /dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get -y update && apt-get install -y yarn
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

USER app

RUN mkdir /home/app/web
WORKDIR /home/app/web
RUN gem install bundler -v 2.2.17 --no-document
RUN bundle config set --local without 'development test'

# Build rarely changes gems
FROM builder AS builder-with-gems

COPY --chown=app:app Gemfile.core /home/app/web/Gemfile.core
COPY --chown=app:app Gemfile.core.lock /home/app/web/Gemfile.core.lock

RUN BUNDLE_GEMFILE=Gemfile.core bundle install -j $(grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}')

# Build the actual image
FROM builder

# Configure nginx
COPY infra/production/storieslinker.com.nginx.conf /etc/nginx/sites-enabled/storieslinker.com.ngixn.conf

# Copy the full Gemfile
COPY --chown=app:app Gemfile /home/app/web/Gemfile
COPY --chown=app:app Gemfile.lock /home/app/web/Gemfile.lock

# Use the cached core gems
COPY --from=builder-with-gems /usr/local/rvm/gems /usr/local/rvm/gems

# Bundle install the extra gems
RUN bundle install -j $(grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}')

# Copy the application codes
COPY --chown=app:app . /home/app/web

# Precompiling CSS, JS
RUN bundle exec rake assets:precompile

USER root

Gemfile.core includes all Gem that takes forever to build its native extension

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.3'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
# Use sqlite3 as the database for Active Record
# gem 'sqlite3', '~> 1.4'
gem 'pg'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-byebug'
  gem 'capistrano', '~> 3.16', require: false
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Your full Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.3'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
# Use sqlite3 as the database for Active Record
# gem 'sqlite3', '~> 1.4'
gem 'pg'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-byebug'
  gem 'capistrano', '~> 3.16', require: false
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'inline_svg'

gem 'settingslogic'

gem 'figaro'

gem 'zgcp_toolkit'

gem 'stackdriver'

gem 'view_component', require: 'view_component/engine'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment