Skip to content

Add default Dockerfiles#46762

Merged
dhh merged 23 commits into
mainfrom
add-default-dockerfile
Dec 19, 2022
Merged

Add default Dockerfiles#46762
dhh merged 23 commits into
mainfrom
add-default-dockerfile

Conversation

@dhh

@dhh dhh commented Dec 17, 2022

Copy link
Copy Markdown
Member

Add Docker files by default to new apps: Dockerfile, .dockerignore, bin/docker-entrypoint. These files can be skipped with --skip-docker. They're intended as a starting point for a production deploy of the application. Not intended for development (see Docked Rails for that).

Example:

docker build -t app .
docker volume create app-storage
docker run --rm -it -v app-storage:/rails/storage -p 3000:3000 --env RAILS_MASTER_KEY=<see config/master.key> app

You can also start a console or a runner from this image:

docker run --rm -it -v app-storage:/rails/storage --env RAILS_MASTER_KEY=<see config/master.key> app console

To create a multi-platform image on Apple Silicon to deploy on AMD or Intel and push to Docker Hub for user/app:

docker login -u <user>
docker buildx create --use
docker buildx build --push --platform=linux/amd64,linux/arm64 -t <user/image> .

Let's make it easier for someone to go from Hello World locally to production.
@rails-bot rails-bot Bot added the railties label Dec 17, 2022
@amatsuda

Copy link
Copy Markdown
Member

The CI lint failure is unrelated to this patch, and has already been fixed on main via #46763.

Comment thread railties/lib/rails/generators/rails/app/templates/Dockerfile.tt Outdated
Comment thread railties/lib/rails/generators/rails/app/templates/Dockerfile.tt
David Heinemeier Hansson added 6 commits December 19, 2022 08:53
* main:
  Remind of credentials diff enrollment on edit
  [docs] Code samples for postgres configs
  Silence credentials generator in app generator
  Let `initialize` not create an Array as its return value
  Reduce Array allocations in MimeNegotiation
  Trim trailing whitespace from *.md files
  Avoid unnecessary replacements when the node doesn't change
  Allow assets:precompile to be run in a production build step without passing in RAILS_MASTER_KEY (#46760)
Comment thread railties/lib/rails/generators/rails/app/templates/docker-entrypoint.tt Outdated
Comment thread railties/lib/rails/generators/rails/app/templates/Dockerfile.tt Outdated
@dhh dhh merged commit 4f3af4a into main Dec 19, 2022
@dhh dhh deleted the add-default-dockerfile branch December 19, 2022 15:07
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Dec 19, 2022
Follow-up to rails#46762.

Docker-related files are intended for production deployment, not
development.  Therefore, this commit prevents those files from being
generated for plugin dummy apps.
@@ -0,0 +1,50 @@
# Make sure it matches the Ruby version in .ruby-version and Gemfile

Copy link
Copy Markdown
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.


# Entrypoint prepares database and starts app on 0.0.0.0:3000 by default,
# but can also take a rails command, like "console" or "runner" to start instead.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

Copy link
Copy Markdown

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 ?

Copy link
Copy Markdown

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
Copy Markdown
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.

Copy link
Copy Markdown

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.

ARG NODE_MAJOR_VERSION=19
RUN curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR_VERSION.x | bash -
RUN apt-get update -qq && \
apt-get install -y build-essential libvips nodejs && \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These should be removed after bundle installs and asset pre-compilation to reduce container bloat

@dixpac

dixpac commented Dec 24, 2022

Copy link
Copy Markdown
Contributor

@dhh what about using alpine based image for production?
From our experience which is Rails 7 app(with esbuild) difference is hundred of MBs in compressed size, even more when image is downloaded and "un-compressed".

@KonnorRogers

Copy link
Copy Markdown

@dixpac while Alpine is great for size, the glaring issue is that it uses musl-libc instead of glibc which could be a big stumbling block for new users.

https://wiki.alpinelinux.org/wiki/Running_glibc_programs

@dhh

dhh commented Dec 24, 2022

Copy link
Copy Markdown
Member Author

Compatibility is more important than size for the default image. You can always tailor the generated file as you see fit.

@collimarco

Copy link
Copy Markdown
Contributor

Is there any command to add the default Dockerfile to an existing Rails app?

@KonnorRogers

Copy link
Copy Markdown

@collimarco run rails new sample-app and just copy the Dockerfile from the sample-app into your current project?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.