dockerfile-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7730245e044329345b271524027cd640794a3577c4b49d2a2ce47a3cf21c94c4
4
+ data.tar.gz: 88fe182e5b8ab19d9725391cfaf1c0010e9d89d7cf44a9e3618f680bbe700315
5
+ SHA512:
6
+ metadata.gz: 411539b040956ad9a1c437437aa36d2ed96a1769354162a2d8e57244c6a5b7dbf7fb1ff45efbd40f86da990b4741c01c6a871c84ac6be735104c4ab8ff39aa17
7
+ data.tar.gz: 06b7e3ac3225bca70269b8aae26dcb9e2f9846b911416a09f4af6f0be82137eebd7f365bf815e0ff1a6c0783a7b8d082cf1bf5856f9913e90bb349408868d60f
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2022 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ ## Purpose
2
+
3
+ Provide Rails generators to produce Dockerfiles and related files.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ # Run `rake release` to release a new version of the gem.
@@ -0,0 +1,75 @@
1
+ module DockerfileRails
2
+ module Scanner
3
+ def scan_rails_app
4
+
5
+ ### database ###
6
+
7
+ database = YAML.load_file('config/database.yml').
8
+ dig('production', 'adapter') rescue nil
9
+
10
+ if database == 'sqlite3'
11
+ @sqlite3 = true
12
+ elsif database == 'postgresql'
13
+ @postgresql = true
14
+ elsif database == 'mysql' or database == 'mysql2'
15
+ @mysql = true
16
+ end
17
+
18
+ ### ruby gems ###
19
+
20
+ @gemfile = []
21
+
22
+ if File.exist? 'Gemfile.lock'
23
+ parser = Bundler::LockfileParser.new(Bundler.read_file('Gemfile.lock'))
24
+ @gemfile += parser.specs.map { |spec, version| spec.name }
25
+ end
26
+
27
+ if File.exist? 'Gemfile'
28
+ @gemfile += Bundler::Definition.build('Gemfile', nil, []).dependencies.map(&:name)
29
+ end
30
+
31
+ @sidekiq = @gemfile.include? 'sidekiq'
32
+ @anycable = @gemfile.include? 'anycable-rails'
33
+ @rmagick = @gemfile.include? 'rmagick'
34
+ @vips = @gemfile.include? 'ruby-vips'
35
+ @bootstrap = @gemfile.include? 'bootstrap'
36
+ @puppeteer = @gemfile.include? 'puppeteer'
37
+ @bootsnap = @gemfile.include? 'bootsnap'
38
+
39
+ ### node modules ###
40
+
41
+ @package_json = []
42
+
43
+ if File.exist? 'package.json'
44
+ @package_json += JSON.load_file('package.json')['dependencies'].keys rescue []
45
+ end
46
+
47
+ @puppeteer ||= @package_json.include? 'puppeteer'
48
+
49
+ ### cable/redis ###
50
+
51
+ @cable = ! Dir['app/channels/*.rb'].empty?
52
+
53
+ if @cable
54
+ @redis_cable = true
55
+ if (YAML.load_file('config/cable.yml').dig('production', 'adapter') rescue '').include? 'any_cable'
56
+ @anycable = true
57
+ end
58
+ end
59
+
60
+ if (IO.read('config/environments/production.rb') =~ /redis/i rescue false)
61
+ @redis_cache = true
62
+ end
63
+
64
+ @redis = @redis_cable || @redis_cache || @sidekiq
65
+
66
+ ### api-only ###
67
+
68
+ @apionly = Rails.application.config.api_only
69
+
70
+ ### db:prepare ###
71
+
72
+ @dbprep = (Rails::VERSION::MAJOR >= 6) ? 'db:prepare' : 'db:migrate'
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ require 'rails'
2
+ require 'dockerfile-rails/scanner'
3
+
4
+ class DockerRailsRailtie < Rails::Railtie
5
+ end
@@ -0,0 +1,130 @@
1
+ class DockerfileGenerator < Rails::Generators::Base
2
+ include DockerfileRails::Scanner
3
+
4
+ def generate_app
5
+ source_paths.push File.expand_path('./templates', __dir__)
6
+
7
+ scan_rails_app
8
+
9
+ template 'Dockerfile.erb', 'Dockerfile'
10
+ template 'dockerignore.erb', '.dockerignore'
11
+
12
+ template 'node-version.erb', '.node-version' if using_node?
13
+
14
+ template 'docker-entrypoint.erb', 'bin/docker-entrypoint'
15
+ chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
16
+ end
17
+
18
+ private
19
+
20
+ def using_node?
21
+ File.exist? 'package.json'
22
+ end
23
+
24
+ def keeps?
25
+ return @keeps if @keeps != nil
26
+ @keeps = !Dir['**/.keep']
27
+ end
28
+
29
+ def build_packages
30
+ # start with the essentials
31
+ packages = %w(build-essential)
32
+
33
+ # add databases: sqlite3, postgres, mysql
34
+ packages += %w(pkg-config libpq-dev default-libmysqlclient-dev)
35
+
36
+ # add redis in case Action Cable, caching, or sidekiq are added later
37
+ packages << "redis"
38
+
39
+ # ActiveStorage preview support
40
+ packages << "libvips" if @gemfile.include? 'ruby-vips'
41
+
42
+ # node support, including support for building native modules
43
+ if using_node?
44
+ packages += %w(curl node-gyp) # pkg-config already listed above
45
+
46
+ # module build process depends on Python, and debian changed
47
+ # how python is installed with the bullseye release. Below
48
+ # is based on debian release included with the Ruby images on
49
+ # Dockerhub.
50
+ case Gem.ruby_version
51
+ when /^2.7/
52
+ bullseye = ruby_version >= "2.7.4"
53
+ when /^3.0/
54
+ bullseye = ruby_version >= "3.0.2"
55
+ else
56
+ bullseye = true
57
+ end
58
+
59
+ if bullseye
60
+ packages << "python-is-python3"
61
+ else
62
+ packages << "python"
63
+ end
64
+ end
65
+
66
+ packages.sort
67
+ end
68
+
69
+ def deploy_packages
70
+ # start with databases: sqlite3, postgres, mysql
71
+ packages = %w(libsqlite3-0 postgresql-client default-mysql-client)
72
+
73
+ # add redis in case Action Cable, caching, or sidekiq are added later
74
+ packages << "redis"
75
+
76
+ # ActiveStorage preview support
77
+ packages << "libvips" if @gemfile.include? 'ruby-vips'
78
+
79
+ packages.sort
80
+ end
81
+
82
+ def binfile_fixups
83
+ # binfiles may have OS specific paths to ruby. Normalize them.
84
+ shebangs = Dir["bin/*"].map { |file| IO.read(file).lines.first }.join
85
+ rubies = shebangs.scan(%r{#!/usr/bin/env (ruby.*)}).flatten.uniq
86
+
87
+ binfixups = (rubies - %w(ruby)).map do |ruby|
88
+ "sed -i 's/#{Regexp.quote(ruby)}$/ruby/' bin/*"
89
+ end
90
+
91
+ # Windows line endings will cause scripts to fail. If any
92
+ # or found OR this generation is run on a windows platform
93
+ # and there are other binfixups required, then convert
94
+ # line endings. This avoids adding unnecessary fixups if
95
+ # none are required, but prepares for the need to do the
96
+ # fix line endings if other fixups are required.
97
+ has_cr = Dir["bin/*"].any? { |file| IO.read(file).include? "\r" }
98
+ if has_cr || (Gem.win_platform? && !binfixups.empty?)
99
+ binfixups.unshift 'sed -i "s/\r$//g" bin/*'
100
+ end
101
+
102
+ # Windows file systems may not have the concept of executable.
103
+ # In such cases, fix up during the build.
104
+ unless Dir["bin/*"].all? { |file| File.executable? file }
105
+ binfixups.unshift "chmod +x bin/*"
106
+ end
107
+
108
+ binfixups
109
+ end
110
+
111
+ def node_version
112
+ using_node? and `node --version`[/\d+\.\d+\.\d+/]
113
+ rescue
114
+ "lts"
115
+ end
116
+
117
+ def yarn_version
118
+ using_node? and `yarn --version`[/\d+\.\d+\.\d+/]
119
+ rescue
120
+ "latest"
121
+ end
122
+
123
+ def depend_on_bootsnap?
124
+ @gemfile.include? 'bootstrap'
125
+ end
126
+
127
+ def api_only?
128
+ Rails.application.config.api_only
129
+ end
130
+ end
@@ -0,0 +1,81 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure it matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= Gem.ruby_version %>
5
+ FROM ruby:$RUBY_VERSION-slim as base
6
+
7
+ # Rails app lives here
8
+ WORKDIR /rails
9
+
10
+ # Set production environment
11
+ ENV RAILS_ENV="production" \
12
+ BUNDLE_PATH="vendor/bundle" \
13
+ BUNDLE_WITHOUT="development:test"
14
+
15
+
16
+ # Throw-away build stage to reduce size of final image
17
+ FROM base as build
18
+
19
+ # Install packages need to build gems<%= using_node? ? " and node modules" : "" %>
20
+ RUN apt-get update -qq && \
21
+ apt-get install -y <%= build_packages.join(" ") %>
22
+
23
+ <% if using_node? -%>
24
+ # Install JavaScript dependencies
25
+ ARG NODE_VERSION=<%= node_version %>
26
+ ARG YARN_VERSION=<%= yarn_version %>
27
+ ENV VOLTA_HOME="/usr/local"
28
+ RUN curl https://get.volta.sh | bash && \
29
+ volta install node@$NODE_VERSION yarn@$YARN_VERSION
30
+
31
+ <% end -%>
32
+ # Install application gems
33
+ COPY Gemfile Gemfile.lock ./
34
+ RUN bundle install
35
+
36
+ <% if using_node? -%>
37
+ # Install node modules
38
+ COPY package.json yarn.lock ./
39
+ RUN yarn install
40
+
41
+ <% end -%>
42
+ # Copy application code
43
+ COPY . .
44
+
45
+ <% if depend_on_bootsnap? -%>
46
+ # Precompile bootsnap code for faster boot times
47
+ RUN bundle exec bootsnap precompile --gemfile app/ lib/
48
+
49
+ <% end -%>
50
+ <% unless binfile_fixups.empty? -%>
51
+ # Adjust binfiles to be executable on Linux
52
+ <%= "RUN " + binfile_fixups.join(" && \\\n ") %>
53
+
54
+ <% end -%>
55
+ <% unless api_only? -%>
56
+ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
57
+ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
58
+
59
+ <% end -%>
60
+
61
+ # Final stage for app image
62
+ FROM base
63
+
64
+ # Install packages need for deployment
65
+ RUN apt-get update -qq && \
66
+ apt-get install --no-install-recommends -y <%= deploy_packages.join(" ") %> && \
67
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
68
+
69
+ # Copy built application from second stage
70
+ COPY --from=build /rails /rails
71
+
72
+ # Deployment options
73
+ ENV RAILS_LOG_TO_STDOUT="1" \
74
+ RAILS_SERVE_STATIC_FILES="true"
75
+
76
+ # Entrypoint prepares the database.
77
+ ENTRYPOINT ["/rails/bin/docker-entrypoint"]
78
+
79
+ # Start the server by default, this can be overwritten at runtime
80
+ EXPOSE 3000
81
+ CMD ["./bin/rails", "server"]
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ # If running the rails server then create or migrate existing database
4
+ if [ "${*}" == "./bin/rails server" ]; then
5
+ ./bin/rails db:prepare
6
+ fi
7
+
8
+ exec "${@}"
@@ -0,0 +1,45 @@
1
+ # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
2
+
3
+ # Ignore git directory.
4
+ /.git/
5
+
6
+ # Ignore bundler config.
7
+ /.bundle
8
+
9
+ # Ignore all default key files.
10
+ /config/master.key
11
+ /config/credentials/*.key
12
+
13
+ # Ignore all environment files.
14
+ /.env*
15
+ !/.env.example
16
+
17
+ # Ignore all logfiles and tempfiles.
18
+ /log/*
19
+ /tmp/*
20
+ <% if keeps? -%>
21
+ !/log/.keep
22
+ !/tmp/.keep
23
+
24
+ # Ignore pidfiles, but keep the directory.
25
+ /tmp/pids/*
26
+ !/tmp/pids/
27
+ !/tmp/pids/.keep
28
+ <% end -%>
29
+
30
+ # Ignore storage (uploaded files in development and any SQLite databases).
31
+ /storage/*
32
+ <% if keeps? -%>
33
+ !/storage/.keep
34
+ /tmp/storage/*
35
+ !/tmp/storage/
36
+ !/tmp/storage/.keep
37
+ <% end -%>
38
+ <% unless options.api? -%>
39
+
40
+ # Ignore assets.
41
+ /node_modules/
42
+ /app/assets/builds/*
43
+ !/app/assets/builds/.keep
44
+ /public/assets
45
+ <% end -%>
@@ -0,0 +1 @@
1
+ <%= ENV["NODE_VERSION"] || node_version %>
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dockerfile-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sam Ruby
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: rubys@intertwingly.net
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - MIT-LICENSE
34
+ - README.md
35
+ - Rakefile
36
+ - lib/dockerfile-rails.rb
37
+ - lib/dockerfile-rails/scanner.rb
38
+ - lib/generators/dockerfile_generator.rb
39
+ - lib/generators/templates/Dockerfile.erb
40
+ - lib/generators/templates/docker-entrypoint.erb
41
+ - lib/generators/templates/dockerignore.erb
42
+ - lib/generators/templates/node-version.erb
43
+ homepage: https://github.com/rubys/docker-rails
44
+ licenses:
45
+ - MIT
46
+ metadata:
47
+ homepage_uri: https://github.com/rubys/docker-rails
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.4.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Dockerfile generator for Rails
67
+ test_files: []