mrsk 0.0.3 → 0.2.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 +193 -77
- data/bin/mrsk +5 -0
- data/lib/mrsk/cli/accessory.rb +85 -0
- data/lib/mrsk/cli/app.rb +123 -0
- data/lib/mrsk/cli/base.rb +48 -0
- data/lib/mrsk/cli/build.rb +53 -0
- data/lib/mrsk/cli/main.rb +110 -0
- data/lib/mrsk/cli/prune.rb +19 -0
- data/lib/mrsk/cli/registry.rb +18 -0
- data/lib/mrsk/cli/server.rb +8 -0
- data/lib/mrsk/cli/templates/deploy.yml +17 -0
- data/lib/mrsk/cli/traefik.rb +77 -0
- data/lib/mrsk/cli.rb +9 -0
- data/lib/mrsk/commander.rb +45 -5
- data/lib/mrsk/commands/accessory.rb +61 -0
- data/lib/mrsk/commands/app.rb +50 -10
- data/lib/mrsk/commands/base.rb +13 -9
- data/lib/mrsk/commands/builder/base.rb +26 -0
- data/lib/mrsk/commands/builder/multiarch/remote.rb +12 -4
- data/lib/mrsk/commands/builder/multiarch.rb +17 -9
- data/lib/mrsk/commands/builder/native/remote.rb +71 -0
- data/lib/mrsk/commands/builder/native.rb +3 -7
- data/lib/mrsk/commands/builder.rb +11 -7
- data/lib/mrsk/commands/traefik.rb +13 -3
- data/lib/mrsk/configuration/accessory.rb +60 -0
- data/lib/mrsk/configuration/role.rb +46 -14
- data/lib/mrsk/configuration.rb +86 -43
- data/lib/mrsk/sshkit_with_ext.rb +12 -0
- data/lib/mrsk/utils.rb +29 -0
- data/lib/mrsk/version.rb +1 -1
- data/lib/mrsk.rb +0 -1
- metadata +40 -18
- data/lib/mrsk/engine.rb +0 -4
- data/lib/tasks/mrsk/app.rake +0 -97
- data/lib/tasks/mrsk/build.rake +0 -52
- data/lib/tasks/mrsk/mrsk.rake +0 -37
- data/lib/tasks/mrsk/prune.rake +0 -18
- data/lib/tasks/mrsk/registry.rake +0 -16
- data/lib/tasks/mrsk/server.rake +0 -11
- data/lib/tasks/mrsk/setup.rb +0 -6
- data/lib/tasks/mrsk/templates/deploy.yml +0 -24
- data/lib/tasks/mrsk/templates/mrsk +0 -8
- data/lib/tasks/mrsk/traefik.rake +0 -41
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mrsk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.0
|
19
|
+
version: '7.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.0
|
26
|
+
version: '7.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sshkit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,40 +38,62 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.21'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.2'
|
41
55
|
description:
|
42
56
|
email: dhh@hey.com
|
43
|
-
executables:
|
57
|
+
executables:
|
58
|
+
- mrsk
|
44
59
|
extensions: []
|
45
60
|
extra_rdoc_files: []
|
46
61
|
files:
|
47
62
|
- MIT-LICENSE
|
48
63
|
- README.md
|
64
|
+
- bin/mrsk
|
49
65
|
- lib/mrsk.rb
|
66
|
+
- lib/mrsk/cli.rb
|
67
|
+
- lib/mrsk/cli/accessory.rb
|
68
|
+
- lib/mrsk/cli/app.rb
|
69
|
+
- lib/mrsk/cli/base.rb
|
70
|
+
- lib/mrsk/cli/build.rb
|
71
|
+
- lib/mrsk/cli/main.rb
|
72
|
+
- lib/mrsk/cli/prune.rb
|
73
|
+
- lib/mrsk/cli/registry.rb
|
74
|
+
- lib/mrsk/cli/server.rb
|
75
|
+
- lib/mrsk/cli/templates/deploy.yml
|
76
|
+
- lib/mrsk/cli/traefik.rb
|
50
77
|
- lib/mrsk/commander.rb
|
51
78
|
- lib/mrsk/commands.rb
|
79
|
+
- lib/mrsk/commands/accessory.rb
|
52
80
|
- lib/mrsk/commands/app.rb
|
53
81
|
- lib/mrsk/commands/base.rb
|
54
82
|
- lib/mrsk/commands/builder.rb
|
83
|
+
- lib/mrsk/commands/builder/base.rb
|
55
84
|
- lib/mrsk/commands/builder/multiarch.rb
|
56
85
|
- lib/mrsk/commands/builder/multiarch/remote.rb
|
57
86
|
- lib/mrsk/commands/builder/native.rb
|
87
|
+
- lib/mrsk/commands/builder/native/remote.rb
|
58
88
|
- lib/mrsk/commands/prune.rb
|
59
89
|
- lib/mrsk/commands/registry.rb
|
60
90
|
- lib/mrsk/commands/traefik.rb
|
61
91
|
- lib/mrsk/configuration.rb
|
92
|
+
- lib/mrsk/configuration/accessory.rb
|
62
93
|
- lib/mrsk/configuration/role.rb
|
63
|
-
- lib/mrsk/
|
94
|
+
- lib/mrsk/sshkit_with_ext.rb
|
95
|
+
- lib/mrsk/utils.rb
|
64
96
|
- lib/mrsk/version.rb
|
65
|
-
- lib/tasks/mrsk/app.rake
|
66
|
-
- lib/tasks/mrsk/build.rake
|
67
|
-
- lib/tasks/mrsk/mrsk.rake
|
68
|
-
- lib/tasks/mrsk/prune.rake
|
69
|
-
- lib/tasks/mrsk/registry.rake
|
70
|
-
- lib/tasks/mrsk/server.rake
|
71
|
-
- lib/tasks/mrsk/setup.rb
|
72
|
-
- lib/tasks/mrsk/templates/deploy.yml
|
73
|
-
- lib/tasks/mrsk/templates/mrsk
|
74
|
-
- lib/tasks/mrsk/traefik.rake
|
75
97
|
homepage: https://github.com/rails/mrsk
|
76
98
|
licenses:
|
77
99
|
- MIT
|
@@ -94,5 +116,5 @@ requirements: []
|
|
94
116
|
rubygems_version: 3.4.1
|
95
117
|
signing_key:
|
96
118
|
specification_version: 4
|
97
|
-
summary: Deploy
|
119
|
+
summary: Deploy Rails apps in containers to servers running Docker with zero downtime.
|
98
120
|
test_files: []
|
data/lib/mrsk/engine.rb
DELETED
data/lib/tasks/mrsk/app.rake
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
namespace :app do
|
5
|
-
desc "Run app on servers (or start them if they've already been run)"
|
6
|
-
task :run do
|
7
|
-
MRSK.config.roles.each do |role|
|
8
|
-
on(role.hosts) do |host|
|
9
|
-
begin
|
10
|
-
execute *MRSK.app.run(role: role.name)
|
11
|
-
rescue SSHKit::Command::Failed => e
|
12
|
-
if e.message =~ /already in use/
|
13
|
-
error "Container with same version already deployed on #{host}, starting that instead"
|
14
|
-
execute *MRSK.app.start, host: host
|
15
|
-
else
|
16
|
-
raise
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
desc "Start existing app on servers (use VERSION=<git-hash> to designate which version)"
|
24
|
-
task :start do
|
25
|
-
on(MRSK.config.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Stop app on servers"
|
29
|
-
task :stop do
|
30
|
-
on(MRSK.config.hosts) { execute *MRSK.app.stop, raise_on_non_zero_exit: false }
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Start app on servers (use VERSION=<git-hash> to designate which version)"
|
34
|
-
task restart: %i[ stop start ]
|
35
|
-
|
36
|
-
desc "Display information about app containers"
|
37
|
-
task :info do
|
38
|
-
on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.info) + "\n\n" }
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "Execute a custom task on servers passed in as CMD='bin/rake some:task'"
|
42
|
-
task :exec do
|
43
|
-
on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.exec(ENV["CMD"])) + "\n\n" }
|
44
|
-
end
|
45
|
-
|
46
|
-
desc "Start Rails Console on primary host"
|
47
|
-
task :console do
|
48
|
-
puts "Launching Rails console on #{MRSK.config.primary_host}..."
|
49
|
-
exec app.console
|
50
|
-
end
|
51
|
-
|
52
|
-
namespace :exec do
|
53
|
-
desc "Execute Rails command on servers, like CMD='runner \"puts %(Hello World)\""
|
54
|
-
task :rails do
|
55
|
-
on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.exec("bin/rails", ENV["CMD"])) + "\n\n" }
|
56
|
-
end
|
57
|
-
|
58
|
-
desc "Execute a custom task on the first defined server"
|
59
|
-
task :once do
|
60
|
-
on(MRSK.config.primary_host) { puts capture(*MRSK.app.exec(ENV["CMD"])) }
|
61
|
-
end
|
62
|
-
|
63
|
-
namespace :once do
|
64
|
-
desc "Execute Rails command on the first defined server, like CMD='runner \"puts %(Hello World)\""
|
65
|
-
task :rails do
|
66
|
-
on(MRSK.config.primary_host) { puts capture(*MRSK.app.exec("bin/rails", ENV["CMD"])) }
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
desc "List all the app containers currently on servers"
|
72
|
-
task :containers do
|
73
|
-
on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.list_containers) + "\n\n" }
|
74
|
-
end
|
75
|
-
|
76
|
-
desc "Show last 100 log lines from app on servers"
|
77
|
-
task :logs do
|
78
|
-
# FIXME: Catch when app containers aren't running
|
79
|
-
on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.logs) + "\n\n" }
|
80
|
-
end
|
81
|
-
|
82
|
-
desc "Remove app containers and images from servers"
|
83
|
-
task remove: %w[ remove:containers remove:images ]
|
84
|
-
|
85
|
-
namespace :remove do
|
86
|
-
desc "Remove app containers from servers"
|
87
|
-
task :containers do
|
88
|
-
on(MRSK.config.hosts) { execute *MRSK.app.remove_containers }
|
89
|
-
end
|
90
|
-
|
91
|
-
desc "Remove app images from servers"
|
92
|
-
task :images do
|
93
|
-
on(MRSK.config.hosts) { execute *MRSK.app.remove_images }
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
data/lib/tasks/mrsk/build.rake
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
namespace :build do
|
5
|
-
desc "Deliver a newly built app image to servers"
|
6
|
-
task deliver: %i[ push pull ]
|
7
|
-
|
8
|
-
desc "Build locally and push app image to registry"
|
9
|
-
task :push do
|
10
|
-
run_locally do
|
11
|
-
begin
|
12
|
-
debug "Using builder: #{MRSK.builder.name}"
|
13
|
-
info "Building image may take a while (run with VERBOSE=1 for progress logging)"
|
14
|
-
execute *MRSK.builder.push
|
15
|
-
rescue SSHKit::Command::Failed => e
|
16
|
-
error "Missing compatible builder, so creating a new one first"
|
17
|
-
execute *MRSK.builder.create
|
18
|
-
execute *MRSK.builder.push
|
19
|
-
end
|
20
|
-
end unless ENV["VERSION"]
|
21
|
-
end
|
22
|
-
|
23
|
-
desc "Pull app image from the registry onto servers"
|
24
|
-
task :pull do
|
25
|
-
on(MRSK.config.hosts) { execute *MRSK.builder.pull }
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Create a local build setup"
|
29
|
-
task :create do
|
30
|
-
run_locally do
|
31
|
-
debug "Using builder: #{MRSK.builder.name}"
|
32
|
-
execute *MRSK.builder.create
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
desc "Remove local build setup"
|
37
|
-
task :remove do
|
38
|
-
run_locally do
|
39
|
-
debug "Using builder: #{MRSK.builder.name}"
|
40
|
-
execute *MRSK.builder.remove
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
desc "Show the name of the configured builder"
|
45
|
-
task :info do
|
46
|
-
run_locally do
|
47
|
-
puts "Builder: #{MRSK.builder.name} (#{MRSK.builder.target.class.name})"
|
48
|
-
puts capture(*MRSK.builder.info)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/tasks/mrsk/mrsk.rake
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
desc "Deploy app for the first time to a fresh server"
|
5
|
-
task fresh: %w[ server:bootstrap registry:login build:deliver traefik:run app:stop app:run ]
|
6
|
-
|
7
|
-
desc "Push the latest version of the app, ensure Traefik is running, then restart app"
|
8
|
-
task deploy: %w[ registry:login build:deliver traefik:run app:stop app:run prune ]
|
9
|
-
|
10
|
-
desc "Rollback to VERSION=x that was already run as a container on servers"
|
11
|
-
task rollback: %w[ app:restart ]
|
12
|
-
|
13
|
-
desc "Display information about Traefik and app containers"
|
14
|
-
task info: %w[ traefik:info app:info ]
|
15
|
-
|
16
|
-
desc "Create config stub in config/deploy.yml"
|
17
|
-
task :init do
|
18
|
-
require "fileutils"
|
19
|
-
|
20
|
-
if (deploy_file = Rails.root.join("config/deploy.yml")).exist?
|
21
|
-
puts "Config file already exists in config/deploy.yml (remove first to create a new one)"
|
22
|
-
else
|
23
|
-
FileUtils.cp_r Pathname.new(File.expand_path("templates/deploy.yml", __dir__)), deploy_file
|
24
|
-
puts "Created configuration file in config/deploy.yml"
|
25
|
-
end
|
26
|
-
|
27
|
-
if (binstub = Rails.root.join("bin/mrsk")).exist?
|
28
|
-
puts "Binstub already exists in bin/mrsk (remove first to create a new one)"
|
29
|
-
else
|
30
|
-
FileUtils.cp_r Pathname.new(File.expand_path("templates/mrsk", __dir__)), binstub
|
31
|
-
puts "Created binstub file in bin/mrsk"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
desc "Remove Traefik, app, and registry session from servers"
|
36
|
-
task remove: %w[ traefik:remove app:remove registry:logout ]
|
37
|
-
end
|
data/lib/tasks/mrsk/prune.rake
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
desc "Prune unused images and stopped containers"
|
5
|
-
task prune: %w[ prune:containers prune:images ]
|
6
|
-
|
7
|
-
namespace :prune do
|
8
|
-
desc "Prune unused images older than 30 days"
|
9
|
-
task :images do
|
10
|
-
on(MRSK.config.hosts) { MRSK.verbosity(:debug) { execute *MRSK.prune.images } }
|
11
|
-
end
|
12
|
-
|
13
|
-
desc "Prune stopped containers for the service older than 3 days"
|
14
|
-
task :containers do
|
15
|
-
on(MRSK.config.hosts) { MRSK.verbosity(:debug) { execute *MRSK.prune.containers } }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
namespace :registry do
|
5
|
-
desc "Login to the registry locally and remotely"
|
6
|
-
task :login do
|
7
|
-
run_locally { execute *MRSK.registry.login }
|
8
|
-
on(MRSK.config.hosts) { execute *MRSK.registry.login }
|
9
|
-
end
|
10
|
-
|
11
|
-
desc "Logout of the registry remotely"
|
12
|
-
task :logout do
|
13
|
-
on(MRSK.config.hosts) { execute *MRSK.registry.logout }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/tasks/mrsk/server.rake
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
namespace :server do
|
5
|
-
desc "Setup Docker on the remote servers"
|
6
|
-
task :bootstrap do
|
7
|
-
# FIXME: Detect when apt-get is not available and use the appropriate alternative
|
8
|
-
on(MRSK.config.hosts) { execute "apt-get install docker.io -y" }
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
data/lib/tasks/mrsk/setup.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# Name of your application will be used for uniquely configuring Traefik and app containers.
|
2
|
-
# Your Dockerfile should set LABEL service=the-same-value to ensure image pruning works.
|
3
|
-
service: my-app
|
4
|
-
|
5
|
-
# Name of the container image
|
6
|
-
image: user/my-app
|
7
|
-
|
8
|
-
# All the servers targeted for deploy. You can reference a single server for a command by using SERVERS=192.168.0.1
|
9
|
-
servers:
|
10
|
-
- 192.168.0.1
|
11
|
-
|
12
|
-
# The following envs are made available to the container when started
|
13
|
-
env:
|
14
|
-
# Remember never to put passwords or tokens directly into this file, use encrypted credentials
|
15
|
-
# REDIS_URL: redis://x/y
|
16
|
-
|
17
|
-
# Where your images will be hosted
|
18
|
-
registry:
|
19
|
-
# Specify the registry server, if you're not using Docker Hub
|
20
|
-
# server: registry.digitalocean.com / ghcr.io / ...
|
21
|
-
|
22
|
-
# Set credentials with bin/rails credentials:edit
|
23
|
-
username: my-user
|
24
|
-
password: my-password-should-go-in-credentials
|
data/lib/tasks/mrsk/traefik.rake
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require_relative "setup"
|
2
|
-
|
3
|
-
namespace :mrsk do
|
4
|
-
namespace :traefik do
|
5
|
-
desc "Run Traefik on servers"
|
6
|
-
task :run do
|
7
|
-
on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
|
8
|
-
end
|
9
|
-
|
10
|
-
desc "Start existing Traefik on servers"
|
11
|
-
task :start do
|
12
|
-
on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Stop Traefik on servers"
|
16
|
-
task :stop do
|
17
|
-
on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
|
18
|
-
end
|
19
|
-
|
20
|
-
desc "Restart Traefik on servers"
|
21
|
-
task restart: %i[ stop start ]
|
22
|
-
|
23
|
-
desc "Display information about Traefik containers from servers"
|
24
|
-
task :info do
|
25
|
-
on(MRSK.config.role(:web).hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.info) + "\n\n" }
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Show last 100 log lines from Traefik on servers"
|
29
|
-
task :logs do
|
30
|
-
on(MRSK.config.hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.logs) + "\n\n" }
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Remove Traefik container and image from servers"
|
34
|
-
task remove: %i[ stop ] do
|
35
|
-
on(MRSK.config.role(:web).hosts) do
|
36
|
-
execute *MRSK.traefik.remove_container
|
37
|
-
execute *MRSK.traefik.remove_image
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|