# 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<% unless options.precompile == "defer" %> as base<% end %> <% else -%> FROM <%= platform %>ruby:$RUBY_VERSION-slim<% unless options.precompile == "defer" %> as base<% end %> <% end -%> <% unless options.label.empty? -%> <% options.label.each do |key, value| -%> LABEL <%= key =~ /^\w[.\w]*$/ ? key : key.inspect %>=<%= value.inspect %> <% end -%> <% end -%> # Rails app lives here WORKDIR /rails <% unless base_args.empty? -%> # Base build arguments ARG <%= base_args.map {|key, value| "#{key}=#{value.inspect}"}.join(" \\\n ") %> <% end -%> # Set production environment ENV <%= base_env.join(" \\\n ") %> # Update gems and bundler RUN gem update --system --no-document && \ gem install -N <%= base_gems.join(" ") %> <% unless base_requirements.empty? -%> # Install packages needed to install <%= base_requirements %> <%= render partial: 'apt_install', locals: {packages: base_packages, clean: true, repos: ''} %> <% end -%> <% if using_execjs? -%> <%= render partial: 'install_node', locals: {yarn_version: nil} %> <% end -%> <% unless options.precompile == "defer" -%> # Throw-away build stage<%= parallel? ? 's' : '' %> to reduce size of final image FROM base as <%= parallel? ? 'pre' : '' %>build <% end -%> # 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 -%> <% unless build_args.empty? -%> # Build arguments ARG <%= build_args.map {|key, value| "#{key}=#{value.inspect}"}.join(" \\\n ") %> <% end -%> <% unless build_env.empty? -%> # Build options ENV <%= build_env.join(" \\\n ") %> <% end -%> # Install application gems COPY<% if options.link? %> --link<% end %> 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 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 install<% if depend_on_bootsnap? -%> && \ bundle exec bootsnap precompile --gemfile<% end %> && \ rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git <% 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 options.link? %> --link<% end %> . . <% 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 -%> <% unless options.precompile == "defer" -%> <% 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 <% end -%> <% unless deploy_args.empty? -%> # Deployment build arguments ARG <%= deploy_args.map {|key, value| "#{key}=#{value.inspect}"}.join(" \\\n ") %> <% end -%> <% unless deploy_packages.empty? -%> # Install packages needed for deployment <%= render partial: 'apt_install', locals: {packages: deploy_packages, clean: true, repos: deploy_repos} %> <% end -%> <% if options.nginx? -%> <%= render partial: 'nginx' %> <% elsif procfile.size > 1 -%> RUN gem install foreman <% end -%> <% unless run_as_root? -%> # Run and own the application files as a non-root user for security <% if options.compose? -%> ARG UID=1000 \ GID=1000 RUN groupadd -f -g $GID rails && \ useradd -u $UID -g $GID rails<% else -%> RUN useradd rails<% end -%> --home /rails --shell /bin/bash<% if options.nginx? %> && \ chown rails:rails /var/lib/nginx /var/log/nginx/*<% end %> <% unless options.swap -%> USER rails:rails <% end -%> <% end -%> <% unless options.precompile == "defer" -%> # Copy built artifacts: gems, application COPY --from=build /usr/local/bundle /usr/local/bundle COPY --from=build <% unless run_as_root? %>--chown=rails:rails <% end %>/rails /rails <% if api_client_dir -%> # Copy built client COPY --from=client <% unless run_as_root? %>--chown=rails:rails <% end %>/rails/<%= api_client_dir %>/build /rails/public <% end -%> <% 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"] <% if procfile.size > 1 -%> # Build a Procfile for production use COPY <<-"EOF" /rails/Procfile.prod <% procfile.each do |name, command| -%> <%= name %>: <%= command %> <% end -%> EOF # Start the server by default, this can be overwritten at runtime EXPOSE 3000 CMD ["foreman", "start", "--procfile=Procfile.prod"] <% else -%> # Start the server by default, this can be overwritten at runtime EXPOSE 3000 CMD ["./bin/rails", "server"] <% end -%>