# syntax = docker/dockerfile:1 # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile ARG RUBY_VERSION=<%= RUBY_VERSION %> <% if api_client_dir -%> <%= render partial: 'node_client' %> <% end -%> <% if options.fullstaq -%> FROM <%= platform %>quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-<%= @options.jemalloc ? 'jemalloc-' : '' %>slim as base <% else -%> FROM <%= platform %>ruby:$RUBY_VERSION-slim as base <% end -%> # Rails app lives here WORKDIR /rails # Set production environment ENV RAILS_ENV="production" \ BUNDLE_PATH="vendor/bundle" \ BUNDLE_WITHOUT="<%= options.ci? ? 'development' : 'development:test' %>" # Update gems and preinstall the desired version of bundler ARG BUNDLER_VERSION=<%= Bundler::VERSION %> RUN gem update --system --no-document && \ gem install -N bundler -v ${BUNDLER_VERSION} <% if using_execjs? -%> <% if using_puppeteer? -%> # Install packages needed to install nodejs and chrome <%= render partial: 'apt_install', locals: {packages: %w(curl gnupg unzip), clean: true, repos: ''} %> <% else -%> # Install packages needed to install nodejs <%= render partial: 'apt_install', locals: {packages: %w(curl unzip), clean: true, repos: ''} %> <% end -%> <%= render partial: 'install_node', locals: {yarn_version: nil} %> <% end -%> # Throw-away build stage<%= parallel? ? 's' : '' %> to reduce size of final image FROM base as <%= parallel? ? 'pre' : '' %>build # Install packages needed to build gems<%= using_node? ? " and node modules" : "" %> <%= render partial: 'apt_install', locals: {packages: build_packages, clean: false, repos: ''} %> <% if parallel? -%> FROM prebuild as node <% end -%> <% if using_node? and (!using_execjs? || File.exist?('yarn.lock')) -%> <%= render partial: 'install_node', locals: {node_version: using_execjs? ? nil : node_version, yarn_version: File.exist?('yarn.lock') ? yarn_version : nil} %> <% end -%> <% if parallel? -%> <%= render partial: 'npm_install', locals: {sources: %w(package.json yarn.lock)} %> FROM prebuild as build <% end -%> # Install application gems COPY Gemfile Gemfile.lock ./ <% if options.cache? -%> RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \ bundle config set app_config .bundle && \ bundle config set path /srv/vendor && \ bundle _${BUNDLER_VERSION}_ install && \ <% if depend_on_bootsnap? -%> bundle exec bootsnap precompile --gemfile && \ <% end -%> bundle clean && \ mkdir -p vendor && \ bundle config set path vendor && \ cp -ar /srv/vendor . <% else -%> RUN bundle _${BUNDLER_VERSION}_ install<% if depend_on_bootsnap? -%> && \ bundle exec bootsnap precompile --gemfile<% end %> <% end -%> <% if parallel? -%> # Copy node modules COPY --from=node /rails/node_modules /rails/node_modules <% elsif using_node? -%> <%= render partial: 'npm_install', locals: {sources: Dir[*%w(package.json package-lock.json yarn.lock)]} %> <% end -%> # Copy application code COPY . . <% if depend_on_bootsnap? -%> # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile app/ lib/ <% end -%> <% unless binfile_fixups.empty? -%> <% if options['bin-cd'] and binfile_fixups.length == 1 -%> # Adjust binfiles to set current working directory <% else -%> # Adjust binfiles to be executable on Linux<%= options['bin-cd'] ? ' and set current working directory' : '' %> <% end -%> <%= "RUN " + binfile_fixups.join(" && \\\n ") %> <% end -%> <% if Dir.exist?('app/assets') and !api_only? -%> # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN SECRET_KEY_BASE<%= Rails::VERSION::MAJOR<7 || Rails::VERSION::STRING.start_with?('7.0') ? '=DUMMY' : '_DUMMY=1' %> ./bin/rails assets:precompile <% end -%> # Final stage for app image FROM base <% unless deploy_packages.empty? -%> # Install packages needed for deployment <%= render partial: 'apt_install', locals: {packages: deploy_packages, clean: true, repos: deploy_repos} %> <% end -%> # Copy built application from previous stage <% if options.ci? -%> COPY --from=build /usr/local/bundle /usr/local/bundle <% end -%> COPY --from=build /rails /rails <% if api_client_dir -%> # Copy built client COPY --from=client /rails/<%= api_client_dir %>/build /rails/public <% end -%> <% unless deploy_env.empty? -%> # Deployment options ENV <%= deploy_env.join(" \\\n ") %> <% end -%> <% if options.prepare -%> # Entrypoint prepares the database. <% else -%> # Entrypoint sets up the container. <% end -%> ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start the server by default, this can be overwritten at runtime EXPOSE 3000 CMD ["./bin/rails", "server"]