Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 71 additions & 55 deletions Dockerfile
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
Copy link
Collaborator

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 😄


# 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"]
14 changes: 14 additions & 0 deletions bin/docker-entrypoint
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 "${@}"
24 changes: 16 additions & 8 deletions config/database.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
development:
host: 127.0.0.1
default: &default
Copy link
Collaborator

Choose a reason for hiding this comment

The 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:
Copy link
Collaborator

Choose a reason for hiding this comment

The 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
26 changes: 7 additions & 19 deletions db/seeds.rb
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')
Copy link
Collaborator

Choose a reason for hiding this comment

The 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
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
ports:
- 3306:3306
expose:
- '3306'
- "3306"
volumes:
- type: volume
source: mysql-data
Expand All @@ -24,15 +24,16 @@ services:
web:
build:
context: .
dockerfile: Dockerfile.dev # <— use the dev Dockerfile
dockerfile: Dockerfile
Copy link
Collaborator

Choose a reason for hiding this comment

The 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:
Expand All @@ -48,4 +49,3 @@ services:

volumes:
mysql-data: