dockerfile-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []