boxing 0.3.1 → 0.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc45fc502d0e92045969b463a8371bfd70c0375903be656554d0b0523a4e54db
4
- data.tar.gz: 2f65fa15db1b98e7f2c8b58c592fdef26feb484408d1bdc75329f882b0561f6c
3
+ metadata.gz: cd1ab96ae737b37be480b3d7d862a5925b951062f7ccae22eb200d26e55f3a14
4
+ data.tar.gz: 8cd2271e0cb3fc6736c2440f978bdee63b0ba43c90a57596f9064f5b576788ae
5
5
  SHA512:
6
- metadata.gz: b3d12460d64bd448880826172ea91393f58ea1b2e44178ae343da1ca2023909a45b2ff1d3c7afc5efcb7b8f0657c8f99d2490d633638cfef45ae2f28ecb176c5
7
- data.tar.gz: 0c8ba08ef084fe5881e8cb90b54ff1d9486abe2de905d21103346b4e445962dbe488c714aac8fe8d599319036d795fd0ac4cef9e9db83680b331e8106fe4e721
6
+ metadata.gz: 0c4c43055ed9973e21b4e1660fff4bc5f6cd870f08f82339a0ea88be4edde2914c2e37086a5bf92a48e493c12fb2ba20c68bb28c936fcd2e3f77a6fe5e5edf29
7
+ data.tar.gz: 25dd924fc89a7aa20361acbcdc2c52b0e320c007308ac1a79a227df9938c2b575f7ee468a0dac1dd5cda8d17a820ea0c6e2fcb18de3ad7e7c15c5fa8746205cd
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boxing (0.3.1)
4
+ boxing (0.6.0)
5
5
  bundler (~> 2.0)
6
6
  thor (~> 1.0)
7
7
 
data/README.md CHANGED
@@ -78,21 +78,90 @@ bundle exec boxing update
78
78
 
79
79
  > If the generated `Dockerfile` is not satisfy, please try to update it.
80
80
 
81
+ ## Configuration
82
+
83
+ If `config/boxing.rb` is found, it will be loaded and change the generated `Dockerfile` and `.dockerignore`
84
+
85
+ ### Source Code Root
86
+
87
+ ```ruby
88
+ Boxing.config do |c|
89
+ c.root = '/var/www'
90
+ end
91
+ ```
92
+
93
+ ### Ignore Files
94
+
95
+ ```ruby
96
+ Boxing.config do |c|
97
+ c.ignores = %w[
98
+ vendor/gems
99
+ ]
100
+ end
101
+ ```
102
+
103
+ ### Extra Packages
104
+
105
+ ```ruby
106
+ Boxing.config do |c|
107
+ c.build_packages = %w[nodejs]
108
+ c.runtime_packages = %w[git]
109
+ end
110
+ ```
111
+
112
+ ### Assets Precompile
113
+
114
+ This feature is disabled by default and suggest to use CI to build it.
115
+
116
+ ```ruby
117
+ Boxing.config do |c|
118
+ c.assets_precompile = true
119
+ # If not given the `node -v` will be execute
120
+ c.node_version = '14.18'
121
+ end
122
+ ```
123
+
124
+ ### Health Check
125
+
126
+ ```ruby
127
+ Boxing.config do |c|
128
+ c.health_check = true
129
+ c.health_check_path = '/api/status.json'
130
+ end
131
+ ```
132
+
133
+ > If `liveness` gem is installed, the health check will enabled by default with `/status` path.
134
+
81
135
  ## Roadmap
82
136
 
83
137
  * [x] `Dockerfile` generator
84
- * [x] `.gitignore` generator
138
+ * [x] `.dockerignore` generator
85
139
  * [x] Common ignore files
86
- * [ ] Customizable ignore files
87
- * [ ] Customize config file `config/boxing.rb`
88
- * [ ] Entrypoint Detection
89
- * [x] Openbox (Suggested)
140
+ * [x] Customizable ignore files
141
+ * [ ] Docker Compose generator
142
+ * [ ] Production Version
143
+ * [x] Development Version
144
+ * [x] Allow run Assets Precompile in Container
145
+ * [ ] Disable `RAILS_SERVE_STATIC_FILES` by default
146
+ * [x] Customize config file `config/boxing.rb`
147
+ * [x] Customize `APP_ROOT`
148
+ * [ ] Extra packages
149
+ * [ ] DSL to customize `Dockerfile`
150
+ * [ ] Build Stage
151
+ * [ ] Entrypoint
152
+ * [ ] Command
153
+ * [x] Expose Port
154
+ * [x] Health Check
155
+ * [x] [Liveness](https://github.com/elct9620/openbox) gem detection
156
+ * [x] Add `curl` for web application
157
+ * [x] Entrypoint Detection
158
+ * [x] [Openbox](https://github.com/elct9620/openbox) (Suggested)
90
159
  * [x] Ruby on Rails
91
- * [ ] Rack
92
- * [ ] Ruby
160
+ * [x] Rack (Default)
93
161
  * [ ] Package Database
94
162
  * [x] Built-in (Move to standalone repoistory in future)
95
163
  * [x] Standalone Repoistory
164
+ * [x] Support gems from `git` repoistory
96
165
  * [x] Customize Source
97
166
  * [ ] Base Image
98
167
  * [x] Alpine
@@ -12,7 +12,9 @@ module Boxing
12
12
  true
13
13
  end
14
14
 
15
+ require_relative 'commands/base'
15
16
  require_relative 'commands/generate'
17
+ require_relative 'commands/compose'
16
18
  require_relative 'commands/update'
17
19
  end
18
20
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Boxing
4
+ # :nodoc:
5
+ module Commands
6
+ # The Base Command
7
+ #
8
+ # @since 0.5.0
9
+ class Base < Thor::Group
10
+ include Thor::Actions
11
+
12
+ # :nodoc:
13
+ def self.source_root
14
+ Pathname.new(File.dirname(__FILE__)).join('../../..')
15
+ end
16
+
17
+ # Prepare command environment
18
+ #
19
+ # @since 0.5.0
20
+ def prepare
21
+ config = Bundler.root.join('config/boxing.rb')
22
+ return unless config.exist?
23
+
24
+ load config
25
+ end
26
+
27
+ private
28
+
29
+ # :nodoc:
30
+ def context
31
+ @context = Context.new(
32
+ Boxing.config,
33
+ Database.new,
34
+ Boxing.dependencies
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Boxing
4
+ # :nodoc:
5
+ module Commands
6
+ # The Docker Compose Generator
7
+ #
8
+ # @since 0.1.0
9
+ class Compose < Base
10
+ # Create Dockerfile
11
+ #
12
+ # @since 0.1.0
13
+ def execute
14
+ Database.download! unless Database.exist?
15
+
16
+ # TODO: Allow set image registry
17
+ # TODO: Allow set application name
18
+ template('templates/docker-compose.yml.tt', 'docker-compose.yml', context: context.to_binding)
19
+ end
20
+ end
21
+
22
+ Boxing::Command.register(Compose, 'compose', 'compose', 'Generate docker-compose.yml')
23
+ end
24
+ end
@@ -9,14 +9,7 @@ module Boxing
9
9
  # The Dockerfle Generator
10
10
  #
11
11
  # @since 0.1.0
12
- class Generate < Thor::Group
13
- include Thor::Actions
14
-
15
- # :nodoc:
16
- def self.source_root
17
- Pathname.new(File.dirname(__FILE__)).join('../../..')
18
- end
19
-
12
+ class Generate < Base
20
13
  # Create Dockerfile
21
14
  #
22
15
  # @since 0.1.0
@@ -26,15 +19,6 @@ module Boxing
26
19
  template('templates/Dockerfile.tt', 'Dockerfile', context: context.to_binding)
27
20
  template('templates/dockerignore.tt', '.dockerignore', context: context.to_binding)
28
21
  end
29
-
30
- private
31
-
32
- def context
33
- @context = Context.new(
34
- Database.new,
35
- Boxing.dependencies
36
- )
37
- end
38
22
  end
39
23
 
40
24
  Boxing::Command.register(Generate, 'generate', 'generate', 'Generate Dockerfile')
@@ -6,7 +6,7 @@ module Boxing
6
6
  # The Database Updater
7
7
  #
8
8
  # @since 0.3.0
9
- class Update < Thor::Group
9
+ class Update < Base
10
10
  # Update Database
11
11
  #
12
12
  # @since 0.3.0
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Boxing
4
+ # The config of boxing
5
+ #
6
+ # @since 0.5.0
7
+ class Config
8
+ # @!attribute root
9
+ # @return [String] the application root
10
+ #
11
+ # @since 0.5.0
12
+ attr_accessor :root, :name, :registry, :ignores, :port,
13
+ :health_check, :health_check_path,
14
+ :assets_precompile, :node_version,
15
+ :build_packages, :runtime_packages
16
+
17
+ # @since 0.5.0
18
+ def initialize(&block)
19
+ @name = 'myapp'
20
+ @root = '/srv/app'
21
+ @port = 9292
22
+ @health_path = '/status'
23
+ @assets_precompile = false
24
+
25
+ instance_exec(self, &block) if defined?(yield)
26
+ end
27
+ end
28
+ end
@@ -5,13 +5,20 @@ module Boxing
5
5
  #
6
6
  # @since 0.1.0
7
7
  class Context
8
+ # @since 0.5.0
9
+ attr_reader :config
10
+
11
+ # @param config [Boxing::Config]
8
12
  # @param database [Boxing::Database]
9
13
  # @param dependencies [Array<Bundler::Dependency>]
10
14
  #
11
15
  # @since 0.1.0
12
- def initialize(database, dependencies = [])
16
+ def initialize(config, database, dependencies = [])
17
+ @config = config
13
18
  @database = database
14
19
  @dependencies = dependencies
20
+
21
+ @config.port = 3000 if has?('rails')
15
22
  end
16
23
 
17
24
  # Return required packages
@@ -20,11 +27,14 @@ module Boxing
20
27
  #
21
28
  # @since 0.1.0
22
29
  def packages
23
- @packages ||= Set.new(
24
- @dependencies
25
- .map(&:name)
26
- .flat_map { |name| @database.package_for(name).to_a }
27
- )
30
+ @packages ||=
31
+ Set
32
+ .new(default_packages + extra_packages)
33
+ .merge(
34
+ @dependencies
35
+ .map(&:name)
36
+ .flat_map { |name| @database.package_for(name).to_a }
37
+ )
28
38
  end
29
39
 
30
40
  # Check rubygems exists
@@ -38,6 +48,54 @@ module Boxing
38
48
  @dependencies.any? { |dep| names.include?(dep.name) }
39
49
  end
40
50
 
51
+ # Does any gem from git
52
+ #
53
+ # @return [TrueClass|FalseClass]
54
+ #
55
+ # @since 0.4.0
56
+ def git?
57
+ @dependencies.any?(&:git)
58
+ end
59
+
60
+ # Default packages
61
+ #
62
+ # @return [Array<Boxing::Package>]
63
+ #
64
+ # @since 0.4.0
65
+ def default_packages
66
+ [
67
+ Package.new('build-base', mode: Package::BUILD)
68
+ ]
69
+ .push(git? ? Package.new('git', mode: Package::BUILD) : nil)
70
+ .push(has?('liveness') ? Package.new('curl', mode: Package::RUNTIME) : nil)
71
+ .compact
72
+ end
73
+
74
+ # Extra Packages
75
+ #
76
+ # @return [Array<Boxing::Package>]
77
+ #
78
+ # @since 0.6.0
79
+ def extra_packages
80
+ Array[config.build_packages, config.runtime_packages].compact.flat_map do |name|
81
+ mode = 0
82
+ mode |= Package::BUILD if config.build_packages&.include?(name)
83
+ mode |= Package::RUNTIME if config.runtime_packages&.include?(name)
84
+ Package.new(name, mode: mode)
85
+ end
86
+ end
87
+
88
+ # Return node.js version
89
+ #
90
+ # @return [String]
91
+ #
92
+ # @since 0.6.0
93
+ def node_version
94
+ return config.node_version if config.node_version
95
+
96
+ `node -v`.gsub(/^v/, '')
97
+ end
98
+
41
99
  # Convert to binding
42
100
  #
43
101
  # @return [Binding]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Boxing
4
- VERSION = '0.3.1'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/boxing.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'boxing/version'
4
+ require_relative 'boxing/config'
4
5
  require_relative 'boxing/package'
5
6
  require_relative 'boxing/database'
6
7
  require_relative 'boxing/context'
@@ -10,6 +11,8 @@ require_relative 'boxing/command'
10
11
  #
11
12
  # @since 0.1.0
12
13
  module Boxing
14
+ LOCK = Mutex.new
15
+
13
16
  module_function
14
17
 
15
18
  # @return [Bundler::Dependency]
@@ -21,4 +24,19 @@ module Boxing
21
24
  .current_dependencies
22
25
  .select { |dep| (dep.groups & groups).any? }
23
26
  end
27
+
28
+ # @return [Boxing::Config]
29
+ #
30
+ # @since 0.5.0
31
+ def config(&block)
32
+ return @config if @config
33
+
34
+ LOCK.synchronize do
35
+ return @config if @config
36
+
37
+ @config = Config.new(&block)
38
+ end
39
+
40
+ @config
41
+ end
24
42
  end
@@ -1,10 +1,11 @@
1
- ARG APP_ROOT=/src/app
1
+ ARG APP_ROOT=<%= config.root %>
2
2
  ARG RUBY_VERSION=<%= RUBY_VERSION %>
3
+ <%- if config.assets_precompile -%>ARG NODE_VERSION=<%= node_version %><%- end -%>
3
4
 
4
5
  FROM ruby:${RUBY_VERSION}-alpine AS gem
5
6
  ARG APP_ROOT
6
7
 
7
- RUN apk add --no-cache build-base <%= packages.select(&:build?).join(' ') %>
8
+ RUN apk add --no-cache <%= packages.select(&:build?).join(' ') %>
8
9
 
9
10
  RUN mkdir -p ${APP_ROOT}
10
11
  COPY Gemfile Gemfile.lock ${APP_ROOT}/
@@ -23,15 +24,35 @@ RUN gem install bundler:<%= Bundler::VERSION %> \
23
24
  && find /usr/local/bundle -type f -name '*.o' -delete \
24
25
  && rm -rf /usr/local/bundle/cache/*.gem
25
26
 
27
+ <%- if config.assets_precompile -%>
28
+ FROM node:${NODE_VERSION}-alpine as node
29
+ FROM ruby:${RUBY_VERSION}-alpine as assets
30
+ ARG APP_ROOT
31
+
32
+ <%- if packages.select(&:runtime?).any? -%>
33
+ RUN apk add --no-cache <%= packages.select(&:runtime?).join(' ') %> yarn
34
+
35
+ <%- end -%>
36
+ COPY --from=node /usr/local/bin/node /usr/local/bin/node
37
+
38
+ COPY --from=gem /usr/local/bundle/config /usr/local/bundle/config
39
+ COPY --from=gem /usr/local/bundle /usr/local/bundle
40
+ COPY --from=gem /${APP_ROOT}/vendor/bundle /${APP_ROOT}/vendor/bundle
41
+
42
+ RUN mkdir -p ${APP_ROOT}
43
+ COPY . ${APP_ROOT}
44
+
45
+ ENV RAILS_ENV production
46
+ WORKDIR ${APP_ROOT}
47
+ RUN bundle exec rake assets:precompile
48
+
49
+ <%- end -%>
26
50
  FROM ruby:${RUBY_VERSION}-alpine
27
51
  ARG APP_ROOT
28
52
 
29
53
  <%- if packages.select(&:runtime?).any? -%>
30
54
  RUN apk add --no-cache <%= packages.select(&:runtime?).join(' ') %>
31
55
 
32
- ARG REVISION
33
- ENV REVISION $REVISION
34
-
35
56
  <%- end -%>
36
57
  COPY --from=gem /usr/local/bundle/config /usr/local/bundle/config
37
58
  COPY --from=gem /usr/local/bundle /usr/local/bundle
@@ -42,10 +63,15 @@ RUN mkdir -p ${APP_ROOT}
42
63
  <%- if has?('rails') -%>
43
64
  ENV RAILS_ENV=production
44
65
  ENV RAILS_LOG_TO_STDOUT=true
66
+ ENV RAILS_SERVE_STATIC_FILES=yes
45
67
  <%- end -%>
46
68
  ENV APP_ROOT=$APP_ROOT
47
69
 
48
70
  COPY . ${APP_ROOT}
71
+ COPY --from=assets /${APP_ROOT}/public /${APP_ROOT}/public
72
+
73
+ ARG REVISION
74
+ ENV REVISION $REVISION
49
75
  RUN echo $REVISION > ${SERVER_ROOT}/REVISION
50
76
 
51
77
  # Apply Execute Permission
@@ -60,7 +86,10 @@ RUN adduser -h ${APP_ROOT} -D -s /bin/nologin ruby ruby && \
60
86
  USER ruby
61
87
  WORKDIR ${APP_ROOT}
62
88
 
63
- EXPOSE <%= has?('rails') ? '3000' : '9292' %>
89
+ EXPOSE <%= config.port %>
90
+ <%- if has?('liveness') || config.health_check -%>
91
+ HEALTHCHECK CMD curl -f http://localhost:<%= config.port %><%= config.health_check_path %> || exit 1
92
+ <%- end -%>
64
93
  <%- if has?('openbox') -%>
65
94
  ENTRYPOINT ["bin/openbox"]
66
95
  CMD ["server"]
@@ -0,0 +1,47 @@
1
+ version: '3.4'
2
+
3
+ volumes:
4
+ database:
5
+ driver: local
6
+
7
+ services:
8
+ <%- if has?('pg') -%>
9
+ postgres:
10
+ image: postgres:13.1
11
+ volumes:
12
+ - database:/var/lib/postgresql/data
13
+ environment:
14
+ - POSTGRES_DB=<%= config.name %>
15
+ - POSTGRES_USER=<%= config.name %>
16
+ - POSTGRES_PASSWORD=<%= config.name %>
17
+ <%- end -%>
18
+ <%- if has?('mysql2') -%>
19
+ mysql:
20
+ image: mysql:8.0
21
+ volumes:
22
+ - database:/var/lib/mysql
23
+ environment:
24
+ - MYSQL_USER=<%= config.name %>
25
+ - MYSQL_PASSWORD=<%= config.name %>
26
+ - MYSQL_DATABASE=<%= config.name %>
27
+ - MYSQL_ROOT_PASSWORD=<%= config.name %>
28
+ <%- end -%>
29
+ application:
30
+ <%- if config.registry.nil? -%>
31
+ build:
32
+ context: .
33
+ <%- else -%>
34
+ image: <%= config.registry %>
35
+ <%- end -%>
36
+ environment:
37
+ - RAILS_MASTER_KEY
38
+ - AUTO_MIGRATION=yes
39
+ <%- if has?('pg') -%>
40
+ - DATABASE_URL=postgres://<%= config.name %>:<%= config.name %>@postgres/<%= config.name %>
41
+ <%- elsif has?('mysql2') %>
42
+ - DATABASE_URL=mysql2://<%= config.name %>:<%= config.name %>@mysql/<%= config.name %>
43
+ <%- end -%>
44
+ ports:
45
+ - "3000:3000"
46
+ depends_on:
47
+ - postgres
@@ -8,8 +8,10 @@ docker-compose*.yml
8
8
  # CI/CD
9
9
  .github/
10
10
  .cache/
11
+ .circleci/
11
12
  coverage/
12
13
  spec/
14
+ test/
13
15
  features/
14
16
  .gitlab-ci.yml
15
17
  .travis.yml
@@ -28,6 +30,17 @@ rspec.xml
28
30
  log/*
29
31
  tmp/*
30
32
 
33
+ # Frontend
34
+ node_modules/
35
+
31
36
  # Licensed
32
37
  .licensed.yml
33
38
  .licenses
39
+
40
+ # Boxing
41
+ config/boxing.rb
42
+ <% if config.ignores -%>
43
+
44
+ # Customize Ignores
45
+ <%= Array[config.ignores].join("\n") %>
46
+ <%- end -%>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boxing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 蒼時弦也
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-29 00:00:00.000000000 Z
11
+ date: 2022-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,13 +60,17 @@ files:
60
60
  - exe/boxing
61
61
  - lib/boxing.rb
62
62
  - lib/boxing/command.rb
63
+ - lib/boxing/commands/base.rb
64
+ - lib/boxing/commands/compose.rb
63
65
  - lib/boxing/commands/generate.rb
64
66
  - lib/boxing/commands/update.rb
67
+ - lib/boxing/config.rb
65
68
  - lib/boxing/context.rb
66
69
  - lib/boxing/database.rb
67
70
  - lib/boxing/package.rb
68
71
  - lib/boxing/version.rb
69
72
  - templates/Dockerfile.tt
73
+ - templates/docker-compose.yml.tt
70
74
  - templates/dockerignore.tt
71
75
  homepage: https://github.com/elct9620/boxing
72
76
  licenses: []