mrsk 0.14.0 → 0.15.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 +47 -9
- data/lib/mrsk/cli/accessory.rb +7 -3
- data/lib/mrsk/cli/traefik.rb +8 -3
- data/lib/mrsk/commands/lock.rb +1 -1
- data/lib/mrsk/configuration.rb +11 -2
- data/lib/mrsk/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b7e74f66fc6480dd991ce88dc5a2527832c6c61ff85ede26625e1e86f1650c9
|
4
|
+
data.tar.gz: 9621b2ae90f53dc652fc41abfa28b000bac895bfcf4a7dc4c82db72787f78e08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bd519ba6639ae9f8c565177a4cbfd2bcf6e725452b76b1b95032f7e8288227b2ae3e3550d1fd946eb85a37c36b2b2a03419c097f64f0777110b3c06f128a545
|
7
|
+
data.tar.gz: 119a7b8551b5f72a2ba54c0f5c059ef36a47a85852616ffd6df04cd3b168113b5892f571609a228c71330cd3cd69045f7fc03e3005a1b95aec41d3ee6a91c4d4
|
data/README.md
CHANGED
@@ -63,6 +63,24 @@ This will:
|
|
63
63
|
|
64
64
|
Voila! All the servers are now serving the app on port 80. If you're just running a single server, you're ready to go. If you're running multiple servers, you need to put a load balancer in front of them. For subsequent deploys, or if your servers already have Docker and curl installed, you can just run `mrsk deploy`.
|
65
65
|
|
66
|
+
### Rails <7 usage
|
67
|
+
|
68
|
+
MRSK is not needed to be in your application Gemfile to be used. However, if you want to guarantee specific MRSK version in your CI/CD workflows, you can create a separate Gemfile for MRSK, for example, `gemfile/mrsk.gemfile`:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
source 'https://rubygems.org'
|
72
|
+
|
73
|
+
gem 'mrsk', '~> 0.14'
|
74
|
+
```
|
75
|
+
|
76
|
+
Bundle with `BUNDLE_GEMFILE=gemfiles/mrsk.gemfile bundle`.
|
77
|
+
|
78
|
+
After this MRSK can be used for deployment:
|
79
|
+
|
80
|
+
```sh
|
81
|
+
BUNDLE_GEMFILE=gemfiles/mrsk.gemfile bundle exec mrsk deploy
|
82
|
+
```
|
83
|
+
|
66
84
|
## Vision
|
67
85
|
|
68
86
|
In the past decade+, there's been an explosion in commercial offerings that make deploying web apps easier. Heroku kicked it off with an incredible offering that stayed ahead of the competition seemingly forever. These days we have excellent alternatives like Fly.io and Render. And hosted Kubernetes is making things easier too on AWS, GCP, Digital Ocean, and elsewhere. But these are all offerings that have you renting computers in the cloud at a premium. If you want to run on your own hardware, or even just have a clear migration path to do so in the future, you need to carefully consider how locked in you get to these commercial platforms. Preferably before the bills swallow your business whole!
|
@@ -123,6 +141,8 @@ This template can safely be checked into git. Then everyone deploying the app ca
|
|
123
141
|
|
124
142
|
If you need separate env variables for different destinations, you can set them with `.env.destination.erb` for the template, which will generate `.env.staging` when run with `mrsk envify -d staging`.
|
125
143
|
|
144
|
+
Note: If you utilize biometrics with 1Password you can remove the `session_token` related parts in the example and just call `op read op://Vault/Docker Hub/password -n`.
|
145
|
+
|
126
146
|
#### Bitwarden as a secret store
|
127
147
|
|
128
148
|
If you are using open source secret store like bitwarden, you can create `.env.erb` as a template which looks up the secrets.
|
@@ -206,13 +226,13 @@ ssh:
|
|
206
226
|
user: app
|
207
227
|
```
|
208
228
|
|
209
|
-
If you are using non-root user, you need to bootstrap your servers manually, before using them with MRSK. On Ubuntu, you'd do:
|
229
|
+
If you are using non-root user (`app` as above example), you need to bootstrap your servers manually, before using them with MRSK. On Ubuntu, you'd do:
|
210
230
|
|
211
231
|
```bash
|
212
232
|
sudo apt update
|
213
233
|
sudo apt upgrade -y
|
214
234
|
sudo apt install -y docker.io curl git
|
215
|
-
sudo usermod -a -G docker
|
235
|
+
sudo usermod -a -G docker app
|
216
236
|
```
|
217
237
|
|
218
238
|
### Using a proxy SSH host
|
@@ -238,6 +258,15 @@ ssh:
|
|
238
258
|
proxy_command: aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --region=us-east-1 ## ssh via aws ssm
|
239
259
|
```
|
240
260
|
|
261
|
+
### Configuring the SSH log level
|
262
|
+
|
263
|
+
```yaml
|
264
|
+
ssh:
|
265
|
+
log_level: debug
|
266
|
+
```
|
267
|
+
|
268
|
+
Valid levels are `debug`, `info`, `warn`, `error` and `fatal` (default).
|
269
|
+
|
241
270
|
### Using env variables
|
242
271
|
|
243
272
|
You can inject env variables into the app containers using `env`:
|
@@ -622,6 +651,16 @@ traefik:
|
|
622
651
|
entrypoints.otherentrypoint.address: ':9000'
|
623
652
|
```
|
624
653
|
|
654
|
+
### Rebooting Traefik
|
655
|
+
|
656
|
+
If you make changes to Traefik args or labels, you'll need to reboot with:
|
657
|
+
|
658
|
+
`mrsk traefik reboot`
|
659
|
+
|
660
|
+
In production, reboot the Traefik containers one by one with a slower but safer approach, using a rolling reboot:
|
661
|
+
|
662
|
+
`mrsk traefik reboot --rolling`
|
663
|
+
|
625
664
|
### Configuring build args for new images
|
626
665
|
|
627
666
|
Build arguments that aren't secret can also be configured:
|
@@ -866,7 +905,7 @@ If you wish to remove the entire application, including Traefik, containers, ima
|
|
866
905
|
|
867
906
|
## Locking
|
868
907
|
|
869
|
-
Commands that are unsafe to run concurrently will take a deploy lock while they run. The lock is the `mrsk_lock
|
908
|
+
Commands that are unsafe to run concurrently will take a deploy lock while they run. The lock is the `mrsk_lock-<service>` directory on the primary server.
|
870
909
|
|
871
910
|
You can check the lock status with:
|
872
911
|
|
@@ -922,8 +961,8 @@ firing a JSON webhook. These variables include:
|
|
922
961
|
- `MRSK_RECORDED_AT` - UTC timestamp in ISO 8601 format, e.g. `2023-04-14T17:07:31Z`
|
923
962
|
- `MRSK_PERFORMER` - the local user performing the command (from `whoami`)
|
924
963
|
- `MRSK_SERVICE_VERSION` - an abbreviated service and version for use in messages, e.g. app@150b24f
|
925
|
-
- `MRSK_VERSION` -
|
926
|
-
- `MRSK_HOSTS` - a comma
|
964
|
+
- `MRSK_VERSION` - the full version being deployed
|
965
|
+
- `MRSK_HOSTS` - a comma-separated list of the hosts targeted by the command
|
927
966
|
- `MRSK_COMMAND` - The command we are running
|
928
967
|
- `MRSK_SUBCOMMAND` - optional: The subcommand we are running
|
929
968
|
- `MRSK_DESTINATION` - optional: destination, e.g. "staging"
|
@@ -940,9 +979,8 @@ Used for pre-build checks - e.g. there are no uncommitted changes or that CI has
|
|
940
979
|
3. pre-deploy
|
941
980
|
For final checks before deploying, e.g. checking CI completed
|
942
981
|
|
943
|
-
3. post-deploy - run after a deploy, redeploy or rollback
|
944
|
-
|
945
|
-
This hook is also passed a `MRSK_RUNTIME` env variable.
|
982
|
+
3. post-deploy - run after a deploy, redeploy or rollback.
|
983
|
+
This hook is also passed a `MRSK_RUNTIME` env variable set to the total seconds the deploy took.
|
946
984
|
|
947
985
|
This could be used to broadcast a deployment message, or register the new version with an APM.
|
948
986
|
|
@@ -953,7 +991,7 @@ The command could look something like:
|
|
953
991
|
curl -q -d content="[My App] ${MRSK_PERFORMER} Rolled back to version ${MRSK_VERSION}" https://3.basecamp.com/XXXXX/integrations/XXXXX/buckets/XXXXX/chats/XXXXX/lines
|
954
992
|
```
|
955
993
|
|
956
|
-
That'll post a line like
|
994
|
+
That'll post a line like the following to a preconfigured chatbot in Basecamp:
|
957
995
|
|
958
996
|
```
|
959
997
|
[My App] [dhh] Rolled back to version d264c4e92470ad1bd18590f04466787262f605de
|
data/lib/mrsk/cli/accessory.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
2
2
|
desc "boot [NAME]", "Boot new accessory service on host (use NAME=all to boot all accessories)"
|
3
|
-
def boot(name)
|
3
|
+
def boot(name, login: true)
|
4
4
|
mutating do
|
5
5
|
if name == "all"
|
6
6
|
MRSK.accessory_names.each { |accessory_name| boot(accessory_name) }
|
@@ -10,7 +10,7 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
|
10
10
|
upload(name)
|
11
11
|
|
12
12
|
on(accessory.hosts) do
|
13
|
-
execute *MRSK.registry.login
|
13
|
+
execute *MRSK.registry.login if login
|
14
14
|
execute *MRSK.auditor.record("Booted #{name} accessory"), verbosity: :debug
|
15
15
|
execute *accessory.run
|
16
16
|
end
|
@@ -53,9 +53,13 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
|
53
53
|
def reboot(name)
|
54
54
|
mutating do
|
55
55
|
with_accessory(name) do |accessory|
|
56
|
+
on(accessory.hosts) do
|
57
|
+
execute *MRSK.registry.login
|
58
|
+
end
|
59
|
+
|
56
60
|
stop(name)
|
57
61
|
remove_container(name)
|
58
|
-
boot(name)
|
62
|
+
boot(name, login: false)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
end
|
data/lib/mrsk/cli/traefik.rb
CHANGED
@@ -10,11 +10,16 @@ class Mrsk::Cli::Traefik < Mrsk::Cli::Base
|
|
10
10
|
end
|
11
11
|
|
12
12
|
desc "reboot", "Reboot Traefik on servers (stop container, remove container, start new container)"
|
13
|
+
option :rolling, type: :boolean, default: false, desc: "Reboot traefik on hosts in sequence, rather than in parallel"
|
13
14
|
def reboot
|
14
15
|
mutating do
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
on(MRSK.traefik_hosts, in: options[:rolling] ? :sequence : :parallel) do
|
17
|
+
execute *MRSK.auditor.record("Rebooted traefik"), verbosity: :debug
|
18
|
+
execute *MRSK.registry.login
|
19
|
+
execute *MRSK.traefik.stop, raise_on_non_zero_exit: false
|
20
|
+
execute *MRSK.traefik.remove_container
|
21
|
+
execute *MRSK.traefik.run, raise_on_non_zero_exit: false
|
22
|
+
end
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
data/lib/mrsk/commands/lock.rb
CHANGED
data/lib/mrsk/configuration.rb
CHANGED
@@ -153,7 +153,15 @@ class Mrsk::Configuration
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def ssh_options
|
156
|
-
{ user: ssh_user, proxy: ssh_proxy, auth_methods: [ "publickey" ] }.compact
|
156
|
+
{ user: ssh_user, proxy: ssh_proxy, auth_methods: [ "publickey" ], logger: ssh_logger }.compact
|
157
|
+
end
|
158
|
+
|
159
|
+
def ssh_logger
|
160
|
+
@ssh_logger ||= ::Logger.new(STDERR).tap { |logger| logger.level = ssh_log_level }
|
161
|
+
end
|
162
|
+
|
163
|
+
def ssh_log_level
|
164
|
+
(raw_config.ssh && raw_config.ssh["log_level"]) || ::Logger::FATAL
|
157
165
|
end
|
158
166
|
|
159
167
|
|
@@ -185,7 +193,8 @@ class Mrsk::Configuration
|
|
185
193
|
service_with_version: service_with_version,
|
186
194
|
env_args: env_args,
|
187
195
|
volume_args: volume_args,
|
188
|
-
ssh_options: ssh_options,
|
196
|
+
ssh_options: ssh_options.except(:logger),
|
197
|
+
ssh_log_level: ssh_log_level,
|
189
198
|
builder: builder.to_h,
|
190
199
|
accessories: raw_config.accessories,
|
191
200
|
logging: logging_args,
|
data/lib/mrsk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mrsk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.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-
|
11
|
+
date: 2023-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
243
243
|
- !ruby/object:Gem::Version
|
244
244
|
version: '0'
|
245
245
|
requirements: []
|
246
|
-
rubygems_version: 3.4.
|
246
|
+
rubygems_version: 3.4.16
|
247
247
|
signing_key:
|
248
248
|
specification_version: 4
|
249
249
|
summary: Deploy web apps in containers to servers running Docker with zero downtime.
|