dockerfile-rails 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -1
- data/lib/dockerfile-rails/scanner.rb +4 -9
- data/lib/generators/dockerfile_generator.rb +69 -7
- data/lib/generators/templates/Dockerfile.erb +65 -6
- data/lib/generators/templates/docker-compose.yml.erb +71 -0
- data/lib/generators/templates/docker-entrypoint.erb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 536685e13e342227e5d6af85e3d778539668bbdab81b5430902ae08286a57c62
|
4
|
+
data.tar.gz: a3155769a131089493ae0682e195f6108dd4c81d03c79c6774ce21af0eda04be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0547a5c9224213fdab9b99a2ca03e5aa411f086abb723b121561226079968e6da769f9acdf76ee123b1fbd57a64aa7d622c5dc44a48ab05717d9a523322955a1
|
7
|
+
data.tar.gz: 37923bd9eaa647b9ca44433ce374d30e0250799e7078669b180f2ac5734241dc7af757a58b12227de999d78e3d4171ae7e3e9ebbbf828e90f2d71184999fb8c7
|
data/README.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
1
|
## Purpose
|
2
2
|
|
3
|
-
Provide Rails generators to produce Dockerfiles and related files.
|
3
|
+
Provide Rails generators to produce Dockerfiles and related files.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```
|
8
|
+
bundle add dockerfile-rails
|
9
|
+
bin/rails generate dockerfile
|
10
|
+
```
|
11
|
+
|
12
|
+
General options:
|
13
|
+
|
14
|
+
* `--force` - overwrite existing files
|
15
|
+
* `--ci` - include test gems in deployed image
|
16
|
+
* `--cache` - use build caching to speed up builds
|
17
|
+
* `--parallel` - use multi-stage builds to install gems and node modules in parallel
|
18
|
+
* `--compose` - generate a `docker-compose.yml` file
|
19
|
+
|
20
|
+
Dependencies:
|
21
|
+
|
22
|
+
Generally the dockerfile generator will be able to determine what dependencies you
|
23
|
+
are actually using. But should you be using DATABASE_URL, for example, at runtime
|
24
|
+
additional support may be needed:
|
25
|
+
|
26
|
+
* `--mysql` - add mysql libraries
|
27
|
+
* `--posgresql` - add posgresql libraries
|
28
|
+
* `--redis` - add redis libraries
|
29
|
+
* `--sqlite3` - add sqlite3 libraries
|
@@ -18,6 +18,7 @@ module DockerfileRails
|
|
18
18
|
### ruby gems ###
|
19
19
|
|
20
20
|
@gemfile = []
|
21
|
+
@git = false
|
21
22
|
|
22
23
|
if File.exist? 'Gemfile.lock'
|
23
24
|
parser = Bundler::LockfileParser.new(Bundler.read_file('Gemfile.lock'))
|
@@ -25,7 +26,9 @@ module DockerfileRails
|
|
25
26
|
end
|
26
27
|
|
27
28
|
if File.exist? 'Gemfile'
|
28
|
-
|
29
|
+
gemfile_definition = Bundler::Definition.build('Gemfile', nil, [])
|
30
|
+
@gemfile += gemfile_definition.dependencies.map(&:name)
|
31
|
+
@git = !gemfile_definition.spec_git_paths.empty?
|
29
32
|
end
|
30
33
|
|
31
34
|
@sidekiq = @gemfile.include? 'sidekiq'
|
@@ -62,14 +65,6 @@ module DockerfileRails
|
|
62
65
|
end
|
63
66
|
|
64
67
|
@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
68
|
end
|
74
69
|
end
|
75
70
|
end
|
@@ -1,6 +1,30 @@
|
|
1
1
|
class DockerfileGenerator < Rails::Generators::Base
|
2
2
|
include DockerfileRails::Scanner
|
3
3
|
|
4
|
+
class_option :ci, type: :boolean, default: false,
|
5
|
+
desc: 'include test gems in bundle'
|
6
|
+
|
7
|
+
class_option :cache, type: :boolean, default: false,
|
8
|
+
desc: 'use build cache to speed up installs'
|
9
|
+
|
10
|
+
class_option :parallel, type: :boolean, default: false,
|
11
|
+
desc: 'use build stages to install gems and node modules in parallel'
|
12
|
+
|
13
|
+
class_option :compose, type: :boolean, default: false,
|
14
|
+
desc: 'generate a docker-compose.yml file'
|
15
|
+
|
16
|
+
class_option :redit, type: :boolean, default: false,
|
17
|
+
desc: 'include redis libraries'
|
18
|
+
|
19
|
+
class_option :sqlite3, aliases: '--sqlite', type: :boolean, default: false,
|
20
|
+
desc: 'include sqlite3 libraries'
|
21
|
+
|
22
|
+
class_option :postgresql, aliases: '--postgres', type: :boolean, default: false,
|
23
|
+
desc: 'include postgresql libraries'
|
24
|
+
|
25
|
+
class_option :mysql, type: :boolean, default: false,
|
26
|
+
desc: 'include mysql libraries'
|
27
|
+
|
4
28
|
def generate_app
|
5
29
|
source_paths.push File.expand_path('./templates', __dir__)
|
6
30
|
|
@@ -13,12 +37,23 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
13
37
|
|
14
38
|
template 'docker-entrypoint.erb', 'bin/docker-entrypoint'
|
15
39
|
chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
|
40
|
+
|
41
|
+
template 'docker-compose.yml.erb', 'docker-compose.yml'
|
16
42
|
end
|
17
43
|
|
18
44
|
private
|
19
45
|
|
20
46
|
def using_node?
|
21
|
-
|
47
|
+
return @using_node if @using_node != nil
|
48
|
+
@using_node = File.exist? 'package.json'
|
49
|
+
end
|
50
|
+
|
51
|
+
def using_redis?
|
52
|
+
options.redis? or @redis
|
53
|
+
end
|
54
|
+
|
55
|
+
def parallel?
|
56
|
+
using_node? && options.parallel
|
22
57
|
end
|
23
58
|
|
24
59
|
def keeps?
|
@@ -31,17 +66,22 @@ private
|
|
31
66
|
packages = %w(build-essential)
|
32
67
|
|
33
68
|
# add databases: sqlite3, postgres, mysql
|
34
|
-
packages
|
69
|
+
packages << 'pkg-config' if options.sqlite3? or @sqlite3
|
70
|
+
packages << 'libpq-dev' if options.postgresql? or @postgresql
|
71
|
+
packages << 'default-libmysqlclient-dev' if options.mysql or @mysql
|
72
|
+
|
73
|
+
# add git if needed to install gems
|
74
|
+
packages << 'git' if @git
|
35
75
|
|
36
76
|
# add redis in case Action Cable, caching, or sidekiq are added later
|
37
|
-
packages << "redis"
|
77
|
+
packages << "redis" if using_redis?
|
38
78
|
|
39
79
|
# ActiveStorage preview support
|
40
80
|
packages << "libvips" if @gemfile.include? 'ruby-vips'
|
41
81
|
|
42
82
|
# node support, including support for building native modules
|
43
83
|
if using_node?
|
44
|
-
packages += %w(curl node-gyp
|
84
|
+
packages += %w(curl node-gyp pkg-config)
|
45
85
|
|
46
86
|
# module build process depends on Python, and debian changed
|
47
87
|
# how python is installed with the bullseye release. Below
|
@@ -63,15 +103,19 @@ private
|
|
63
103
|
end
|
64
104
|
end
|
65
105
|
|
66
|
-
packages.sort
|
106
|
+
packages.sort.uniq
|
67
107
|
end
|
68
108
|
|
69
109
|
def deploy_packages
|
110
|
+
packages = []
|
111
|
+
|
70
112
|
# start with databases: sqlite3, postgres, mysql
|
71
|
-
packages
|
113
|
+
packages << 'libsqlite3-0' if options.sqlite3? or @sqlite3
|
114
|
+
packages << 'postgresql-client' if options.postgresql? or @postgresql
|
115
|
+
packages << 'default-mysql-client' if options.mysql or @mysql
|
72
116
|
|
73
117
|
# add redis in case Action Cable, caching, or sidekiq are added later
|
74
|
-
packages << "redis"
|
118
|
+
packages << "redis" if using_redis?
|
75
119
|
|
76
120
|
# ActiveStorage preview support
|
77
121
|
packages << "libvips" if @gemfile.include? 'ruby-vips'
|
@@ -108,6 +152,16 @@ private
|
|
108
152
|
binfixups
|
109
153
|
end
|
110
154
|
|
155
|
+
def deploy_database
|
156
|
+
if options.postgresql? or @postgresql
|
157
|
+
'postgresql'
|
158
|
+
elsif options.mysql or @mysql
|
159
|
+
'mysql'
|
160
|
+
else
|
161
|
+
'sqlite3'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
111
165
|
def node_version
|
112
166
|
using_node? and `node --version`[/\d+\.\d+\.\d+/]
|
113
167
|
rescue
|
@@ -127,4 +181,12 @@ private
|
|
127
181
|
def api_only?
|
128
182
|
Rails.application.config.api_only
|
129
183
|
end
|
184
|
+
|
185
|
+
def dbprep_command
|
186
|
+
if Rails::VERSION::MAJOR >= 6
|
187
|
+
'db:prepare'
|
188
|
+
else
|
189
|
+
'db:migrate'
|
190
|
+
end
|
191
|
+
end
|
130
192
|
end
|
@@ -10,16 +10,31 @@ WORKDIR /rails
|
|
10
10
|
# Set production environment
|
11
11
|
ENV RAILS_ENV="production" \
|
12
12
|
BUNDLE_PATH="vendor/bundle" \
|
13
|
-
BUNDLE_WITHOUT="development:test"
|
13
|
+
BUNDLE_WITHOUT="<%= options.ci? ? 'test' : 'development:test' %>"
|
14
14
|
|
15
|
+
ARG BUNDLER_VERSION=<%= Bundler::VERSION %>
|
16
|
+
RUN gem update --system --no-document && \
|
17
|
+
gem install -N bundler -v ${BUNDLER_VERSION}
|
15
18
|
|
16
|
-
|
17
|
-
|
19
|
+
|
20
|
+
# Throw-away build stage<%= parallel? ? 's' : '' %> to reduce size of final image
|
21
|
+
FROM base as <%= parallel? ? 'pre' : '' %>build
|
18
22
|
|
19
23
|
# Install packages need to build gems<%= using_node? ? " and node modules" : "" %>
|
24
|
+
<% if options.cache? %>
|
25
|
+
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
26
|
+
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
27
|
+
apt-get update -qq && \
|
28
|
+
<% else -%>
|
20
29
|
RUN apt-get update -qq && \
|
30
|
+
<% end -%>
|
21
31
|
apt-get install -y <%= build_packages.join(" ") %>
|
22
32
|
|
33
|
+
<% if parallel? -%>
|
34
|
+
|
35
|
+
FROM prebuild as node
|
36
|
+
|
37
|
+
<% end -%>
|
23
38
|
<% if using_node? -%>
|
24
39
|
# Install JavaScript dependencies
|
25
40
|
ARG NODE_VERSION=<%= node_version %>
|
@@ -28,15 +43,47 @@ ENV VOLTA_HOME="/usr/local"
|
|
28
43
|
RUN curl https://get.volta.sh | bash && \
|
29
44
|
volta install node@$NODE_VERSION yarn@$YARN_VERSION
|
30
45
|
|
46
|
+
<% end -%>
|
47
|
+
<% if parallel? -%>
|
48
|
+
# Install node modules
|
49
|
+
COPY package.json yarn.lock ./
|
50
|
+
<% if options.cache? -%>
|
51
|
+
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
52
|
+
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
53
|
+
<% else -%>
|
54
|
+
RUN yarn install
|
55
|
+
<% end -%>
|
56
|
+
|
57
|
+
|
58
|
+
FROM prebuild as build
|
59
|
+
|
31
60
|
<% end -%>
|
32
61
|
# Install application gems
|
33
62
|
COPY Gemfile Gemfile.lock ./
|
34
|
-
|
63
|
+
<% if options.cache? -%>
|
64
|
+
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
|
65
|
+
bundle config set app_config .bundle && \
|
66
|
+
bundle config set path /srv/vendor && \
|
67
|
+
bundle _${BUNDLER_VERSION}_ install && \
|
68
|
+
bundle clean && \
|
69
|
+
mkdir -p vendor && \
|
70
|
+
bundle config set path vendor && \
|
71
|
+
cp -ar /srv/vendor .
|
72
|
+
<% else -%>
|
73
|
+
RUN bundle _${BUNDLER_VERSION}_ install
|
74
|
+
<% end -%>
|
35
75
|
|
36
|
-
<% if
|
76
|
+
<% if parallel? -%>
|
77
|
+
asdf
|
78
|
+
<% elsif using_node? -%>
|
37
79
|
# Install node modules
|
38
80
|
COPY package.json yarn.lock ./
|
81
|
+
<% if options.cache? -%>
|
82
|
+
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
83
|
+
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
84
|
+
<% else -%>
|
39
85
|
RUN yarn install
|
86
|
+
<% end -%>
|
40
87
|
|
41
88
|
<% end -%>
|
42
89
|
# Copy application code
|
@@ -54,19 +101,31 @@ RUN bundle exec bootsnap precompile --gemfile app/ lib/
|
|
54
101
|
<% end -%>
|
55
102
|
<% unless api_only? -%>
|
56
103
|
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
|
57
|
-
RUN
|
104
|
+
RUN SECRET_KEY_BASE<%= Rails::VERSION::MAJOR<7 || Rails::VERSION::STRING.start_with?('7.0') ? '=DUMMY' : '_DUMMY=1' %> ./bin/rails assets:precompile
|
58
105
|
|
59
106
|
<% end -%>
|
60
107
|
|
61
108
|
# Final stage for app image
|
62
109
|
FROM base
|
110
|
+
<% unless deploy_packages.empty? -%>
|
63
111
|
|
64
112
|
# Install packages need for deployment
|
113
|
+
<% if options.cache? -%>
|
114
|
+
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
115
|
+
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
116
|
+
apt-get update -qq && \
|
117
|
+
apt-get install --no-install-recommends -y <%= deploy_packages.join(" ") %>
|
118
|
+
<% else -%>
|
65
119
|
RUN apt-get update -qq && \
|
66
120
|
apt-get install --no-install-recommends -y <%= deploy_packages.join(" ") %> && \
|
67
121
|
rm -rf /var/lib/apt/lists /var/cache/apt/archives
|
122
|
+
<% end -%>
|
123
|
+
<% end -%>
|
68
124
|
|
69
125
|
# Copy built application from second stage
|
126
|
+
<% if options.ci? -%>
|
127
|
+
COPY --from=build /usr/local/bundle /usr/local/bundle
|
128
|
+
<% end -%>
|
70
129
|
COPY --from=build /rails /rails
|
71
130
|
|
72
131
|
# Deployment options
|
@@ -0,0 +1,71 @@
|
|
1
|
+
version: "3.8"
|
2
|
+
services:
|
3
|
+
web:
|
4
|
+
build: .
|
5
|
+
ports:
|
6
|
+
- "3000:3000"
|
7
|
+
environment:
|
8
|
+
- RAILS_MASTER_KEY=$RAILS_MASTER_KEY
|
9
|
+
<% if using_redis? -%>
|
10
|
+
- REDIS_URL=redis://redis-db:6379
|
11
|
+
<% end -%>
|
12
|
+
<% if deploy_database == 'postgresql' -%>
|
13
|
+
- DATABASE_URL=postgres://root:password@postgres-db/
|
14
|
+
<% elsif deploy_database == 'mysql' -%>
|
15
|
+
- DATABASE_URL=mysql2://root:password@mysql-db/
|
16
|
+
<% end -%>
|
17
|
+
<% if deploy_database == 'sqlite3' -%>
|
18
|
+
volumes:
|
19
|
+
- ./db:/rails/db
|
20
|
+
<% end -%>
|
21
|
+
<% if using_redis? or deploy_database != 'sqlite3' -%>
|
22
|
+
depends_on:
|
23
|
+
<% if using_redis? -%>
|
24
|
+
redis-db:
|
25
|
+
condition: service_started
|
26
|
+
<% end -%>
|
27
|
+
<% if deploy_database == 'postgresql' -%>
|
28
|
+
postgres-db:
|
29
|
+
condition: service_healthy
|
30
|
+
<% elsif deploy_database == 'mysql' -%>
|
31
|
+
mysql-db:
|
32
|
+
condition: service_healthy
|
33
|
+
<% end -%>
|
34
|
+
<% if deploy_database == 'postgresql' -%>
|
35
|
+
|
36
|
+
postgres-db:
|
37
|
+
image: postgres
|
38
|
+
environment:
|
39
|
+
POSTGRES_USER: root
|
40
|
+
POSTGRES_PASSWORD: password
|
41
|
+
volumes:
|
42
|
+
- ./tmp/db:/var/lib/postgresql/data
|
43
|
+
ports:
|
44
|
+
- "5432:5432"
|
45
|
+
healthcheck:
|
46
|
+
test: pg_isready
|
47
|
+
interval: 2s
|
48
|
+
timeout: 5s
|
49
|
+
retries: 30
|
50
|
+
<% elsif deploy_database == 'mysql' -%>
|
51
|
+
|
52
|
+
mysql-db:
|
53
|
+
image: mysql
|
54
|
+
command:
|
55
|
+
- --default-authentication-plugin=mysql_native_password
|
56
|
+
environment:
|
57
|
+
MYSQL_ROOT_PASSWORD: password
|
58
|
+
volumes:
|
59
|
+
- ./tmp/db:/var/lib/mysql
|
60
|
+
healthcheck:
|
61
|
+
test: mysqladmin ping -h 127.0.0.1 -u root --password=password
|
62
|
+
interval: 2s
|
63
|
+
timeout: 5s
|
64
|
+
retries: 30
|
65
|
+
<% end -%>
|
66
|
+
<% end -%>
|
67
|
+
<% if using_redis? -%>
|
68
|
+
|
69
|
+
redis-db:
|
70
|
+
image: redis
|
71
|
+
<% end -%>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dockerfile-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- lib/dockerfile-rails/scanner.rb
|
38
38
|
- lib/generators/dockerfile_generator.rb
|
39
39
|
- lib/generators/templates/Dockerfile.erb
|
40
|
+
- lib/generators/templates/docker-compose.yml.erb
|
40
41
|
- lib/generators/templates/docker-entrypoint.erb
|
41
42
|
- lib/generators/templates/dockerignore.erb
|
42
43
|
- lib/generators/templates/node-version.erb
|