fly-apps / dockerfile-rails Goto Github PK
View Code? Open in Web Editor NEWProvides a Rails generator to produce Dockerfiles and related files.
License: MIT License
Provides a Rails generator to produce Dockerfiles and related files.
License: MIT License
It would be great if this could add all the ImageMagic libraries if it detects rmagick or minimagick.
Always include git
in the official Rails Dockerfile.
Even if a Gemfile starts off without a git
reference, it's something that is likely to happen during the course of a Rails project. It would be great to not have this break the Dockerfile
build.
Everything below is a bug I ran into when deploying a Rails application with a github
reference. I can dive deeper into the problem, but the simpler fix with what I think is a better dev experience is what I propose above.
When I deploy an application with the following Gemfile:
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
"https://github.com/#{repo_name}.git"
end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 7.0.0'
# Use Puma as the app server
gem 'puma', '~> 6.0'
# Use SCSS Gor stylesheets
gem 'sassc-rails'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.10'
# Use Redis adapter to run Action Cable in production
gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.13'
# HAML templates yo
gem 'haml-rails'
# Authorization libraries
gem 'omniauth'
gem 'omniauth-google-oauth2'
# Authorization logic
gem 'pundit'
# Form helper
gem 'simple_form', '~> 5.0'
# Communicate with Twilio
gem 'twilio-ruby'
# Handle phone numbers as a propper data type (and normalize)
gem 'phony_rails'
# For claims to create resources in a phone ack
gem 'jwt'
# Validate password and token strengths based on entropy.
gem 'strong_password'
# Display times locally
gem 'local_time'
# Run Postgres in production
gem 'pg', '~> 1.4'
# Application error alerts
gem 'rollbar'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
# Generate's PDFs, mostly for labels
gem "prawn", "~> 2.0"
# Print QR codes in a PDF
gem "prawn-qrcode", "~> 0.5.0"
# Hierarchial record organization in ActiveRecord
gem "closure_tree", "~> 7.0"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# Parse natrual language date and time strings
gem "chronic", "~> 0.10.2"
# Search Postgres records
gem "pg_search", "~> 2.3"
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.3'
# Blanks from forms are converted into nil instead of stored as "" in the database
gem "nilify_blanks", "~> 1.4"
# Does union queries in ActiveRecord.
gem "active_record_union"
# Converts GUIDs in the URLs into shorter ids
gem "anybase", "~> 0.0.15"
# Pull this out when Rails 6.1 is a thing
gem "view_component", "~> 2.0"
# View template for CSV files
gem "csv_builder", "~> 2.1"
# Content management
if sitepress_gem_path = ENV["SITEPRESS_GEM_PATH"]
gem "sitepress", path: sitepress_gem_path
gem "sitepress-cli", path: sitepress_gem_path
gem "sitepress-rails", path: sitepress_gem_path
gem "sitepress-core", path: sitepress_gem_path
gem "sitepress-server", path: sitepress_gem_path
else
gem "sitepress-rails", github: "sitepress/sitepress", branch: "main"
end
# Markdown gem
gem "redcarpet", "~> 3.5.0"
# Parses SVG vector files and inverts them for darkmode.
gem "color", "~> 1.8"
# Used for reporting from the shell so I can see who signed up within a day/week
gem "groupdate", "~> 5.2"
# Render PDF file as an image to get around really annoying problems
# embedding PDFs in webpages or trying to embed them via PDF.js
gem "mini_magick", "~> 4.0.0"
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails'
gem 'faker'
gem 'factory_bot_rails'
end
group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'spring-commands-rspec'
end
group :test do
gem 'pundit-matchers', '~> 1.7.0'
gem 'shoulda-matchers', '~> 4.5.0'
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
gem 'rexml'
end
if featureomatic_path = ENV["FEATUREOMATIC_GEM_PATH"]
gem "featureomatic", path: featureomatic_path
else
gem "featureomatic", "~> 0.1.1", github: "rocketshipio/featureomatic"
end
gem "imageomatic", "~> 0.1.1", github: "imageomatic/ruby"
gem "mailto", "~> 0.1.1"
gem "stripe", "~> 5.38"
# Resource-oriented rails controllers
if oxidizer_peth = ENV["OXIDIZER_GEM_PATH"]
gem "oxidizer", path: oxidizer_peth
else
gem "oxidizer", github: "rocketshipio/oxidizer", branch: "main"
end
# No-password login flow
gem "nopassword", github: "rocketshipio/nopassword", branch: "main"
gem "matrix", "~> 0.4.2"
gem "ahoy_matey", "~> 4.1"
gem "slim-rails", "~> 3.5"
gem "blazer", "~> 2.6"
gem "turbo-rails", "~> 1.3"
gem "dockerfile-rails", ">= 1.0.0", :group => :development
The git
package is not included.
I've tracked down where that's set at https://github.com//rubys/dockerfile-rails/blob/f8564073360444cfd967eeb6c3d7f08c6ac29615/lib/dockerfile-rails/scanner.rb#L30-L42
What I'm not sure about is if the rescue block is catching "too much" since it rescues all errors. Here's what I get when I run that block in irb
or bundle exec irb
irb(main):007:0> gemfile_definition.spec_git_paths.empty?
/Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/source/git/git_proxy.rb:224:in `allowed_with_path': The git source https://github.com/rocketshipio/nopassword.git is not yet checked out. Please run `bundle install` before trying to start your application (Bundler::GitError)
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/source/git/git_proxy.rb:190:in `find_local_revision'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/source/git/git_proxy.rb:62:in `revision'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/source/git.rb:234:in `revision'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/source/git.rb:103:in `install_path'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/definition.rb:274:in `block in spec_git_paths'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/definition.rb:274:in `map'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.3.16/lib/bundler/definition.rb:274:in `spec_git_paths'
from (irb):7:in `<main>'
from /Users/bradgessler/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.6.2/exe/irb:11:in `<top (required)>'
from /Users/bradgessler/.rbenv/versions/3.2.0/bin/irb:25:in `load'
from /Users/bradgessler/.rbenv/versions/3.2.0/bin/irb:25:in `<main>'
irb(main):008:1* if File.exist? 'Gemfile'
irb(main):009:2* begin
irb(main):010:2* gemfile_definition = Bundler::Definition.build('Gemfile', nil, [])
irb(main):011:2* @gemfile += gemfile_definition.dependencies.map(&:name)
irb(main):012:2*
irb(main):013:3* unless ENV['RAILS_ENV'] == 'test'
irb(main):014:3* @git = !gemfile_definition.spec_git_paths.empty?
irb(main):015:2* end
irb(main):016:2* rescue => error
irb(main):017:2* STDERR.puts error.message
irb(main):018:1* end
irb(main):019:0> end
irb(main):020:0*
undefined method `+' for nil:NilClass
=> nil
Please add Litestream for SQLite3 db as a generator option.
Thank you!
We have a couple of generated gems that are in the same repo as our application.
Bundle install fails if they haven't been copied to docker image.
Would it be possible to look through the Gemfile/ Gemfile.lock for all gems specified with with a path and copy them before running bundle install
I'm trying to use ruby file: ".ruby-version"
on my Gemfile so I just have one file to update Ruby's version but I noticed I can't deploy on Fly with this change, I get the error that .ruby-version
does not exist.
I noticed that COPY --link Gemfile Gemfile.lock ./
happens before COPY . .
so at the bundle install phase, .ruby-version
file is not there yet. There are a couple of ways to fix this, either put COPY . .
before running bundle (not great) or simply copy .ruby-version
before (or with) copying gemfile/gemfile.lock, but there's a catch: not everyone will have this file (or maybe the file is in the gitignore/dockerignore list)
thinking if this could be fixed somehow. any ideas?
Consider adding a new option or more information in README about installing deb packages needed for gem compilation and those needed for runtime.
It's about a situation when the app needs a gem for Postgresql, MySQL and MSSQL server to work (as well as GEOS for geospatial extensions). In this case, simply using the -add option does not help, and you have to assign different packages in the section:
FROM base as build
# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev git libpq-dev node-gyp pkg-config python-is-python3 \
freetds-dev libgeos-dev
than the packages needed here:
FROM base
# Install packages needed for deployment
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y \
default-libmysqlclient-dev default-mysql-client freetds-bin libgeos-* libvips nodejs postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
Apparently --add
only adds packages required to build gems.
I am also curious if this tool is to be used to create Docker images for development or is it intended to be only for building production images? I'm asking because here is hardcoded RAILS_ENV production
When generating a Dockerfile for a project that uses execjs
and Yarn, the "Install yarn" section of the generated Dockerfile is missing a RUN
instruction.
The steps below were used to recreate the issue and the result is available here: https://github.com/jeff-french/dockerfile-rails-issue-reproduction
# Check environment
ruby --version
# ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
rails --version
# Rails 7.1.3
node --version
# v20.11.0
yarn --version
# 4.0.2
# New rails project
rails new blog
cd blog
# Setup Yarn
corepack enable
yarn init -2
yarn set version stable
yarn install
# Add execjs
bundle add execjs
# dockerfile-rails
bundle add dockerfile-rails --optimistic --group development
rails g dockerfile --force
This will produce an invalid section starting around line 40 of the generated Dockerfile
# Install yarn
ARG YARN_VERSION=4.0.2
corepack enable && \
corepack prepare yarn@$YARN_VERSION --activate
# Install yarn
ARG YARN_VERSION=4.0.2
RUN corepack enable && \
corepack prepare yarn@$YARN_VERSION --activate
The issue appears to be caused when the install_node
template is called the second time to setup Yarn:
dockerfile-rails/lib/generators/templates/Dockerfile.erb
Lines 67 to 70 in ec2b18e
In this call node_version
gets set to nil
due to the usage of execjs
and yarn_version
get set to 4.0.2
.
When the install_node
template gets rendered from this call, the following section gets skipped entirely since node_version=nil
:
dockerfile-rails/lib/generators/templates/_install_node.erb
Lines 23 to 34 in ec2b18e
and then this section attempts to append to the RUN
command from the previously skipped section:
dockerfile-rails/lib/generators/templates/_install_node.erb
Lines 35 to 46 in ec2b18e
I was able to get the expected output by changing the following section:
dockerfile-rails/lib/generators/templates/_install_node.erb
Lines 41 to 43 in ec2b18e
to
<% else -%>
<% if node_version -%> <% else %>RUN<% end %> corepack enable && \
<% end -%>
This fix worked in this particular situation but I'm not sure if it is a drop in solution when execjs
is not being used and the node_install
ends up rendering the full template.
The Webp-ffi gem requires libjpeg-dev libpng-dev libtiff-dev libwebp-dev
Hello, I am trying to use this dockerfile in a rails 6.1 project to run tests in Gitlab CI.
The build step runs fine with kaniko, but the test step fails with bundler: command not found: rails
. When I check what the vendor directory contains, it looks OK in the build step, but empty in the test step.
This is my dockerfile.yml
# generated by dockerfile-rails
---
options:
cache: true
ci: true
jemalloc: true
mysql: true
redis: true
root: true
packages:
build:
- git
- ruby-dev
- gcc
- make
- g++
- libffi-dev
- libmariadb-dev-compat
This is the Dockerfile
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.1.4
FROM ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /rails
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development" \
BUNDLE_DEPLOYMENT="1"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stage to reduce size of final image
FROM base as build
# Install packages needed to build gems and node modules
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl default-libmysqlclient-dev g++ gcc git libffi-dev libmariadb-dev-compat make node-gyp pkg-config python-is-python3 ruby-dev
# Install Node.js
ARG NODE_VERSION=17.6.0
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
rm -rf /tmp/node-build-master
# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
bundle config set app_config .bundle && \
bundle config set path /srv/vendor && \
bundle install && \
bundle exec bootsnap precompile --gemfile && \
bundle clean && \
mkdir -p vendor && \
bundle config set path vendor && \
cp -ar /srv/vendor .
# Install node modules
COPY --link package.json package-lock.json ./
RUN --mount=type=cache,id=bld-npm-cache,target=/root/.npm \
npm install
# Copy application code
COPY --link . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Final stage for app image
FROM base
# Install packages needed for deployment
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y curl default-mysql-client imagemagick libjemalloc2
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
# Deployment options
ENV LD_PRELOAD="libjemalloc.so.2" \
MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true" \
RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true"
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
This is the kaniko command in the build step:
script:
- mkdir -p /kaniko/.docker
- export container=docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --force --cache=false --context $CI_PROJECT_DIR --dockerfile Dockerfile --build-arg BUILDKIT_INLINE_CACHE=1 --build-arg RAILS_MASTER_KEY=$MASTER_KEY --destination $CI_REGISTRY_IMAGE:$DESTINATION_TAG
I think the required package is libicu-dev
I'm using SQL Server in my app. When I build a Dockerfile without specifying a database, it assumes I wish to use Sqlite3.
My Dockerfile is generated with the following additional lines:
RUN mkdir /data
# ...
ENV DATABASE_URL="sqlite3:///data/production.sqlite3"
# ...
VOLUME /data
A few notes:
@sqlite3 = true
dockerfile_generator.rb
sets a default to sqlite3--sqlite3
from the Add a Database section.I can appreciate that adding sqlite3 as a default is probably convenient or likely, however, if it is being used, it will be in the gemfile, or the database config, and as such, will be detected and should not be assumed unless specified. Because it is, I am manually editing the Dockerfile, even though it's otherwise entirely autogenerated from my config/dockerfile.yml
config file.
Would you consider removing the default value for #deploy_database
, and require checking as you do for pg and mysql?
So the dockerfile has this line
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
It will run migration when rails server being started. My question is, if auto-scaling triggers multiple web instances, will that run multiple db migrations at the same time? I think it would be nice if the migration could only run just once, after deployment, not everytime when a web server starts.
We use Shrine to store uploaded files. The Shrine documentation uses public/uploads for the storage directory.
https://shrinerb.com/docs/getting-started
It would be good to ignore this in .dockerignore like the storage directory is.
Alternatively an "instructions" option could be added to add anything custom to the .dockerignore.
I'm not entirely sure this is necessary in all cases, but in my experiments, I had to change this line to get my app to work properly.
to
rails: "./bin/rails server -b 0.0.0.0"
Support to compare versions using String
is a recent addition, causing this line to raise exception RubyGems < 3.4.19
โถ ruby --version
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-darwin20]
โถ gem --version
3.2.33
โถ bin/rails generate dockerfile --parallel --cache --ci
/Users/ttilberg/.asdf/installs/ruby/3.0.4/lib/ruby/gems/3.0.0/gems/dockerfile-rails-1.5.7/lib/generators/dockerfile_generator.rb:504:in `>=': comparison of Gem::Version with String failed (ArgumentError)
from /Users/ttilberg/.asdf/installs/ruby/3.0.4/lib/ruby/gems/3.0.0/gems/dockerfile-rails-1.5.7/lib/generators/dockerfile_generator.rb:504:in `base_gems'
๐ Thanks for your contribution.
Issue:
I have a new Rails 7.1.2 which after the creation of the app I deleted the default DockerFile that comes with Rails 7.1.x
and run the command.
bin/rails generate dockerfile --fullstaq --jemalloc
Then when I tried to check that the image builds with
docker build .
I got this error.
23.69 An error occurred while installing psych (5.1.2), and Bundler cannot continue.
23.69
23.69 In Gemfile:
23.69 importmap-rails was resolved to 1.2.3, which depends on
23.69 railties was resolved to 7.1.2, which depends on
23.69 irb was resolved to 1.10.1, which depends on
23.69 rdoc was resolved to 6.6.2, which depends on
23.69 psych
....
....
....
Dockerfile:32
--------------------
31 | COPY --link Gemfile Gemfile.lock ./
32 | >>> RUN bundle install && \
33 | >>> bundle exec bootsnap precompile --gemfile && \
34 | >>> rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
35 |
--------------------
ERROR: failed to solve: process "/bin/bash -o pipefail -c bundle install && bundle exec bootsnap precompile --gemfile && rm -rf ~/.bundle/ \"${BUNDLE_PATH}\"/ruby/*/cache \"${BUNDLE_PATH}\"/ruby/*/bundler/gems/*/.git" did not complete successfully: exit code: 5
Doing some extra research it turns out that Phych 5.x.x requires libyaml on MacOS and libyaml-dev
on ubuntu.
ruby/psych#602
Resolution:
Adding libyaml-dev
in the DockerFile builds the image successfully.
Thanks
.tool-versions
may also contain information about ruby, yarn, and python, java, awscli, azure-cli, elixir, etc.. versions formatted like...
ruby 3.2.0
nodejs 19.6.0
yarn 1.22.19
python 3.10.7 2.7.18
I think the Dockerfile is missing the rails assets:precompile
and because of that the assets are not included in the asset pipeline.
โฏ docker run -p 3000:3000 -e RAILS_MASTER_KEY=$(cat config/master.key) esbuild-welcome
W, [2023-01-22T00:16:02.288717 #7] WARN -- : You are running SQLite in production, this is generally not recommended. You can disable this warning by setting "config.active_record.sqlite3_production_warning=false".
=> Booting Puma
=> Rails 7.0.4.1 application starting in production
=> Run `bin/rails server --help` for more startup options
W, [2023-01-22T00:16:02.729948 #1] WARN -- : You are running SQLite in production, this is generally not recommended. You can disable this warning by setting "config.active_record.sqlite3_production_warning=false".
Puma starting in single mode...
* Puma version: 5.6.5 (ruby 3.1.3-p185) ("Birdie's Version")
* Min threads: 5
* Max threads: 5
* Environment: production
* PID: 1
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
I, [2023-01-22T00:16:09.640125 #1] INFO -- : [51ad9596-d807-424d-a198-1f70350edc90] Started GET "/" for 172.17.0.1 at 2023-01-22 00:16:09 +0000
I, [2023-01-22T00:16:09.641340 #1] INFO -- : [51ad9596-d807-424d-a198-1f70350edc90] Processing by TimeController#index as HTML
I, [2023-01-22T00:16:09.643353 #1] INFO -- : [51ad9596-d807-424d-a198-1f70350edc90] Rendered time/index.html.erb within layouts/application (Duration: 0.3ms | Allocations: 288)
I, [2023-01-22T00:16:09.645141 #1] INFO -- : [51ad9596-d807-424d-a198-1f70350edc90] Rendered layout layouts/application.html.erb (Duration: 2.1ms | Allocations: 1272)
I, [2023-01-22T00:16:09.645281 #1] INFO -- : [51ad9596-d807-424d-a198-1f70350edc90] Completed 500 Internal Server Error in 4ms (Allocations: 2487)
F, [2023-01-22T00:16:09.645694 #1] FATAL -- : [51ad9596-d807-424d-a198-1f70350edc90]
[51ad9596-d807-424d-a198-1f70350edc90] ActionView::Template::Error (The asset "application.css" is not present in the asset pipeline.
):
[51ad9596-d807-424d-a198-1f70350edc90] 6: <%= csrf_meta_tags %>
[51ad9596-d807-424d-a198-1f70350edc90] 7: <%= csp_meta_tag %>
[51ad9596-d807-424d-a198-1f70350edc90] 8:
[51ad9596-d807-424d-a198-1f70350edc90] 9: <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
[51ad9596-d807-424d-a198-1f70350edc90] 10: <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
[51ad9596-d807-424d-a198-1f70350edc90] 11: </head>
[51ad9596-d807-424d-a198-1f70350edc90] 12:
[51ad9596-d807-424d-a198-1f70350edc90]
[51ad9596-d807-424d-a198-1f70350edc90] app/views/layouts/application.html.erb:9
Hi
I need to access Rails.application.credentials
at build time.
How do I do this?
Thanks!
The following is failing when building with Ruby 2.7.8.
RUN gem update --system --no-document && \
gem install -N bundler
Rubygems has dropped support for Ruby 2.6 and 2.7 in version 3.5.0.
https://github.com/rubygems/rubygems/releases/tag/v3.5.0
This can be fixed by specifying the latest version of rubygems that is compatible with these version of Ruby. e.g.
RUN gem update --system 3.4.22 --no-document && \
gem install -N bundler
Hey Sam!
Thanks for all the work you've put into this gem. I'm currently running in an error from the scanner.rb
when trying to determine if git is needed. My gemfile has multiple gems requiring git. This is the stacktrace when running bin/rails generate dockerfile
/Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/source/git/git_proxy.rb:224:in `allowed_with_path': The git source https://github.com/shrinerb/shrine.git is not yet checked out. Please run `bundle install` before trying to start your application (Bundler::GitError)
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/source/git/git_proxy.rb:190:in `find_local_revision'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/source/git/git_proxy.rb:62:in `revision'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/source/git.rb:234:in `revision'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/source/git.rb:103:in `install_path'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/definition.rb:284:in `block in spec_git_paths'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/definition.rb:284:in `map'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bundler-2.3.25/lib/bundler/definition.rb:284:in `spec_git_paths'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/dockerfile-rails-0.4.3/lib/dockerfile-rails/scanner.rb:31:in `scan_rails_app'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/dockerfile-rails-0.4.3/lib/generators/dockerfile_generator.rb:48:in `generate_app'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:134:in `block in invoke_all'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:134:in `each'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:134:in `map'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:134:in `invoke_all'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/group.rb:232:in `dispatch'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/railties/lib/rails/generators.rb:275:in `invoke'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/railties/lib/rails/commands/generate/generate_command.rb:26:in `perform'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/railties/lib/rails/command/base.rb:69:in `perform'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/railties/lib/rails/command.rb:48:in `invoke'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/railties/lib/rails/commands.rb:18:in `<main>'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:38:in `require'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/skylight-5.3.4/lib/skylight/probes.rb:166:in `require'
from /Users/louim/work/didacte/bin/rails:5:in `<main>'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:10:in `block in fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:10:in `block in fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:27:in `fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/bundler/gems/rails-ca3e163b7cf8/activesupport/lib/active_support/fork_tracker.rb:27:in `fork'
from <internal:/Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/Users/louim/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from -e:1:in `<main>'
But the source is checked out and I'm able to start the application without any problem. I'm using the latest version (ATM) of the gem: 0.43. The problem is not specific to that gem, if commented from the file, it fails on the next one using git.
Happy to help debugging if you need more details!
The latest jsbundling-rails release includes the ability to use bun as well. It would be nice if when the Dockerfile is being generated, it could also detect bun
as the js runtime (probably via the presence of bun.lockb
or bun.config.js
files and use that instead of Node
Hey!
My app is 99% like an API only rails app with a frontend folder. We don't use the api_only
rails setting but I'd like to be able to override the API only detection with a generator flag here: https://github.com/rubys/dockerfile-rails/blob/6e69810279fe46d6f5b9d09a3a6b4b4ae876bc0c/lib/generators/dockerfile_generator.rb#L241-L243
Does that sound useful to you?
Disclaimer: I'm not a docker superuser, especially when it comes to managing permissions and users between the host and containers, so it's very possible I'm doing something wrong.
Doing a standard generation with --compose --postgresql
seems to generate a docker-compose.yml
that specifies a volume mapping of ./tmp/db:/var/lib/postgresql/data
; the resulting tmp/db
directory is owned by root
on the host system which is problematic - this caught me out specifically because when I attempted to do docker build .
it would fail since it wasn't allowed to read that file.
I suspect this is probably not a direct bug in the gem itself, but it's the sort of thing I feel this gem should be trying to help with.
(I assume this probably happened with all variations that configure volumes, but have only used postgresql
myself)
We just encountered a deploy issue because we were generating the docker file on an M1 Mac and deploying to x86 without explicitly setting the platform.
Given the intention of this effort is to operate on the principle of least surprise, that most deploy environments are still x86, and M(1|2) Macs are going to be more common, it would be helpful to provide a notice that you may be generating unintentional results without specifying the --platform
option.
Erroring and asking to declare the --platform
option might be the cleanest option, but a bit heavy handed. A very obvious warning might be better. The warning/error could be isolated to if Gem::Platform.local.cpu
is used as a fallback.
> [build 7/7] RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile:
#21 3.323 sh: 1: yarn: not found
#21 3.323 rails aborted!
#21 3.324 jsbundling-rails: Command build failed, ensure yarn is installed and `yarn build` runs without errors
#21 3.324 /rails/vendor/ruby/3.2.0/gems/jsbundling-rails-1.1.1/lib/tasks/jsbundling/build.rake:5:in `block (2 levels) in <main>'
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.1
FROM quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-jemalloc-slim as base
LABEL fly_launch_runtime="rails"
# Rails app lives here
WORKDIR /rails
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development:test" \
BUNDLE_DEPLOYMENT="1"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stages to reduce size of final image
FROM base as prebuild
# Install packages needed to build gems and node modules
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl git node-gyp pkg-config python-is-python3
FROM prebuild as node
# Install JavaScript dependencies
ARG NODE_VERSION=16.15.1
ARG YARN_VERSION=1.22.18
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master
# Install node modules
COPY --link package.json yarn.lock ./
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
YARN_CACHE_FOLDER=/root/.yarn yarn install --frozen-lockfile
FROM prebuild as build
# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
bundle config set app_config .bundle && \
bundle config set path /srv/vendor && \
bundle install && \
bundle exec bootsnap precompile --gemfile && \
bundle clean && \
mkdir -p vendor && \
bundle config set path vendor && \
cp -ar /srv/vendor .
# Copy node modules
COPY --from=node /rails/node_modules /rails/node_modules
# Copy application code
COPY --link . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Adjust binfiles to set current working directory
RUN grep -l '#!/usr/bin/env ruby' /rails/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)'
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
# Final stage for app image
FROM base
# Install packages needed for deployment
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y iputils-ping libsqlite3-0 net-tools procps traceroute
# Run and own the application files as a non-root user for security
RUN useradd rails --home /rails --shell /bin/bash
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=rails:rails /rails /rails
# Deployment options
ENV RUBY_YJIT_ENABLE="1"
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
Spent some time to debug it, but maybe put some warning/confirmation when jsbundling-rails
is present and user is using --parallel
option or add node/yarn into prebuild
stage?
I have a config file like this:
# generated by dockerfile-rails
---
options:
bin-cd: true
cache: true
fullstaq: true
jemalloc: true
parallel: true
postgresql: true
redis: true
root: true
yjit: true
packages:
base:
- git
- libyaml-dev
envs:
base:
BUNDLE_WITHOUT: development:test:linting:profiler
GIT_REV: "${GIT_REV}"
BUILD_DATE: "${BUILD_DATE}"
RAILS_LOG_TO_STDOUT: 'true'
args:
base:
GIT_REV: "${GIT_REV}"
BUILD_DATE: "${BUILD_DATE}"
when I try to generate the Dockerfile, libyaml-dev
is simply ignored, no matter what I try and if I manually add it to the Dockerfile, it gets wiped if I try to regenerate the Dockerfile.
I'm not sure if it is related or not but I'm using Rails from the main branch and when I run the generator, I see this before anything else:
The git source https://github.com/rails/rails.git is not yet checked out. Please run `bundle install` before trying to start your application
identical Dockerfile
identical .dockerignore
identical .node-version
identical bin/docker-entrypoint
identical config/dockerfile.yml
even though the git source is definitely checked out
(erb):23:in `get_binding': undefined method `split' for nil:NilClass (NoMethodError)
from /Users/shin/.rbenv/versions/3.1.3/lib/ruby/3.1.0/erb.rb:905:in `eval'
from /Users/shin/.rbenv/versions/3.1.3/lib/ruby/3.1.0/erb.rb:905:in `result'
from /Users/shin/.rbenv/versions/3.1.3/lib/ruby/gems/3.1.0/gems/dockerfile-rails-1.0.7/lib/generators/dockerfile_generator.rb:142:in `render'
from /Users/shin/.rbenv/versions/3.1.3/lib/ruby/gems/3.1.0/gems/dockerfile-rails-1.0.7/lib/generators/templates/Dockerfile.erb:57:in `template'
I was trying to deploy my app to Fly.io and saw this error. How should I solve this error?
How to reproduce:
bin/rails generate dockerfile --cache --parallel --yjit --max-idle=3600
configure nginx and passenger
section of the generated Dockerfile, note how EOF
appears twice in a row instead of above, rending the Dockerfile corrupted.COPY <<-'EOF' /etc/nginx/sites-enabled/default
server {
listen 3000;
root /rails/public;
passenger_enabled on;
passenger_ctl hook_detached_process /etc/nginx/hook_detached_process;
passenger_min_instances 0;
passenger_pool_idle_time ;
}
# <<<<<<<<<<<<< SHOULD BE HERE
COPY <<-'EOF' /etc/nginx/sites-enabled/hook_detached_process
#!/usr/bin/env ruby
status = `passenger-status`
processes = status[/^Processes\s*:\s*(\d*)/, 1].to_i
system 'nginx -s stop' if processes == 0
EOF # <<<<<<<<<<<<< THIS
EOF
I host some gems in a private gemserver.
As it seems, dockerfile-rails does not support to set secrets.
This is how I do it in my current Dockerfile
:
RUN --mount=type=secret,id=gemserver_credentials,dst=/kaniko/gemserver_credentials \
--mount=type=cache,id=gems,sharing=locked,target=/app/vendor/cache \
BUNDLE_GEMS__MYSERVER__COM="$(cat /kaniko/gemserver_credentials)" \
&& mkdir -p /usr/local/bundle \
&& export BUNDLE_GEMS__MYSERVER__COM \
&& bundle config set cache_all true \
&& bundle install \
&& find /usr/local/bundle/ -name ".git" -exec rm -rv {} + \
&& find /usr/local/bundle/ -name "*.c" -delete \
&& find /usr/local/bundle/ -name "*.o" -delete \
&& bundle cache \
&& bundle config unset cache_all \
&& rm -rf /usr/local/bundle/ruby/*/cache
Notable is
--mount=type=secret,id=gemserver_credentials,dst=/kaniko/gemserver_credentials
I mount the secret at /kaniko
to be able to support kaniko next to docker buildBUNDLE_GEMS__MYSERVER__COM="$(cat /kaniko/gemserver_credentials)"
reads the secretexport BUNDLE_GEMS__MYSERVER__COM
exposes the secret to bundlerI also have a special Docker Compose file, which I load in addition to the normal docker-compose.yml file
version: '3.8'
services:
web:
build:
secrets:
- gemserver_credentials
secrets:
- gemserver_credentials
secrets:
gemserver_credentials:
file: ./BUNDLE_GEMS__MYSERVER__COM.txt
I understand this isn't meant for mrsk, but it'll be used by many people for that. And mrsk now requires curl
to be installed.
Maybe add it by default (it's a small package) or via an option?
Over the weekend, I realized that the exposed port dockerfile-rails
generated when Thruster is present is insufficient to make Thurster work transparently. I summed up my findings here but long story short:
dockerfile-rails
exposes 3000EXPOSE
directives to route traffic to the correct port, will bypass Thruster completely in these casesI think the easiest solution is to keep exposing 3000 for the sake of backward compatibility (and everyone expects Rails to expose 3000 anyway) but bind Thruster to 3000 and Puma to e.g. 3001, something like this:
if thurster?
ARG TARGET_PORT=3001
ARG HTTP_PORT=3000
EXPOSE ${HTTP_PORT}
end
I can take a stab at a PR for it unless you have a better idea
I'm building a project using a template available in this repo
Now, someone tried running the project in Windows using docker desktop and they keep getting this error:
#17 110.5 Installing sprockets-rails 3.4.2 #17 110.6 Installing actionmailer 7.0.4.3 #17 110.7 Installing activestorage 7.0.4.3 #17 110.7 Installing railties 7.0.4.3 #17 111.1 Fetching actionmailbox 7.0.4.3 #17 111.1 Fetching actiontext 7.0.4.3 #17 111.3 Installing actionmailbox 7.0.4.3 #17 111.3 Installing actiontext 7.0.4.3 #17 112.1 Fetching cssbundling-rails 1.1.2 #17 112.1 Fetching jsbundling-rails 1.1.1 #17 112.1 Fetching turbo-rails 1.4.0
#17 112.1 Fetching stimulus-rails 1.2.1 #17 112.3 Installing cssbundling-rails 1.1.2 #17 112.3 Installing jsbundling-rails 1.1.1 #17 112.4 Installing stimulus-rails 1.2.1
#17 112.5 Installing turbo-rails 1.4.0
#17 114.7 Fetching actioncable 7.0.4.3
#17 114.7 Fetching puma 5.6.5
#17 114.9 Installing actioncable 7.0.4.3
#17 115.0 Installing puma 5.6.5 with native extensions
#17 115.1 Fetching rails 7.0.4.3
#17 115.3 Installing rails 7.0.4.3
#17 116.3 Fetching bootsnap 1.16.0
#17 116.4 Installing bootsnap 1.16.0 with native extensions
#17 127.0 Bundle complete! 18 Gemfile dependencies, 57 gems now installed.
#17 127.0 Gems in the groups 'development' and 'test' were not installed.
#17 127.0 Bundled gems are installed into `./vendor/bundle`
#17 DONE 130.2s
#18 [build 5/9] COPY --link package.json yarn.lock ./
# 18 DONE 0.1s
#19 [build 6/9] RUN yarn install --frozen-lockfile
#19 1.546 yarn install v1.22.19
#19 1.657 [1/4] Resolving packages...
#19 1.809 [2/4] Fetching packages...
#19 27.33 [3/4] Linking dependencies...
# 19 29.95 [4/4] Building fresh packages...
# 19 30.50 Done in 28.96s.
#19 DONE 30.7s
#20 [build 7/9] COPY --link . .
#20 DONE 0.2s
#21 [build 8/9] RUN bundle exec bootsnap precompile app/lib/
# 21 DONE 1.7s
#22 [build 9/9] RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets: precompile
#22 0.692 /usr/bin/env: 'ruby\r': No such file or directory
#22 ERROR: executor failed running [/bin/sh -c SECRET_KEY_BASE=DUMMY ./bin/rails assets: precompile]: exit code: 127
> [build 9/9] RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets: precompile:
#22 0.692 /usr/bin/env: 'ruby\r': No such file or directory
failed to solve: executor failed running [/bin/sh -c SECRET_KEY_BASE=DUMMY ./bin/rails assets: precompile]: exit code: 127 $
(sorry that I can't offer a more complete backtrace, it's what the person receiving the error sent me)
Here's the Dockerfile:
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.0
FROM ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /rails
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development:test" \
BUNDLE_DEPLOYMENT="1"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stage to reduce size of final image
FROM base as build
# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl libpq-dev node-gyp pkg-config python-is-python3
# Install JavaScript dependencies
ARG NODE_VERSION=14.20.1
ARG YARN_VERSION=1.22.19
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master
# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN bundle install && \
bundle exec bootsnap precompile --gemfile && \
rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git
# Install node modules
COPY --link package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Copy application code
COPY --link . .
# 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 ./bin/rails assets:precompile
# Final stage for app image
FROM base
# Install packages needed for deployment
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Run and own the application files as a non-root user for security
ARG UID=1000 \
GID=1000
RUN groupadd -f -g $GID rails && \
useradd -u $UID -g $GID rails --home /rails --shell /bin/bash
USER rails:rails
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=rails:rails /rails /rails
# Deployment options
ENV RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true"
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
the docker-compose.yml
version: "3.8"
services:
web:
build:
context: .
args:
UID: ${UID:-1000}
GID: ${GID:-${UID:-1000}}
ports:
- "3000:3000"
environment:
- RAILS_MASTER_KEY=$RAILS_MASTER_KEY
- DATABASE_URL=postgres://root:password@postgres-db/
depends_on:
postgres-db:
condition: service_healthy
postgres-db:
image: postgres
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: password
volumes:
- ./tmp/db:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: pg_isready
interval: 2s
timeout: 5s
retries: 30
(we're using docker compose to build and run the images)
The problem is that I don't really have any windows environment to test it. It runs perfectly in different Linux environments, and I've read that the problem is directly related to windows line endings. The other problem, not a minor one, is that the user trying to run the project is not really technical, so I vastly prefer to understand how to make it work out-of-the-box instead of offering some solution that the affected person has to run on they end.
hey ๐๐ป
I see this issue where node is installed in the image and .node-version
is generated even if Bun is being used. This can cause problems, as I found before.
I think that using_node?
method just checks for package.json
existence which is not 100% correct since Bun also uses this. I believe that using_node?
should also check I'm not using_bun?
I think the old fly.io images also allowed this.
This allows me to build the image with BUNDLE_WITHOUT=development
This would be the image to use in the CI pipeline for testing.
After all tests were successful, one would build the production image with BUNDLE_WITHOUT=development:test
.
ARG BUNDLE_WITHOUT=development:test
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
I followed Sqlite3 on fly volumes tutorial and proactively enabled swap for demo rails app.
It turned out that, since the container is launched as root user when swap is on, fly mounts volumes for root too:
Mounting /dev/vdb at /mnt/volume w/ uid: 0, gid: 0 and chmod 0755
then entry-point script substitutes user for rails server
command with rails
user:
rendering mounted volumes un-accessible for rails
user.
Hey! I bumped the gem to the latest version and I started seeing:
ERROR: ld.so: object '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
in my docker compose logs. A wild guess is that it's related to the newly added security lockdown features, but I thought i'd ask before digging in.
It seems like this function should be checking for the presence of redis
or possibly redis-client
in the bundle instead of sidekiq
. I think
If so, are you able to add a a Changelog file or Release Notes for the tags, in order to show the purpose behind the updates. I've tried to follow the commits but it's hard to get a high level view of the purpose for the updates.
Much appreciated for the time spent on this. Impressive project. Thanks!
If you connect to a docker container and run rails console
, IRB will attempt to record a history file in /rails/.irb_history
, but this location is not writeable.
Perhaps configuring IRB to record this to /rails/log/irb_history.log
would be preferable. Users can already do this manually by including a .irbrc
file in the root of their project, so it may be helpful to create a default one if that file does not exist.
See https://community.fly.io/t/error-when-calling-executing-puppeteer/10395 for original request.
Dear dockerfile-rails
Team,
Regarding the issue mentioned in the title, I am searching for a gem that supports Alpine Linux
in the Dockerfile and Docker Compose for development purposes. Do you have any ideas? ๐
Regards
Right now, if ActionCable is being using, we try to add redis even if ActionCable is not configured to use redis. It would be better to make the check a bit smarter in determining if redis is actually required.
Hey ๐๐ป
I've been using Bun for quite some time now, and it seems stable for use with Rails.
I was checking the Docker ecosystem for Bun and turns out that they have official images now. I toyed around a little bit and manage to use the official image instead of manually install Bun like this:
FROM oven/bun:1 as bun
# Install node modules
COPY --link package.json bun.lockb ./
RUN --mount=type=cache,id=bld-bun-cache,target=/root/.bun \
bun install --frozen-lockfile
FROM prebuild as build
# Install application gems
COPY --link Gemfile Gemfile.lock .ruby-version ./
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
bundle config set app_config .bundle && \
bundle config set path /srv/vendor && \
bundle install && \
bundle clean && \
mkdir -p vendor && \
bundle config set path vendor && \
cp -ar /srv/vendor .
# Copy bun modules
COPY --from=bun /home/bun/app/node_modules /rails/node_modules
COPY --from=bun /usr/local/bin/bun /usr/local/bun
ENV PATH=/usr/local/bun/bin:$PATH
Changes needed were
- FROM prebuild as bun
+ FROM oven/bun:1 as bun # it could point to version and OS like `1-alpine` and so on
# on the prebuild stage
- COPY --from=bun /rails/node_modules /rails/node_modules
+ COPY --from=bun /home/bun/app/node_modules /rails/node_modules
- COPY --from=bun /usr/local/bun /usr/local/bun
+ COPY --from=bun /usr/local/bin/bun /usr/local/bun/bin/.
what are your thoughts on this one?
The readme mentions:
--max-idle=n - exit afer n seconds of inactivity. Supports iso 8601 and sleep syntaxes. Uses passenger for now, awaiting puma/puma#2580 support.
Puma has just added Shutdown on Idle on puma/puma#3209 ๐
Hi, I'm trying to generate Dockerfile with Alpine:
$ bin/rails generate dockerfile --alpine --jemalloc --yjit --cache --parallel
Node part of the generated Dockfile:
# Install JavaScript dependencies
ARG NODE_VERSION=20.10.0
ARG YARN_VERSION=1.22.21
RUN curl -sL https://unofficial-builds.nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64-musl.tar.gz | tar xz -C /tmp/ && \
cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-v${NODE_VERSION}-linux-x64-musl
# Copy node modules
COPY --from=node /rails/node_modules /rails/node_modules
COPY --from=node /usr/local/node /usr/local/node
ENV PATH=/usr/local/node/bin:$PATH
When building the image, it raises an error:
Error: failed to fetch an image or build from source: error building: failed to solve: failed to compute cache key: "/usr/local/node" not found: not found
Found the reason is the Node paths are inconsistent:
cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local && \
use /usr/local
COPY --from=node /usr/local/node /usr/local/node
use /usr/local/node
I tried to fix it by modifying the Dockerfile:
# Install JavaScript dependencies
ARG NODE_VERSION=20.10.0
ARG YARN_VERSION=1.22.21
+ ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://unofficial-builds.nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64-musl.tar.gz | tar xz -C /tmp/ && \
+ mkdir /usr/local/node && \
- cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local && \
+ cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-v${NODE_VERSION}-linux-x64-musl
It works, but I'm not sure it's the best way.
So please fix it in the generator, thanks.
I upgraded a project from 1.5.1 to 1.5.2 and generated a new Dockerfile. Subsequently, nginx refuses to start:
July 29, 2023 at 09:01 (UTC+2:00) 07:01:17 rails.1 | terminated by SIGTERM staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:17 nginx.1 | exited with code 1 staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:17 system | sending SIGTERM to all processes staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:16 nginx.1 | 2023/07/29 07:01:16 [emerg] 20#20: open() "/usr/share/nginx/stdout" failed (13: Permission denied) staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:16 nginx.1 | 2023/07/29 07:01:16 [warn] 20#20: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1 staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:16 nginx.1 | started with pid 14 staging-web
July 29, 2023 at 09:01 (UTC+2:00) 07:01:16 rails.1 | started with pid 15
This is on AWS ECS. For good measure, the Dockerfile diff:
diff --git a/Dockerfile b/Dockerfile
index c7220c5..06a329e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -51,14 +51,14 @@ RUN apt-get update -qq && \
# configure nginx
RUN gem install foreman && \
sed -i 's|pid /run|pid /rails/tmp/pids|' /etc/nginx/nginx.conf && \
- sed -i 's/access_log\s.*;/access_log \/dev\/stdout;/' /etc/nginx/nginx.conf && \
- sed -i 's/error_log\s.*;/error_log \/dev\/stderr info;/' /etc/nginx/nginx.conf
+ sed -i 's/access_log\s.*;/access_log stdout;/' /etc/nginx/nginx.conf && \
+ sed -i 's/error_log\s.*;/error_log stderr info;/' /etc/nginx/nginx.conf
COPY <<-"EOF" /etc/nginx/sites-available/default
server {
listen 3000 default_server;
listen [::]:3000 default_server;
- access_log /dev/stdout;
+ access_log stdout;
root /rails/public;
@@ -92,7 +92,7 @@ RUN useradd rails --create-home --shell /bin/bash && \
USER rails:rails
# Deployment options
-ENV LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libjemalloc.so.2" \
+ENV LD_PRELOAD="libjemalloc.so.2" \
MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true" \
PORT="3001" \
RAILS_LOG_TO_STDOUT="1"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.