Last active
November 14, 2025 14:19
-
-
Save Melrt/a3dc3d55db2c225b643032f1fefea031 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # syntax=docker/dockerfile:1.7-labs | |
| ARG RUBY_VERSION | |
| ARG DISTRO_NAME=bullseye | |
| FROM ruby:$RUBY_VERSION-slim-$DISTRO_NAME AS base | |
| SHELL ["/bin/bash", "-c"] | |
| RUN echo "IRB.conf[:HISTORY_FILE] = ENV['IRB_HISTFILE']" >> ~/.irbrc | |
| ARG DISTRO_NAME | |
| # Common dependencies | |
| # Using --mount to speed up build with caching, see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/reference.md#run---mount | |
| ARG PACKAGES_TO_INSTALL="" | |
| RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ | |
| --mount=type=cache,target=/var/lib/apt,sharing=locked \ | |
| --mount=type=tmpfs,target=/var/log \ | |
| rm -f /etc/apt/apt.conf.d/docker-clean; \ | |
| apt-get update -qq && \ | |
| DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \ | |
| curl \ | |
| file \ | |
| libjemalloc2 \ | |
| libpq5 \ | |
| shared-mime-info \ | |
| $(echo $PACKAGES_TO_INSTALL | xargs -n1 | sort -u | xargs) \ | |
| && rm -rf /var/lib/apt/lists/* | |
| ARG RAILS_ENV | |
| # Ruby/Rails env configuration | |
| ENV RAILS_ENV=$RAILS_ENV \ | |
| NODE_ENV=production \ | |
| BUNDLE_PATH=/usr/local/bundle \ | |
| PATH="/home/my_user/app/bin:${PATH}" \ | |
| LANG=C.UTF-8 \ | |
| LC_ALL=C.UTF-8 \ | |
| LD_PRELOAD=libjemalloc.so.2 \ | |
| MALLOC_CONF=narenas:2 \ | |
| # Upgrade RubyGems if possible | |
| RUN gem update --system --no-document; | |
| FROM base AS production-builder | |
| # Rails app lives here | |
| WORKDIR /rails | |
| # buildr dependencies | |
| # Using --mount to speed up build with caching, see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/reference.md#run---mount | |
| ARG PACKAGES_TO_INSTALL="" | |
| RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ | |
| --mount=type=cache,target=/var/lib/apt,sharing=locked \ | |
| --mount=type=tmpfs,target=/var/log \ | |
| rm -f /etc/apt/apt.conf.d/docker-clean; \ | |
| apt-get update -qq && \ | |
| DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \ | |
| build-essential \ | |
| libpq-dev \ | |
| libyaml-dev \ | |
| libssl-dev \ | |
| libz-dev \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Install NodeJS and NPM from Nodesource | |
| ARG NODE_MAJOR=21 | |
| RUN echo "Package: nodejs" >> /etc/apt/preferences.d/preferences \ | |
| && echo "Pin: origin deb.nodesource.com" >> /etc/apt/preferences.d/preferences \ | |
| && echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/preferences \ | |
| && curl -sSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \ | |
| && apt-get install -y --no-install-recommends nodejs \ | |
| && rm -rf /var/lib/apt/lists/* \ | |
| && npm install -g yarn | |
| # Then, we re-configure Bundler | |
| ENV RAILS_ENV=$RAILS_ENV \ | |
| BUNDLE_JOBS=4 \ | |
| BUNDLE_RETRY=3 | |
| # Copy code | |
| COPY Gemfile Gemfile.lock ./ | |
| RUN mkdir -p $BUNDLE_PATH \ | |
| && bundle config --local path "${BUNDLE_PATH}" \ | |
| && bundle config set clean "true" \ | |
| && bundle config set no-cache "true" \ | |
| && bundle config --local without "development:test" \ | |
| && bundle install --jobs=${BUNDLE_JOBS} \ | |
| && rm -rf $BUNDLE_PATH/.bundle $BUNDLE_PATH/ruby/*/cache/* $BUNDLE_PATH/ruby/*/bundler/gems/*/.git | |
| # Copy application code | |
| COPY . . | |
| # Copy database config to avoid human errors | |
| COPY .dockerdev/database.yml.template config/database.yml | |
| # Install JS packages | |
| RUN yarn install --check-files | |
| # Precompile assets | |
| # NOTE: The app may require some environment variables (e.g., SECRET_KEY_BASE). All known mandatory variables | |
| # are listed with fake values in .dockerdev/env_variables.sh script and exported below | |
| RUN ( \ | |
| source .dockerdev/.env \ | |
| && env \ | |
| && env_file_name=./config/environments/${RAILS_ENV}.rb \ | |
| && echo 'Rails.application.config.require_master_key = false' >> $env_file_name \ | |
| && bundle exec rake assets:clobber assets:precompile \ | |
| && sed -i '$ d' $env_file_name \ | |
| ) | |
| # Finally, our production image definition | |
| FROM base AS production | |
| SHELL ["/bin/bash", "-c"] | |
| WORKDIR "/home/my_user/app" | |
| # Install NodeJS and NPM from Nodesource | |
| ARG NODE_MAJOR=21 | |
| ARG FORCE_NODE="" | |
| RUN test -n "$FORCE_NODE" \ | |
| && echo "Package: nodejs" >> /etc/apt/preferences.d/preferences \ | |
| && echo "Pin: origin deb.nodesource.com" >> /etc/apt/preferences.d/preferences \ | |
| && echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/preferences \ | |
| && curl -sSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \ | |
| && apt-get install -y --no-install-recommends nodejs \ | |
| && rm -rf /var/lib/apt/lists/* \ | |
| && npm install -g yarn \ | |
| || echo "nodejs not mandatory for production environment" | |
| # Copy application code | |
| COPY . . | |
| # Configure Rails to allow public file server served by app server | |
| RUN sed -i 's/\(.*public_file_server\.enabled.*= \).*/\1true/' config/environments/${RAILS_ENV}.rb | |
| # Copy database config to avoid human errors | |
| COPY .dockerdev/database.yml.template /home/my_user/app/config/database.yml | |
| # Copy artifacts | |
| # 1) Installed gems | |
| COPY --from=production-builder $BUNDLE_PATH $BUNDLE_PATH | |
| # 2) Compiled assets | |
| COPY --from=production-builder /rails/publi[c]/asset[s]/ ./public/assets | |
| # pack[s] is on purpose. Using glob pattern to avoid error if folder does not exists | |
| COPY --from=production-builder /rails/publi[c]/pack[s]/ ./public/packs | |
| # 3) We can even copy the Bootsnap cache to speed up our Rails server load! | |
| COPY --from=production-builder /rails/tm[p]/cach[e]/bootsnap* ./tmp/cache/bootsnap | |
| # Force creation of tmp and log folders if not exists | |
| RUN mkdir -p /home/my_user/app/tmp | |
| # Run and own only the runtime files as a non-root user for security | |
| RUN groupadd --system --gid 1000 my_user && \ | |
| useradd my_user --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ | |
| chown -R my_user:my_user /home/my_user | |
| USER 1000:1000 | |
| EXPOSE 3000 | |
| CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment