kuby-core 0.11.16 → 0.15.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/Gemfile +1 -2
  4. data/README.md +2 -1
  5. data/kuby-core.gemspec +1 -1
  6. data/lib/kuby/commands.rb +25 -73
  7. data/lib/kuby/docker/alpine.rb +2 -1
  8. data/lib/kuby/docker/app_image.rb +34 -0
  9. data/lib/kuby/docker/bundler_phase.rb +10 -0
  10. data/lib/kuby/docker/cli.rb +7 -13
  11. data/lib/kuby/docker/docker_uri.rb +50 -9
  12. data/lib/kuby/docker/errors.rb +1 -19
  13. data/lib/kuby/docker/image.rb +142 -0
  14. data/lib/kuby/docker/layer.rb +0 -7
  15. data/lib/kuby/docker/local_tags.rb +9 -10
  16. data/lib/kuby/docker/package_phase.rb +0 -5
  17. data/lib/kuby/docker/packages.rb +1 -0
  18. data/lib/kuby/docker/remote_tags.rb +10 -5
  19. data/lib/kuby/docker/setup_phase.rb +17 -9
  20. data/lib/kuby/docker/spec.rb +38 -62
  21. data/lib/kuby/docker/timestamp_tag.rb +8 -1
  22. data/lib/kuby/docker/timestamped_image.rb +114 -0
  23. data/lib/kuby/docker.rb +27 -25
  24. data/lib/kuby/environment.rb +1 -10
  25. data/lib/kuby/kubernetes/bare_metal_provider.rb +16 -4
  26. data/lib/kuby/kubernetes/deployer.rb +1 -1
  27. data/lib/kuby/kubernetes/docker_desktop_provider.rb +0 -15
  28. data/lib/kuby/kubernetes/spec.rb +21 -17
  29. data/lib/kuby/plugin.rb +2 -2
  30. data/lib/kuby/plugins/rails_app/assets.rb +62 -70
  31. data/lib/kuby/plugins/rails_app/assets_image.rb +57 -0
  32. data/lib/kuby/plugins/rails_app/generators/kuby.rb +31 -9
  33. data/lib/kuby/plugins/rails_app/plugin.rb +53 -236
  34. data/lib/kuby/plugins/rails_app.rb +1 -0
  35. data/lib/kuby/tasks.rb +98 -69
  36. data/lib/kuby/version.rb +1 -1
  37. data/lib/kuby.rb +2 -20
  38. data/spec/docker/spec_spec.rb +21 -118
  39. data/spec/docker/timestamped_image_spec.rb +123 -0
  40. data/spec/spec_helper.rb +10 -11
  41. metadata +10 -14
  42. data/lib/kuby/dev_setup.rb +0 -346
  43. data/lib/kuby/docker/dev_spec.rb +0 -202
  44. data/lib/kuby/docker/metadata.rb +0 -90
  45. data/lib/kuby/docker/tags.rb +0 -92
  46. data/lib/kuby/rails_commands.rb +0 -84
  47. data/spec/docker/metadata_spec.rb +0 -73
  48. data/spec/dummy/Gemfile.lock +0 -223
  49. data/spec/dummy/config/master.key +0 -1
  50. data/spec/dummy/tmp/cache/bootsnap-load-path-cache +0 -0
@@ -47,27 +47,23 @@ module Kuby
47
47
  environment.kubernetes.plugins[@database.plugin_name] = @database.plugin
48
48
  environment.kubernetes.add_plugin(:kube_db)
49
49
 
50
- unless environment.development?
51
- environment.docker do
52
- insert :rewrite_db_config, RewriteDbConfig.new, after: :copy_phase
53
- end
50
+ environment.docker do
51
+ insert :rewrite_db_config, RewriteDbConfig.new, after: :copy_phase
54
52
  end
55
53
  end
56
54
 
57
- unless environment.development?
58
- environment.kubernetes.add_plugin(:nginx_ingress)
59
- environment.kubernetes.add_plugin(:rails_assets) do
60
- asset_url context.asset_url
61
- packs_url context.packs_url
62
- asset_path context.asset_path
63
- end
55
+ environment.kubernetes.add_plugin(:nginx_ingress)
56
+ environment.kubernetes.add_plugin(:rails_assets) do
57
+ asset_url context.asset_url
58
+ packs_url context.packs_url
59
+ asset_path context.asset_path
60
+ end
64
61
 
65
- if @tls_enabled
66
- context = self
62
+ if @tls_enabled
63
+ context = self
67
64
 
68
- environment.kubernetes.add_plugin(:cert_manager) do
69
- email context.environment.docker.credentials.email
70
- end
65
+ environment.kubernetes.add_plugin(:cert_manager) do
66
+ email context.environment.docker.credentials.email
71
67
  end
72
68
  end
73
69
  end
@@ -79,14 +75,13 @@ module Kuby
79
75
  def before_deploy(manifest)
80
76
  # Make sure plugin has been configured. If not, do nothing.
81
77
  if cert_manager = environment.kubernetes.plugin(:cert_manager)
82
- cert_manager.annotate_ingress(ingress)
78
+ cert_manager.annotate_ingress(ingress) if tls_enabled
83
79
  end
84
80
 
85
- image_with_tag = "#{docker.metadata.image_url}:#{kubernetes.tag}"
81
+ image_with_tag = "#{docker.image.image_url}:#{kubernetes.tag || Kuby::Docker::LATEST_TAG}"
86
82
 
87
83
  if assets = environment.kubernetes.plugin(:rails_assets)
88
84
  assets.configure_ingress(ingress, hostname)
89
- assets.configure_deployment(deployment, image_with_tag)
90
85
  end
91
86
 
92
87
  spec = self
@@ -99,14 +94,12 @@ module Kuby
99
94
  image image_with_tag
100
95
  end
101
96
 
102
- unless spec.environment.development?
103
- init_container(:create_db) do
104
- image image_with_tag
105
- end
97
+ init_container(:create_db) do
98
+ image image_with_tag
99
+ end
106
100
 
107
- init_container(:migrate_db) do
108
- image image_with_tag
109
- end
101
+ init_container(:migrate_db) do
102
+ image image_with_tag
110
103
  end
111
104
  end
112
105
  end
@@ -248,7 +241,7 @@ module Kuby
248
241
  annotations do
249
242
  add(
250
243
  'getkuby.io/dockerfile-checksum',
251
- kube_spec.environment.docker.to_dockerfile.checksum
244
+ kube_spec.environment.docker.image.dockerfile.checksum
252
245
  )
253
246
  end
254
247
  end
@@ -303,117 +296,57 @@ module Kuby
303
296
  end
304
297
  end
305
298
 
306
- unless kube_spec.environment.development?
307
- readiness_probe do
308
- success_threshold 1
309
- failure_threshold 2
310
- initial_delay_seconds 15
311
- period_seconds 3
312
- timeout_seconds 1
313
-
314
- http_get do
315
- path '/healthz'
316
- port kube_spec.docker.webserver_phase.port
317
- scheme 'HTTP'
318
- end
319
- end
320
- end
321
-
322
- if kube_spec.environment.development?
323
- env do
324
- name 'BUNDLE_PATH'
325
- value '/bundle'
326
- end
327
-
328
- env do
329
- name 'GEM_HOME'
330
- value '/bundle'
331
- end
332
-
333
- env do
334
- name 'BOOTSNAP_CACHE_DIR'
335
- value '/usr/src/bootsnap'
336
- end
337
-
338
- volume_mount do
339
- name "#{kube_spec.selector_app}-code"
340
- mount_path '/usr/src/app'
341
- end
342
-
343
- volume_mount do
344
- name "#{kube_spec.selector_app}-bundle"
345
- mount_path '/bundle'
346
- end
347
-
348
- volume_mount do
349
- name "#{kube_spec.selector_app}-bootsnap"
350
- mount_path '/usr/src/bootsnap'
299
+ readiness_probe do
300
+ success_threshold 1
301
+ failure_threshold 2
302
+ initial_delay_seconds 15
303
+ period_seconds 3
304
+ timeout_seconds 1
305
+
306
+ http_get do
307
+ path '/healthz'
308
+ port kube_spec.docker.webserver_phase.port
309
+ scheme 'HTTP'
351
310
  end
352
311
  end
353
312
  end
354
313
 
355
- if kube_spec.environment.development?
356
- volume do
357
- name "#{kube_spec.selector_app}-code"
314
+ init_container(:create_db) do
315
+ name "#{kube_spec.selector_app}-create-db"
316
+ command %w(bundle exec rake kuby:rails_app:db:create_unless_exists)
358
317
 
359
- persistent_volume_claim do
360
- claim_name kube_spec.code_volume_claim.metadata.name
318
+ env_from do
319
+ config_map_ref do
320
+ name kube_spec.config_map.metadata.name
361
321
  end
362
322
  end
363
323
 
364
- volume do
365
- name "#{kube_spec.selector_app}-bundle"
366
-
367
- persistent_volume_claim do
368
- claim_name kube_spec.bundle_volume_claim.metadata.name
324
+ env_from do
325
+ secret_ref do
326
+ name kube_spec.app_secrets.metadata.name
369
327
  end
370
328
  end
329
+ end
371
330
 
372
- volume do
373
- name "#{kube_spec.selector_app}-bootsnap"
331
+ init_container(:migrate_db) do
332
+ name "#{kube_spec.selector_app}-migrate-db"
333
+ command %w(bundle exec rake db:migrate)
374
334
 
375
- persistent_volume_claim do
376
- claim_name kube_spec.bootsnap_volume_claim.metadata.name
377
- end
378
- end
379
- else
380
- init_container(:create_db) do
381
- name "#{kube_spec.selector_app}-create-db"
382
- command %w(bundle exec rake kuby:rails_app:db:create_unless_exists)
383
-
384
- env_from do
385
- config_map_ref do
386
- name kube_spec.config_map.metadata.name
387
- end
388
- end
389
-
390
- env_from do
391
- secret_ref do
392
- name kube_spec.app_secrets.metadata.name
393
- end
335
+ env_from do
336
+ config_map_ref do
337
+ name kube_spec.config_map.metadata.name
394
338
  end
395
339
  end
396
340
 
397
- init_container(:migrate_db) do
398
- name "#{kube_spec.selector_app}-migrate-db"
399
- command %w(bundle exec rake db:migrate)
400
-
401
- env_from do
402
- config_map_ref do
403
- name kube_spec.config_map.metadata.name
404
- end
405
- end
406
-
407
- env_from do
408
- secret_ref do
409
- name kube_spec.app_secrets.metadata.name
410
- end
341
+ env_from do
342
+ secret_ref do
343
+ name kube_spec.app_secrets.metadata.name
411
344
  end
412
345
  end
346
+ end
413
347
 
414
- image_pull_secret do
415
- name kube_spec.environment.kubernetes.registry_secret.metadata.name
416
- end
348
+ image_pull_secret do
349
+ name kube_spec.environment.kubernetes.registry_secret.metadata.name
417
350
  end
418
351
 
419
352
  restart_policy 'Always'
@@ -470,118 +403,6 @@ module Kuby
470
403
  @ingress
471
404
  end
472
405
 
473
- def code_volume(&block)
474
- spec = self
475
-
476
- if environment.development?
477
- @code_volume ||= KubeDSL.persistent_volume do
478
- metadata do
479
- name "#{spec.selector_app}-code"
480
- end
481
-
482
- spec do
483
- access_modes ['ReadWriteMany']
484
-
485
- capacity do
486
- add :storage, '1Mi'
487
- end
488
-
489
- host_path do
490
- path File.expand_path(spec.root)
491
- end
492
-
493
- storage_class_name 'hostpath'
494
- end
495
- end
496
-
497
- @code_volume.instance_eval(&block) if block
498
- @code_volume
499
- end
500
- end
501
-
502
- def code_volume_claim(&block)
503
- spec = self
504
-
505
- if environment.development?
506
- @code_volume_claim ||= KubeDSL.persistent_volume_claim do
507
- metadata do
508
- name "#{spec.selector_app}-code"
509
- namespace spec.namespace.metadata.name
510
- end
511
-
512
- spec do
513
- access_modes ['ReadWriteMany']
514
-
515
- resources do
516
- requests do
517
- add :storage, '1Mi'
518
- end
519
- end
520
-
521
- storage_class_name 'hostpath'
522
- volume_name spec.code_volume.metadata.name
523
- end
524
- end
525
-
526
- @code_volume_claim.instance_eval(&block) if block
527
- @code_volume_claim
528
- end
529
- end
530
-
531
- def bundle_volume_claim(&block)
532
- spec = self
533
-
534
- if environment.development?
535
- @bundle_volume_claim ||= KubeDSL.persistent_volume_claim do
536
- metadata do
537
- name "#{spec.selector_app}-bundle"
538
- namespace spec.namespace.metadata.name
539
- end
540
-
541
- spec do
542
- access_modes ['ReadWriteMany']
543
- storage_class_name 'hostpath'
544
-
545
- resources do
546
- requests do
547
- add :storage, '2Gi'
548
- end
549
- end
550
- end
551
- end
552
-
553
- @bundle_volume_claim.instance_eval(&block) if block
554
- @bundle_volume_claim
555
- end
556
- end
557
-
558
- def bootsnap_volume_claim(&block)
559
- spec = self
560
-
561
- if environment.development?
562
- @bootsnap_volume_claim ||= KubeDSL.persistent_volume_claim do
563
- metadata do
564
- name "#{spec.selector_app}-bootsnap"
565
- namespace spec.namespace.metadata.name
566
- end
567
-
568
- spec do
569
- access_modes ['ReadWriteMany']
570
- storage_class_name 'hostpath'
571
-
572
- resources do
573
- requests do
574
- add :storage, '2Gi'
575
- end
576
- end
577
- end
578
- end
579
-
580
- @bootsnap_volume_claim.instance_eval(&block) if block
581
- @bootsnap_volume_claim
582
- end
583
- end
584
-
585
406
  def resources
586
407
  @resources ||= [
587
408
  service,
@@ -590,10 +411,6 @@ module Kuby
590
411
  app_secrets,
591
412
  deployment,
592
413
  ingress,
593
- code_volume,
594
- code_volume_claim,
595
- bundle_volume_claim,
596
- bootsnap_volume_claim,
597
414
  *database&.plugin&.resources
598
415
  ]
599
416
  end
@@ -3,6 +3,7 @@ module Kuby
3
3
  module Plugins
4
4
  module RailsApp
5
5
  autoload :AssetCopyTask, 'kuby/plugins/rails_app/asset_copy_task'
6
+ autoload :AssetsImage, 'kuby/plugins/rails_app/assets_image'
6
7
  autoload :Assets, 'kuby/plugins/rails_app/assets'
7
8
  autoload :Database, 'kuby/plugins/rails_app/database'
8
9
  autoload :MySQL, 'kuby/plugins/rails_app/mysql'
data/lib/kuby/tasks.rb CHANGED
@@ -9,65 +9,57 @@ module Kuby
9
9
  @environment = environment
10
10
  end
11
11
 
12
- def print_dockerfile
13
- theme = Rouge::Themes::Base16::Solarized.new
14
- formatter = Rouge::Formatters::Terminal256.new(theme)
15
- lexer = Rouge::Lexers::Docker.new
16
- tokens = lexer.lex(Kuby.environment.docker.to_dockerfile.to_s)
17
- puts formatter.format(tokens)
12
+ def print_dockerfiles(only = nil)
13
+ kubernetes.docker_images.each do |image|
14
+ next if only && image.identifier != only
15
+
16
+ image = image.current_version
17
+ identifier = image.identifier ? " ##{image.identifier}" : ""
18
+ Kuby.logger.info("Dockerfile for#{identifier} image #{image.image_url} with tags #{image.tags.join(', ')}")
19
+ theme = Rouge::Themes::Base16::Solarized.new
20
+ formatter = Rouge::Formatters::Terminal256.new(theme)
21
+ lexer = Rouge::Lexers::Docker.new
22
+ tokens = lexer.lex(image.dockerfile.to_s)
23
+ puts formatter.format(tokens)
24
+ end
18
25
  end
19
26
 
20
27
  def setup
21
28
  environment.kubernetes.setup
22
29
  end
23
30
 
24
- def build
25
- build_args = {}
31
+ def build(build_args = {}, docker_args = [], only = nil)
32
+ check_platform(docker_args)
26
33
 
27
- unless ENV.fetch('RAILS_MASTER_KEY', '').empty?
28
- build_args['RAILS_MASTER_KEY'] = ENV['RAILS_MASTER_KEY']
29
- end
34
+ kubernetes.docker_images.each do |image|
35
+ next if only && image.identifier != only
30
36
 
31
- docker.cli.build(
32
- dockerfile: docker.to_dockerfile,
33
- image_url: docker.metadata.image_url,
34
- tags: docker.metadata.tags,
35
- build_args: build_args
36
- )
37
- end
37
+ return unless perform_docker_login_if_necessary(image)
38
38
 
39
- def push
40
- if environment.development?
41
- fail 'Cannot push Docker images built for the development environment'
39
+ image = image.new_version
40
+ Kuby.logger.info("Building image #{image.image_url} with tags #{image.tags.join(', ')}")
41
+ image.build(build_args, docker_args)
42
42
  end
43
+ end
43
44
 
44
- host = docker.metadata.image_host
45
-
46
- if docker.credentials.username && !docker.cli.auths.include?(host)
47
- Kuby.logger.info("Attempting to log in to registry at #{host}")
45
+ def push(only = nil)
46
+ kubernetes.docker_images.each do |image|
47
+ next if only && image.identifier != only
48
48
 
49
- begin
50
- docker.cli.login(
51
- url: docker.metadata.image_host,
52
- username: docker.credentials.username,
53
- password: docker.credentials.password
54
- )
55
- rescue Kuby::Docker::LoginError => e
56
- Kuby.logger.fatal("Couldn't log in to the registry at #{host}")
57
- Kuby.logger.fatal(e.message)
58
- return
59
- end
49
+ image = image.current_version
50
+ Kuby.logger.info("Pushing image #{image.image_url} with tags #{image.tags.join(', ')}")
51
+ push_image(image)
60
52
  end
53
+ end
61
54
 
62
- image_url = docker.metadata.image_url
55
+ def push_image(image)
56
+ return unless perform_docker_login_if_necessary(image)
63
57
 
64
58
  begin
65
- docker.tags.local.latest_tags.each do |tag|
66
- docker.cli.push(image_url, tag)
67
- end
59
+ image.tags.each { |tag| image.push(tag) }
68
60
  rescue Kuby::Docker::MissingTagError => e
69
61
  msg = "#{e.message} Run kuby build to build the "\
70
- 'Docker image before running this task.'
62
+ 'Docker images before running this task.'
71
63
 
72
64
  Kuby.logger.fatal(msg)
73
65
  Kuby.logger.fatal(e.message)
@@ -82,10 +74,16 @@ module Kuby
82
74
  environment.kubernetes.rollback
83
75
  end
84
76
 
85
- def print_resources
77
+ def print_resources(kind = nil, name_pattern = nil)
86
78
  kubernetes.before_deploy
87
79
 
80
+ name_rxp = Regexp.new(name_pattern) if name_pattern
81
+
88
82
  kubernetes.resources.each do |res|
83
+ next if kind && res.kind_sym.to_s != kind
84
+
85
+ next if name_rxp && !name_rxp.match?(res.metadata.name)
86
+
89
87
  puts res.to_resource.serialize.to_yaml
90
88
  end
91
89
  end
@@ -135,42 +133,73 @@ module Kuby
135
133
  kubernetes_cli.restart_deployment(namespace, deployment)
136
134
  end
137
135
 
138
- def dev_deployment_ok
139
- return true unless Kuby.environment.development?
136
+ private
137
+
138
+ def check_platform(docker_args)
139
+ arch, * = RUBY_PLATFORM.split('-')
140
+
141
+ if arch != 'x86_64' && !docker_args.include?('--platform')
142
+ Kuby.logger.fatal(<<~END)
143
+ Hey there! It looks like your processor isn't x86-compatible.
144
+ By default, Docker will try to build images that match the
145
+ current architecture, in this case #{arch}. Most hosting
146
+ providers run x86 hardware, meaning Docker images built using
147
+ this computer's architecture might fail to run when deployed
148
+ to production. You can fix this by running the build command
149
+ with a special --platform flag, eg:
150
+
151
+ bundle exec kuby -e production build -- --platform linux/amd64
152
+
153
+ If you meant to build for the current architecture, you can
154
+ prevent this error by passing the --platform argument for the
155
+ current architecture, eg. --platform linux/arm64 for ARM, etc.
156
+ END
157
+
158
+ exit 1
159
+ end
160
+ end
161
+
162
+ def perform_docker_login_if_necessary(image)
163
+ auth_uris = image.docker_cli.auths.map do |url|
164
+ Kuby::Docker::DockerURI.parse_uri(url)
165
+ end
140
166
 
141
- deployments = kubernetes_cli.get_objects(
142
- 'deployments', namespace, match_labels.serialize
167
+ logged_in = image.credentials.username && (
168
+ auth_uris.any? do |uri|
169
+ image.image_hostname == uri.host ||
170
+ image.registry_index_hostname == uri.host
171
+ end
143
172
  )
144
173
 
145
- if deployments.empty?
146
- puts 'No development environment detected.'
147
- STDOUT.write('Set up development environment? (y/n): ')
148
- answer = STDIN.gets.strip.downcase
149
- return false unless answer =~ /ye?s?/
150
- return DevSetup.new(environment).run
151
- else
152
- depl = deployments.first
153
- deployed_checksum = depl.dig('metadata', 'annotations', 'getkuby.io/dockerfile-checksum')
154
- current_checksum = docker.to_dockerfile.checksum
155
-
156
- if deployed_checksum != current_checksum
157
- puts "Development environment appears to be out-of-date."
158
- puts "Environment checksum: #{deployed_checksum}"
159
- puts "Current checksum: #{current_checksum}"
160
- STDOUT.write('Update development environment? (y/n): ')
161
- answer = STDIN.gets.strip.downcase
162
- # return true here to prevent letting an out-of-date deployment
163
- # stop us from running commands
164
- return true unless answer =~ /ye?s?/
165
- return DevSetup.new(environment).run
174
+ if !logged_in
175
+ Kuby.logger.info("Attempting to log in to registry at #{image.image_host}")
176
+
177
+ begin
178
+ # For some reason, Docker login with a port doesn't work for some
179
+ # registries (most notably Docker Hub). Since the default is 443 anyway,
180
+ # it should be fine to omit it.
181
+ url = if image.image_uri.has_default_port?
182
+ image.image_hostname # host without port
183
+ else
184
+ image.image_host # host with port
185
+ end
186
+
187
+ image.docker_cli.login(
188
+ url: url,
189
+ username: image.credentials.username,
190
+ password: image.credentials.password
191
+ )
192
+ rescue Kuby::Docker::LoginError => e
193
+ Kuby.logger.fatal("Couldn't log in to the registry at #{image.image_host}")
194
+ Kuby.logger.fatal(e.message)
195
+
196
+ return false
166
197
  end
167
198
  end
168
199
 
169
200
  true
170
201
  end
171
202
 
172
- private
173
-
174
203
  def get_first_pod
175
204
  pods = kubernetes_cli.get_objects(
176
205
  'pods', namespace, match_labels.serialize
data/lib/kuby/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # typed: true
2
2
 
3
3
  module Kuby
4
- VERSION = '0.11.16'.freeze
4
+ VERSION = '0.15.0'.freeze
5
5
  end
data/lib/kuby.rb CHANGED
@@ -13,7 +13,6 @@ module Kuby
13
13
  autoload :CLIBase, 'kuby/cli_base'
14
14
  autoload :Commands, 'kuby/commands'
15
15
  autoload :Definition, 'kuby/definition'
16
- autoload :DevSetup, 'kuby/dev_setup'
17
16
  autoload :Docker, 'kuby/docker'
18
17
  autoload :Environment, 'kuby/environment'
19
18
  autoload :Kubernetes, 'kuby/kubernetes'
@@ -21,7 +20,6 @@ module Kuby
21
20
  autoload :Plugin, 'kuby/plugin'
22
21
  autoload :PluginRegistry, 'kuby/plugin_registry'
23
22
  autoload :Plugins, 'kuby/plugins'
24
- autoload :RailsCommands, 'kuby/rails_commands'
25
23
  autoload :Tasks, 'kuby/tasks'
26
24
  autoload :TrailingHash, 'kuby/trailing_hash'
27
25
 
@@ -52,24 +50,6 @@ module Kuby
52
50
  @definition = Definition.new(name.to_s)
53
51
  @definition.instance_eval(&block)
54
52
 
55
- # default development environment
56
- @definition.environment(:development) do
57
- kubernetes do
58
- add_plugin(:rails_app) do
59
- tls_enabled false
60
-
61
- database do
62
- if requires_credentials?
63
- user(DEFAULT_DB_USER)
64
- password(DEFAULT_DB_PASSWORD)
65
- end
66
- end
67
- end
68
-
69
- provider :docker_desktop
70
- end
71
- end
72
-
73
53
  @definition.environments.each do |_, env|
74
54
  env.kubernetes.after_configuration
75
55
  end
@@ -174,3 +154,5 @@ Kuby.register_package(:c_toolchain,
174
154
  debian: 'build-essential',
175
155
  alpine: 'build-base'
176
156
  )
157
+
158
+ Kuby.register_package(:git, 'git')