-
Notifications
You must be signed in to change notification settings - Fork 12
fix: improve dockerfile for staging use #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,61 +1,77 @@ | ||
| FROM ruby:2.7.8-buster | ||
| # syntax=docker/dockerfile:1 | ||
| # check=error=true | ||
|
|
||
| # Install basic Linux packages | ||
| RUN apt-get update -qq && apt-get install -y \ | ||
| # Make sure RUBY_VERSION matches the Ruby version in .ruby-version | ||
| ARG RUBY_VERSION=3.3.8 | ||
| FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base | ||
|
|
||
| # Rails app lives here | ||
| WORKDIR /rails | ||
|
|
||
| # 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 | ||
|
|
||
| # Set production environment | ||
| ENV RAILS_ENV="production" \ | ||
| BUNDLE_DEPLOYMENT="1" \ | ||
| BUNDLE_PATH="/usr/local/bundle" \ | ||
| BUNDLE_WITHOUT="development" | ||
|
|
||
| # 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 \ | ||
| libpq-dev \ | ||
| nodejs \ | ||
| yarn \ | ||
| default-libmysqlclient-dev \ | ||
| git \ | ||
| curl \ | ||
| imagemagick \ | ||
| libvips \ | ||
| tzdata \ | ||
| libxml2-dev \ | ||
| libxslt1-dev \ | ||
| libffi-dev \ | ||
| libreadline-dev \ | ||
| libssl-dev \ | ||
| zlib1g-dev \ | ||
| libsqlite3-dev \ | ||
| sqlite3 | ||
|
|
||
| # Set working directory | ||
| WORKDIR /app | ||
|
|
||
| # Set environment variables | ||
| ENV RAILS_ENV=production \ | ||
| RACK_ENV=production \ | ||
| BUNDLE_PATH=/gems \ | ||
| BUNDLE_BIN=/gems/bin \ | ||
| PATH="/gems/bin:$PATH" | ||
|
|
||
| # Install bundler | ||
| RUN gem install bundler -v 2.4.12 | ||
|
|
||
| # Copy app code and install dependencies | ||
| libyaml-dev \ | ||
| pkg-config && \ | ||
| rm -rf /var/lib/apt/lists /var/cache/apt/archives | ||
|
|
||
| # Install application gems | ||
| 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 | ||
|
|
||
| # Copy application code | ||
| COPY . . | ||
|
|
||
| RUN bundle install --without development test | ||
|
|
||
| # These envs are used in the rails application. While they are entirely | ||
| # unrelated to the docker build process, they are required for the app to run. | ||
| # Without these build args the asset precompilation will fail. | ||
| ARG SECRET_KEY_BASE | ||
| ARG AWS_ACCESS_KEY_ID | ||
| ARG AWS_SECRET_ACCESS_KEY | ||
| ARG AWS_REGION | ||
| ARG AWS_S3_BUCKET | ||
| ARG SMTP_USERNAME | ||
| ARG SMTP_PASSWORD | ||
| ARG SMTP_SERVER | ||
| ARG SMTP_PORT | ||
|
|
||
| # Precompile assets (if applicable) | ||
| RUN bundle exec rake assets:precompile | ||
|
|
||
| # Expose port (default Rails) | ||
| EXPOSE 3000 | ||
| # Precompile bootsnap code for faster boot times | ||
| # RUN bundle exec bootsnap precompile app/ lib/ | ||
|
|
||
| # Precompiling assets for production without requiring secret RAILS_MASTER_KEY | ||
| RUN SECRET_KEY_BASE=dummy \ | ||
| SMTP_SERVER=dummy \ | ||
| SMTP_PORT=dummy \ | ||
| SMTP_USERNAME=dummy \ | ||
| SMTP_PASSWORD=dummy \ | ||
| ./bin/rails assets:precompile | ||
|
|
||
| # Final stage for app image | ||
| FROM base | ||
|
|
||
| # Start the server (customize to your app server if needed) | ||
| CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] | ||
| # Copy built artifacts: gems, application | ||
| COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" | ||
| COPY --from=build /rails /rails | ||
|
|
||
| # 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 tmp | ||
| USER 1000:1000 | ||
|
|
||
| # Entrypoint prepares the database. | ||
| ENTRYPOINT ["/rails/bin/docker-entrypoint"] | ||
|
|
||
| # Start server via Thruster by default, this can be overwritten at runtime | ||
| EXPOSE 3000 | ||
| CMD ["./bin/rails", "server"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #!/bin/bash -e | ||
|
|
||
| # Enable jemalloc for reduced memory usage and latency. | ||
| if [ -z "${LD_PRELOAD+x}" ]; then | ||
| LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) | ||
| export LD_PRELOAD | ||
| fi | ||
|
|
||
| # If running the rails server then create or migrate existing database | ||
| if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then | ||
| ./bin/rails db:prepare | ||
| fi | ||
|
|
||
| exec "${@}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,26 @@ | ||
| development: | ||
| host: 127.0.0.1 | ||
| default: &default | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pysch issues with upgrade were causing an issue here, which is why the stanza got pulled out. |
||
| host: <%= ENV.fetch('DB_HOST', 'localhost') %> | ||
| username: root | ||
| port: 3306 | ||
| adapter: mysql2 | ||
| encoding: utf8 | ||
| pool: 5 | ||
| pool: 100 | ||
|
|
||
| development: | ||
| <<: *default | ||
| database: awbw_development | ||
|
|
||
| # Warning: The database defined as "test" will be erased and | ||
| # re-generated from your development database when you run "rake". | ||
| # Do not set this db to the same as development or production. | ||
| test: | ||
| host: 127.0.0.1 | ||
| username: root | ||
| adapter: mysql2 | ||
| encoding: utf8 | ||
| pool: 5 | ||
| <<: *default | ||
| database: awbw_test | ||
|
|
||
| production: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're using DATABASE_URL so there's no reason to set these except for configuration like pool size |
||
| <<: *default | ||
| database: awbw_production | ||
|
|
||
| staging: | ||
| <<: *default | ||
| database: awbw_staging | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,13 @@ | ||
| # Resolve the correct DB credentials | ||
| config = YAML.load(ERB.new(File.read(Rails.root.join('config/database.yml'))).result) | ||
| env_config = config[Rails.env] | ||
|
|
||
| # Extract credentials | ||
| adapter = env_config['adapter'] | ||
| database = env_config['database'] | ||
|
|
||
| # Only run if MySQL is the DB | ||
| if adapter.include?('mysql') | ||
| sql_file = Rails.root.join('db', 'awbw_dml_only.sql') | ||
| sql_file = Rails.root.join('db', 'awbw_dml_only.sql') | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is going to fall out in the rebase from other PRs but solid catch, |
||
|
|
||
| puts "Loading SQL dump from #{sql_file}..." | ||
| puts "Loading SQL dump from #{sql_file}..." | ||
|
|
||
| # Run the command | ||
| command = "rails dbconsole < #{sql_file}" | ||
| system(command) || raise("Failed to load SQL dump into #{database}") | ||
|
|
||
| puts "SUCCESS! SQL dump loaded successfully." | ||
| else | ||
| puts "Skipping SQL dump: not using MySQL (adapter = #{adapter})" | ||
| end | ||
| # Run the command | ||
| command = "rails dbconsole < #{sql_file}" | ||
| system(command) || raise("Failed to load SQL dump") | ||
|
|
||
| puts "SUCCESS! SQL dump loaded successfully." | ||
|
|
||
| # wrapping in a tx for now | ||
| ActiveRecord::Base.transaction do | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ services: | |
| ports: | ||
| - 3306:3306 | ||
| expose: | ||
| - '3306' | ||
| - "3306" | ||
| volumes: | ||
| - type: volume | ||
| source: mysql-data | ||
|
|
@@ -24,15 +24,16 @@ services: | |
| web: | ||
| build: | ||
| context: . | ||
| dockerfile: Dockerfile.dev # <— use the dev Dockerfile | ||
| dockerfile: Dockerfile | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're only using compose locally right? Or are you trying to get everything together in one place? |
||
| target: build | ||
| depends_on: | ||
| database: | ||
| condition: service_healthy | ||
| env_file: .env | ||
| environment: | ||
| # Fallback so Rails can boot even if .env is minimal. | ||
| # If you prefer traditional keys, set DB_* in .env and configure database.yml accordingly. | ||
| DATABASE_URL: mysql2://root@database:3306/awbw_development | ||
| DB_HOST: "database" | ||
| RAILS_ENV: development | ||
| RAILS_LOG_TO_STDOUT: "true" | ||
| ports: | ||
|
|
@@ -48,4 +49,3 @@ services: | |
|
|
||
| volumes: | ||
| mysql-data: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider locking this to the debian version we're shipping. Otherwise you can end up surprised when the rails docker team switched the base image underneath you 😄