boxing 0.4.1 → 0.6.2

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: fe3d343131564fde7cf4de0e29e3ef500be4107eee0893855473f6efc958eaf5
4
- data.tar.gz: a2d34fe4ce57859dc44b20ddcd77026f07f24ea25b77d54a15ab6980c1d06817
3
+ metadata.gz: bc21028b8c1cec59fa65a7625960e5148558949307af4ca0a67c113de3c13384
4
+ data.tar.gz: f31e60e67183097d525671bf03314083e0f0616a4d6069c87005fbc5c069fd29
5
5
  SHA512:
6
- metadata.gz: 37e4a71b5784d2226b0ce46267f299b968a0307930eea655303c1050d7861fcc9ece58e50f8018ac10e243258b22b96e12261a5ff91b99f95c1d9b403643957d
7
- data.tar.gz: 20ec4384c3be3fbd1f904cd1911aab41c95aa100f1cef6f243a245b1697865131e114ef878a31fca4f88e6f5119edf558986d2c9a669e05a5be1060b65b3f90e
6
+ metadata.gz: 0eddac800256df2f53666810539c6347703274bde008d7043309d096b27a7c083fd96a6ab854a84c0354b8387532689a8cc612da06ed310cc6a5c97b0f3d73ff
7
+ data.tar.gz: de2c527ba2ce831900bf5942872b169faae0cb0b5fb4f931fecc7083745a7f5ab5b3631ce0f40380efeb5e0e650c2d7d8695c123aa019a613c267f6b593e1713
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boxing (0.4.1)
4
+ boxing (0.6.2)
5
5
  bundler (~> 2.0)
6
6
  thor (~> 1.0)
7
7
 
data/README.md CHANGED
@@ -78,18 +78,86 @@ 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
@@ -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
@@ -22,7 +29,7 @@ module Boxing
22
29
  def packages
23
30
  @packages ||=
24
31
  Set
25
- .new(default_packages)
32
+ .new(default_packages + extra_packages)
26
33
  .merge(
27
34
  @dependencies
28
35
  .map(&:name)
@@ -60,9 +67,35 @@ module Boxing
60
67
  Package.new('build-base', mode: Package::BUILD)
61
68
  ]
62
69
  .push(git? ? Package.new('git', mode: Package::BUILD) : nil)
70
+ .push(has?('liveness') ? Package.new('curl', mode: Package::RUNTIME) : nil)
63
71
  .compact
64
72
  end
65
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
+
66
99
  # Convert to binding
67
100
  #
68
101
  # @return [Binding]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Boxing
4
- VERSION = '0.4.1'
4
+ VERSION = '0.6.2'
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,5 +1,6 @@
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
@@ -23,6 +24,29 @@ 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
 
@@ -39,10 +63,13 @@ RUN mkdir -p ${APP_ROOT}
39
63
  <%- if has?('rails') -%>
40
64
  ENV RAILS_ENV=production
41
65
  ENV RAILS_LOG_TO_STDOUT=true
66
+ ENV RAILS_SERVE_STATIC_FILES=yes
42
67
  <%- end -%>
43
68
  ENV APP_ROOT=$APP_ROOT
44
69
 
45
70
  COPY . ${APP_ROOT}
71
+ <%- if config.assets_precompile -%>COPY --from=assets /${APP_ROOT}/public /${APP_ROOT}/public
72
+ <%- end -%>
46
73
 
47
74
  ARG REVISION
48
75
  ENV REVISION $REVISION
@@ -60,7 +87,10 @@ RUN adduser -h ${APP_ROOT} -D -s /bin/nologin ruby ruby && \
60
87
  USER ruby
61
88
  WORKDIR ${APP_ROOT}
62
89
 
63
- EXPOSE <%= has?('rails') ? '3000' : '9292' %>
90
+ EXPOSE <%= config.port %>
91
+ <%- if has?('liveness') || config.health_check -%>
92
+ HEALTHCHECK CMD curl -f http://localhost:<%= config.port %><%= config.health_check_path %> || exit 1
93
+ <%- end -%>
64
94
  <%- if has?('openbox') -%>
65
95
  ENTRYPOINT ["bin/openbox"]
66
96
  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
@@ -29,7 +29,19 @@ rspec.xml
29
29
  # Rails
30
30
  log/*
31
31
  tmp/*
32
+ /config/master.key
33
+
34
+ # Frontend
35
+ node_modules/
32
36
 
33
37
  # Licensed
34
38
  .licensed.yml
35
39
  .licenses
40
+
41
+ # Boxing
42
+ config/boxing.rb
43
+ <% if config.ignores -%>
44
+
45
+ # Customize Ignores
46
+ <%= Array[config.ignores].join("\n") %>
47
+ <%- 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.4.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - 蒼時弦也
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-30 00:00:00.000000000 Z
11
+ date: 2022-02-21 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: []