Skip to content
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

Add default Dockerfiles #46762

Merged
merged 23 commits into from Dec 19, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions railties/lib/rails/generators/app_base.rb
Expand Up @@ -37,6 +37,9 @@ def self.add_shared_options_for(name)
class_option :skip_git, type: :boolean, aliases: "-G", default: nil,
desc: "Skip git init, .gitignore and .gitattributes"

class_option :skip_docker, type: :boolean, default: nil,
desc: "Skip Dockerfile, .dockerignore and bin/docker-entrypoint"

class_option :skip_keeps, type: :boolean, default: nil,
desc: "Skip source control .keep files"

Expand Down
14 changes: 14 additions & 0 deletions railties/lib/rails/generators/rails/app/app_generator.rb
Expand Up @@ -70,6 +70,14 @@ def gitattributes
template "gitattributes", ".gitattributes"
end

def dockerfiles
template "Dockerfile"
template "dockerignore", ".dockerignore"

template "docker-entrypoint", "bin/docker-entrypoint"
chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
end

def version_control
if !options[:skip_git] && !options[:pretend]
run git_init_command, capture: options[:quiet], abort_on_failure: false
Expand Down Expand Up @@ -342,6 +350,12 @@ def update_active_storage
end
remove_task :update_active_storage

def create_dockerfiles
unless options[:skip_docker]
build(:dockerfiles)
end
end

def create_config_files
build(:config)
end
Expand Down
33 changes: 33 additions & 0 deletions railties/lib/rails/generators/rails/app/templates/Dockerfile.tt
@@ -0,0 +1,33 @@
# Make sure it matches the Ruby version in .ruby-version and Gemfile
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be useful to mention --build-arg to help with debugging out-of-sync Ruby versions.

FROM ruby:<%= Gem.ruby_version %>

<% if using_node? -%>
# Install JavaScript dependencies and libvips for Active Storage
RUN curl -sL https://deb.nodesource.com/setup_19.x | bash -
RUN apt-get update -qq && apt-get install -y build-essential libvips nodejs && npm install -g yarn
dhh marked this conversation as resolved.
Show resolved Hide resolved

<% elsif !skip_active_storage? -%>
# Install libvips for Active Storage preview support
RUN apt-get update -qq && apt-get install -y build-essential libvips
dhh marked this conversation as resolved.
Show resolved Hide resolved

<% end -%>
WORKDIR /rails

ENV RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true" \
RAILS_ENV="production" \
BUNDLE_WITHOUT="development:test"

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install

# Copy application code
COPY . .

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile
dhh marked this conversation as resolved.
Show resolved Hide resolved

# Entrypoint prepares database and starts app on 0.0.0.0:3000
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it using the root user ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Mapping cleanly for non-root use-cases is an exercise in frustration especially for Linux where it needs to map to a host UID / GID in /etc/hosts.

If not running as root is important, run it via Podman.

If this is intended for deployment, most hosting providers aren't giving you root level to the full server. Just within the container you're given so I don't think it's a huge deal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are plenty of risks with rails running as root within a container, even is a syscap constrained environment (like the cloud). If a container is compromised, the attacker now has the ability to install packages, read and write arbitrary files within the container.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ianks thanks. This makes sense. I generally run all my docker containers as non-root users just because it's generally good practice, didn't realize there was real security concerns with it on hosting providers considering I never see dockerfiles from them as non-root users. Apologies for brushing this off and thank you for taking the time.

EXPOSE 3000
@@ -0,0 +1,9 @@
#!/bin/sh

# Used by the Dockerfile to start the application with a prepared database

# Create new or migrate existing database
./bin/rails db:prepare

# Start the server
exec ./bin/rails server "$@"
dhh marked this conversation as resolved.
Show resolved Hide resolved
30 changes: 30 additions & 0 deletions railties/lib/rails/generators/rails/app/templates/dockerignore.tt
@@ -0,0 +1,30 @@
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.

# Ignore bundler config.
/.bundle

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
<% if keeps? -%>
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
<% end -%>

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*
<% if keeps? -%>
!/storage/.keep
/tmp/storage/*
!/tmp/storage/
!/tmp/storage/.keep
<% end -%>
<% unless options.api? -%>

/public/assets
<% end -%>