dlss-capistrano-docker 1.0.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 +7 -0
- data/.gitignore +56 -0
- data/.rubocop.yml +178 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +67 -0
- data/README.md +98 -0
- data/Rakefile +15 -0
- data/dlss-capistrano-docker.gemspec +33 -0
- data/lib/dlss/docker/capistrano/tasks/docker.rake +50 -0
- data/lib/dlss/docker/capistrano/tasks/docker_compose.rake +198 -0
- data/lib/dlss/docker/capistrano/tasks/honeybadger.rake +58 -0
- data/lib/dlss/docker/capistrano/tasks/shared_configs.rake +21 -0
- data/lib/dlss/docker/capistrano/tasks/ssh.rake +10 -0
- data/lib/dlss/docker/capistrano.rb +6 -0
- metadata +158 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7b180b31a5354ceec3029befccbdeac4ba5c86321eb75a1beb369d0c24a5ebbd
|
|
4
|
+
data.tar.gz: 30865848d3ef1b7c5e86565641aed355c011cf85e5219999c112a1d234d353eb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f90641ba2d8b8c60c7f22e45dfc477f163732e9aeb3b89244b5b1563e09f10913c51cdb59464dc8d015c7b5f558655d01d7b9729fbe11b541603ab0504828a53
|
|
7
|
+
data.tar.gz: dddb973eaecac7511a4a6128cdf6a0e2b065226e0e8c40547204b191ae101cb5eb3010669551831ce1a8685fb10b8e86f5854ada8044815f3d548c59c71524c8
|
data/.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
/.config
|
|
4
|
+
/coverage/
|
|
5
|
+
/InstalledFiles
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/spec/examples.txt
|
|
9
|
+
/test/tmp/
|
|
10
|
+
/test/version_tmp/
|
|
11
|
+
/tmp/
|
|
12
|
+
|
|
13
|
+
# Used by dotenv library to load environment variables.
|
|
14
|
+
# .env
|
|
15
|
+
|
|
16
|
+
# Ignore Byebug command history file.
|
|
17
|
+
.byebug_history
|
|
18
|
+
|
|
19
|
+
## Specific to RubyMotion:
|
|
20
|
+
.dat*
|
|
21
|
+
.repl_history
|
|
22
|
+
build/
|
|
23
|
+
*.bridgesupport
|
|
24
|
+
build-iPhoneOS/
|
|
25
|
+
build-iPhoneSimulator/
|
|
26
|
+
|
|
27
|
+
## Specific to RubyMotion (use of CocoaPods):
|
|
28
|
+
#
|
|
29
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
|
30
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
|
31
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
|
32
|
+
#
|
|
33
|
+
# vendor/Pods/
|
|
34
|
+
|
|
35
|
+
## Documentation cache and generated files:
|
|
36
|
+
/.yardoc/
|
|
37
|
+
/_yardoc/
|
|
38
|
+
/doc/
|
|
39
|
+
/rdoc/
|
|
40
|
+
|
|
41
|
+
## Environment normalization:
|
|
42
|
+
/.bundle/
|
|
43
|
+
/vendor/bundle
|
|
44
|
+
/lib/bundler/man/
|
|
45
|
+
|
|
46
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
47
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
48
|
+
# Gemfile.lock
|
|
49
|
+
# .ruby-version
|
|
50
|
+
# .ruby-gemset
|
|
51
|
+
|
|
52
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
53
|
+
.rvmrc
|
|
54
|
+
|
|
55
|
+
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
|
56
|
+
# .rubocop-https?--*
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.1
|
|
3
|
+
SuggestExtensions: false
|
|
4
|
+
DisplayCopNames: true
|
|
5
|
+
Include:
|
|
6
|
+
- './Rakefile' # rake only
|
|
7
|
+
- '**/*.rb'
|
|
8
|
+
- '**/*.rake' # rake only
|
|
9
|
+
|
|
10
|
+
Bundler/GemComment:
|
|
11
|
+
OnlyFor:
|
|
12
|
+
- restrictive_version_specifiers
|
|
13
|
+
- branch
|
|
14
|
+
|
|
15
|
+
# Configuration parameters: AllowURI, URISchemes.
|
|
16
|
+
Layout/LineLength:
|
|
17
|
+
Max: 120
|
|
18
|
+
|
|
19
|
+
# consider if refactoring will improve adherence to SOLID and/or improve readability
|
|
20
|
+
# Sometimes splitting the class up won't improve readablity, it just makes reader jump around in the code.
|
|
21
|
+
Metrics/ClassLength:
|
|
22
|
+
Max: 150 # default 100
|
|
23
|
+
|
|
24
|
+
# consider if refactoring will improve adherence to SOLID and/or improve readability
|
|
25
|
+
# Sometimes splitting the method up won't improve readablity, it just makes reader jump around in the code.
|
|
26
|
+
# Good method names help.
|
|
27
|
+
Metrics/MethodLength:
|
|
28
|
+
Max: 15 # default 10
|
|
29
|
+
|
|
30
|
+
# capistrano tasks tend to be long.
|
|
31
|
+
Metrics/BlockLength:
|
|
32
|
+
Enabled: false
|
|
33
|
+
|
|
34
|
+
# "> 0", "== 0", "< 0" are not less readable than ".positive?", ".zero?" or ".negative?"
|
|
35
|
+
Style/NumericPredicate:
|
|
36
|
+
Enabled: false
|
|
37
|
+
|
|
38
|
+
Style/RegexpLiteral:
|
|
39
|
+
Enabled: false
|
|
40
|
+
|
|
41
|
+
Style/SymbolArray:
|
|
42
|
+
MinSize: 4 # default 2
|
|
43
|
+
|
|
44
|
+
Style/WordArray:
|
|
45
|
+
MinSize: 4 # default 2
|
|
46
|
+
|
|
47
|
+
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
|
48
|
+
Enabled: true
|
|
49
|
+
Gemspec/RequireMFA: # new in 1.23
|
|
50
|
+
Enabled: true
|
|
51
|
+
Layout/LineContinuationLeadingSpace: # new in 1.31
|
|
52
|
+
Enabled: true
|
|
53
|
+
Layout/LineContinuationSpacing: # new in 1.31
|
|
54
|
+
Enabled: true
|
|
55
|
+
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
|
56
|
+
Enabled: true
|
|
57
|
+
Layout/SpaceBeforeBrackets: # new in 1.7
|
|
58
|
+
Enabled: true
|
|
59
|
+
Lint/AmbiguousAssignment: # new in 1.7
|
|
60
|
+
Enabled: true
|
|
61
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
|
62
|
+
Enabled: true
|
|
63
|
+
Lint/AmbiguousRange: # new in 1.19
|
|
64
|
+
Enabled: true
|
|
65
|
+
Lint/ConstantOverwrittenInRescue: # new in 1.31
|
|
66
|
+
Enabled: true
|
|
67
|
+
Lint/DeprecatedConstants: # new in 1.8
|
|
68
|
+
Enabled: true
|
|
69
|
+
Lint/DuplicateBranch: # new in 1.3
|
|
70
|
+
Enabled: true
|
|
71
|
+
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
|
|
72
|
+
Enabled: true
|
|
73
|
+
Lint/EmptyBlock: # new in 1.1
|
|
74
|
+
Enabled: true
|
|
75
|
+
Lint/EmptyClass: # new in 1.3
|
|
76
|
+
Enabled: true
|
|
77
|
+
Lint/EmptyInPattern: # new in 1.16
|
|
78
|
+
Enabled: true
|
|
79
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
|
80
|
+
Enabled: true
|
|
81
|
+
Lint/LambdaWithoutLiteralBlock: # new in 1.8
|
|
82
|
+
Enabled: true
|
|
83
|
+
Lint/NoReturnInBeginEndBlocks: # new in 1.2
|
|
84
|
+
Enabled: true
|
|
85
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
|
86
|
+
Enabled: true
|
|
87
|
+
Lint/NumberedParameterAssignment: # new in 1.9
|
|
88
|
+
Enabled: true
|
|
89
|
+
Lint/OrAssignmentToConstant: # new in 1.9
|
|
90
|
+
Enabled: true
|
|
91
|
+
Lint/RedundantDirGlobSort: # new in 1.8
|
|
92
|
+
Enabled: true
|
|
93
|
+
Lint/RefinementImportMethods: # new in 1.27
|
|
94
|
+
Enabled: true
|
|
95
|
+
Lint/RequireRangeParentheses: # new in 1.32
|
|
96
|
+
Enabled: true
|
|
97
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
|
98
|
+
Enabled: true
|
|
99
|
+
Lint/SymbolConversion: # new in 1.9
|
|
100
|
+
Enabled: true
|
|
101
|
+
Lint/ToEnumArguments: # new in 1.1
|
|
102
|
+
Enabled: true
|
|
103
|
+
Lint/TripleQuotes: # new in 1.9
|
|
104
|
+
Enabled: true
|
|
105
|
+
Lint/UnexpectedBlockArity: # new in 1.5
|
|
106
|
+
Enabled: true
|
|
107
|
+
Lint/UnmodifiedReduceAccumulator: # new in 1.1
|
|
108
|
+
Enabled: true
|
|
109
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
|
110
|
+
Enabled: true
|
|
111
|
+
Naming/BlockForwarding: # new in 1.24
|
|
112
|
+
Enabled: true
|
|
113
|
+
Security/CompoundHash: # new in 1.28
|
|
114
|
+
Enabled: true
|
|
115
|
+
Security/IoMethods: # new in 1.22
|
|
116
|
+
Enabled: true
|
|
117
|
+
Style/ArgumentsForwarding: # new in 1.1
|
|
118
|
+
Enabled: true
|
|
119
|
+
Style/CollectionCompact: # new in 1.2
|
|
120
|
+
Enabled: true
|
|
121
|
+
Style/DocumentDynamicEvalDefinition: # new in 1.1
|
|
122
|
+
Enabled: true
|
|
123
|
+
Style/EmptyHeredoc: # new in 1.32
|
|
124
|
+
Enabled: true
|
|
125
|
+
Style/EndlessMethod: # new in 1.8
|
|
126
|
+
Enabled: true
|
|
127
|
+
Style/EnvHome: # new in 1.29
|
|
128
|
+
Enabled: true
|
|
129
|
+
Style/FetchEnvVar: # new in 1.28
|
|
130
|
+
Enabled: true
|
|
131
|
+
Style/FileRead: # new in 1.24
|
|
132
|
+
Enabled: true
|
|
133
|
+
Style/FileWrite: # new in 1.24
|
|
134
|
+
Enabled: true
|
|
135
|
+
Style/HashConversion: # new in 1.10
|
|
136
|
+
Enabled: true
|
|
137
|
+
Style/HashExcept: # new in 1.7
|
|
138
|
+
Enabled: true
|
|
139
|
+
Style/IfWithBooleanLiteralBranches: # new in 1.9
|
|
140
|
+
Enabled: true
|
|
141
|
+
Style/InPatternThen: # new in 1.16
|
|
142
|
+
Enabled: true
|
|
143
|
+
Style/MagicCommentFormat: # new in 1.35
|
|
144
|
+
Enabled: true
|
|
145
|
+
Style/MapCompactWithConditionalBlock: # new in 1.30
|
|
146
|
+
Enabled: true
|
|
147
|
+
Style/MapToHash: # new in 1.24
|
|
148
|
+
Enabled: true
|
|
149
|
+
Style/MultilineInPatternThen: # new in 1.16
|
|
150
|
+
Enabled: true
|
|
151
|
+
Style/NegatedIfElseCondition: # new in 1.2
|
|
152
|
+
Enabled: true
|
|
153
|
+
Style/NestedFileDirname: # new in 1.26
|
|
154
|
+
Enabled: true
|
|
155
|
+
Style/NilLambda: # new in 1.3
|
|
156
|
+
Enabled: true
|
|
157
|
+
Style/NumberedParameters: # new in 1.22
|
|
158
|
+
Enabled: true
|
|
159
|
+
Style/NumberedParametersLimit: # new in 1.22
|
|
160
|
+
Enabled: true
|
|
161
|
+
Style/ObjectThen: # new in 1.28
|
|
162
|
+
Enabled: true
|
|
163
|
+
Style/OpenStructUse: # new in 1.23
|
|
164
|
+
Enabled: true
|
|
165
|
+
Style/QuotedSymbols: # new in 1.16
|
|
166
|
+
Enabled: true
|
|
167
|
+
Style/RedundantArgument: # new in 1.4
|
|
168
|
+
Enabled: true
|
|
169
|
+
Style/RedundantInitialize: # new in 1.27
|
|
170
|
+
Enabled: true
|
|
171
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
|
172
|
+
Enabled: true
|
|
173
|
+
Style/SelectByRegexp: # new in 1.22
|
|
174
|
+
Enabled: true
|
|
175
|
+
Style/StringChars: # new in 1.12
|
|
176
|
+
Enabled: true
|
|
177
|
+
Style/SwapValues: # new in 1.1
|
|
178
|
+
Enabled: true
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
dlss-capistrano-docker (1.0.0)
|
|
5
|
+
capistrano (~> 3.0)
|
|
6
|
+
capistrano-one_time_key
|
|
7
|
+
capistrano-shared_configs
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
airbrussh (1.4.1)
|
|
13
|
+
sshkit (>= 1.6.1, != 1.7.0)
|
|
14
|
+
ast (2.4.2)
|
|
15
|
+
byebug (11.1.3)
|
|
16
|
+
capistrano (3.17.1)
|
|
17
|
+
airbrussh (>= 1.0.0)
|
|
18
|
+
i18n
|
|
19
|
+
rake (>= 10.0.0)
|
|
20
|
+
sshkit (>= 1.9.0)
|
|
21
|
+
capistrano-one_time_key (0.1.0)
|
|
22
|
+
capistrano (~> 3.0)
|
|
23
|
+
capistrano-shared_configs (0.2.2)
|
|
24
|
+
concurrent-ruby (1.1.10)
|
|
25
|
+
i18n (1.12.0)
|
|
26
|
+
concurrent-ruby (~> 1.0)
|
|
27
|
+
json (2.6.2)
|
|
28
|
+
net-scp (1.2.1)
|
|
29
|
+
net-ssh (>= 2.6.5)
|
|
30
|
+
net-ssh (7.0.1)
|
|
31
|
+
parallel (1.22.1)
|
|
32
|
+
parser (3.1.2.1)
|
|
33
|
+
ast (~> 2.4.1)
|
|
34
|
+
rainbow (3.1.1)
|
|
35
|
+
rake (13.0.6)
|
|
36
|
+
regexp_parser (2.5.0)
|
|
37
|
+
rexml (3.2.5)
|
|
38
|
+
rubocop (1.36.0)
|
|
39
|
+
json (~> 2.3)
|
|
40
|
+
parallel (~> 1.10)
|
|
41
|
+
parser (>= 3.1.2.1)
|
|
42
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
43
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
44
|
+
rexml (>= 3.2.5, < 4.0)
|
|
45
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
|
46
|
+
ruby-progressbar (~> 1.7)
|
|
47
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
48
|
+
rubocop-ast (1.21.0)
|
|
49
|
+
parser (>= 3.1.1.0)
|
|
50
|
+
ruby-progressbar (1.11.0)
|
|
51
|
+
sshkit (1.21.3)
|
|
52
|
+
net-scp (>= 1.1.2)
|
|
53
|
+
net-ssh (>= 2.8.0)
|
|
54
|
+
unicode-display_width (2.3.0)
|
|
55
|
+
|
|
56
|
+
PLATFORMS
|
|
57
|
+
x86_64-darwin-21
|
|
58
|
+
|
|
59
|
+
DEPENDENCIES
|
|
60
|
+
bundler
|
|
61
|
+
byebug
|
|
62
|
+
dlss-capistrano-docker!
|
|
63
|
+
rake (>= 12.3.3)
|
|
64
|
+
rubocop (~> 1.0)
|
|
65
|
+
|
|
66
|
+
BUNDLED WITH
|
|
67
|
+
2.3.22
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# dlss-capistrano-docker
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/dlss-capistrano-docker)
|
|
4
|
+
|
|
5
|
+
This gem provides Capistrano Docker deployment tasks used by Stanford Libraries' Digital Library Systems and Services group.
|
|
6
|
+
|
|
7
|
+
It requires that the services to be run on a server be specified by a docker compose configuration file.
|
|
8
|
+
|
|
9
|
+
## Included Tasks
|
|
10
|
+
* `ssh`: establishes an SSH connection to the host running in environment, and changes into the current deployment directory.
|
|
11
|
+
* `honeybadger:notify`: notifies Honeybadger of deploy using curl (thus, ruby is not required on host).
|
|
12
|
+
* `docker:login`: log into Docker Hub. Logging in is required to avoid strict image download limits.
|
|
13
|
+
* `docker:logout`: log out of Docker Hub.
|
|
14
|
+
* `docker:prune`: prune docker artifacts to avoid filling disk space.
|
|
15
|
+
* `docker_compose:migrate`: migrate the database.
|
|
16
|
+
* `docker_compose:seed`: seed the database.
|
|
17
|
+
* `docker_compose:build`: build images for the services.
|
|
18
|
+
* `docker_compose:setup_rabbit`: create channel, queues, etc for RabbitMQ.
|
|
19
|
+
* `docker_compose:restart`: down then up services.
|
|
20
|
+
* `docker_compose:up`: stop services.
|
|
21
|
+
* `docker_compose:down`: tear down services.
|
|
22
|
+
* `docker_compose:copy_assets`: copy assets from a container to the server so they can be served by Apache.
|
|
23
|
+
* `docker_compose:dereference_linked_files`: turn linked files into actual files.
|
|
24
|
+
* `docker_compose:dereference_linked_dirs`: turn linked directories into actual directories containing actual files.
|
|
25
|
+
|
|
26
|
+
## Hooks
|
|
27
|
+
Hooks into the Capistrano lifecycle are provided for most of these tasks. These hooks can be controlled with variables, e.g., `docker_hub_use_hooks` to control the hooks for `docker:login` and `docker:logout`.
|
|
28
|
+
|
|
29
|
+
In addition to tasks included in this gem, a hook is provided for `shared_configs:update`.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
For an example of any of the following, see https://github.com/sul-dlss/happy-heron
|
|
33
|
+
|
|
34
|
+
### `Gemfile`
|
|
35
|
+
* Add `gem 'dlss-capistrano-docker', require: false` to the deployment group.
|
|
36
|
+
* Remove any gems that are removed from `Capfile` below.
|
|
37
|
+
* Move puma gem from development/test dependencies to the application dependencies. (Puma will be used as the application server instead of Passenger.)
|
|
38
|
+
|
|
39
|
+
### `Capfile`
|
|
40
|
+
* Remove any of the following:
|
|
41
|
+
```
|
|
42
|
+
require 'capistrano/bundler'
|
|
43
|
+
require 'capistrano/rails'
|
|
44
|
+
require 'capistrano/honeybadger'
|
|
45
|
+
require 'capistrano/passenger'
|
|
46
|
+
require 'whenever/capistrano'
|
|
47
|
+
require 'dlss/capistrano'
|
|
48
|
+
```
|
|
49
|
+
* Add `require 'dlss/docker/capistrano`
|
|
50
|
+
|
|
51
|
+
### `config/deploy.rb`
|
|
52
|
+
* For `:linked_files` remove `config/database.yml` and `config/secrets.yml` if present. Both of these will be provided by environment variables.
|
|
53
|
+
* For `:linked_dirs` remove `tmp/pids`, `tmp/cache`, `tmp/sockets`, `public/system` if present. `log` and `config/settings` should remain.
|
|
54
|
+
* Remove any sidekiq, sneakers, passenger, whenever, or shared_configs related settings.
|
|
55
|
+
* Add `set :docker_compose_file, 'docker-compose.prod.yml'` to reference the production docker-compose file.
|
|
56
|
+
* Optionally, add `set :docker_compose_seed_use_hooks, true` to perform seeding.
|
|
57
|
+
* Optionally, add `set :docker_compose_rabbitmq_use_hooks, true` to perform Rabbitmq setup.
|
|
58
|
+
* Note that there are other settings supported by this gem for additional configuration.
|
|
59
|
+
|
|
60
|
+
### `config/deploy/<environment>.rb`
|
|
61
|
+
* Each server should have the `app` role and any roles that correspond with profiles in the docker-compose file. This is what controls what services are run on the server.
|
|
62
|
+
|
|
63
|
+
### `config/puma.rb`
|
|
64
|
+
* Change `RAILS_MAX_THREAD` to `PUMA_MAX_THREAD` and `RAILS_MIN_THREAD` to `PUMA_MIN_THREAD`.
|
|
65
|
+
* Enable workers with `workers ENV.fetch('PUMA_WORKERS', 2)`
|
|
66
|
+
* Enable preload with `preload_app!`.
|
|
67
|
+
|
|
68
|
+
### `config/schedule.rb`
|
|
69
|
+
* Add `set :job_template, nil` to execute with sh instead of bash.
|
|
70
|
+
|
|
71
|
+
### `Dockerfile`
|
|
72
|
+
* When possible, base the image on Alpine (e.g., `FROM ruby:3.1-alpine`).
|
|
73
|
+
* Processes should run as the application user (e.g., `h2`) not root, with user id and group id set to match the server.
|
|
74
|
+
* If using Whenever, install Supercronic (which does not have to run as root) and write the crontab file during the build with `RUN sh -c 'bundle exec whenever . | tee -a config/crontab'`.
|
|
75
|
+
* When possible, write to both a log file and stdout.
|
|
76
|
+
* Precompile assets (`RUN bin/rails assets:precompile`) as part of the build. `SECRET_KEY_BASE` will need to be available for precompiling.
|
|
77
|
+
|
|
78
|
+
### `docker-compose.prod.yml`
|
|
79
|
+
* Duplicate configuration can be shared with fragments (e.g., `&environment` / `*environment`).
|
|
80
|
+
* The command for a container can be overridden with `command:`, e.g., `command: bin/bundle exec rake sneakers:run 2>&1 | tee -a log/sneakers.log`.
|
|
81
|
+
* Each service should be assigned to one or more profiles. These correspond to capistrano roles. For example:
|
|
82
|
+
```
|
|
83
|
+
profiles:
|
|
84
|
+
- cron
|
|
85
|
+
```
|
|
86
|
+
* Containers should link in the shared logs directory. For example:
|
|
87
|
+
```
|
|
88
|
+
volumes:
|
|
89
|
+
- /opt/app/h2/happy-heron/shared/log:/app/log
|
|
90
|
+
```
|
|
91
|
+
* Environment variables provided by the server should be passed through to the container. For example:
|
|
92
|
+
```
|
|
93
|
+
environment:
|
|
94
|
+
- HONEYBADGER_API_KEY
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `.dockerignore`
|
|
98
|
+
Ignore `public.assets`
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'bundler'
|
|
4
|
+
|
|
5
|
+
Dir.glob('lib/tasks/*.rake').each { |r| import r }
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
Bundler.setup(:default, :development)
|
|
9
|
+
rescue Bundler::BundlerError => e
|
|
10
|
+
$stderr.puts e.message
|
|
11
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
|
12
|
+
exit e.status_code
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "dlss-capistrano-docker"
|
|
7
|
+
s.version = '1.0.0'
|
|
8
|
+
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.authors = ['Justin Littman']
|
|
11
|
+
s.email = ['justinlittman@stanford.edu']
|
|
12
|
+
s.summary = "Capistrano recipes for use in SUL/DLSS projects for docker deployment"
|
|
13
|
+
s.homepage = 'https://github.com/sul-dlss/dlss-capistrano-docker'
|
|
14
|
+
s.license = "Apache-2.0"
|
|
15
|
+
|
|
16
|
+
s.required_ruby_version = '>= 3.0', '< 4'
|
|
17
|
+
|
|
18
|
+
# All dependencies are runtime dependencies, since this gem's "runtime" is
|
|
19
|
+
# the dependent gem's development-time.
|
|
20
|
+
s.add_dependency "capistrano", "~> 3.0"
|
|
21
|
+
s.add_dependency "capistrano-one_time_key"
|
|
22
|
+
s.add_dependency "capistrano-shared_configs"
|
|
23
|
+
|
|
24
|
+
s.add_development_dependency 'bundler'
|
|
25
|
+
s.add_development_dependency 'byebug'
|
|
26
|
+
s.add_development_dependency 'rake', '>= 12.3.3'
|
|
27
|
+
s.add_development_dependency 'rubocop', '~> 1.0'
|
|
28
|
+
|
|
29
|
+
s.files = `git ls-files`.split($/)
|
|
30
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
31
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
32
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
33
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Capistrano plugin hook to set default values
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
set :docker_prune_use_hooks, fetch(:docker_prune_use_hooks, true)
|
|
7
|
+
set :docker_hub_use_hooks, fetch(:docker_hub_use_hooks, true)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Integrate hooks into Capistrano
|
|
12
|
+
namespace :deploy do
|
|
13
|
+
before :starting, :add_docker_hooks do
|
|
14
|
+
invoke 'docker:add_prune_hooks' if fetch(:docker_prune_use_hooks)
|
|
15
|
+
invoke 'docker:add_hub_hooks' if fetch(:docker_hub_use_hooks)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
namespace :docker do
|
|
20
|
+
task :add_prune_hooks do
|
|
21
|
+
# Cleaning up docker on start so that images/logs are available for troubleshooting.
|
|
22
|
+
after 'deploy:starting', 'docker:prune'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
task :add_hub_hooks do
|
|
26
|
+
after 'deploy:starting', 'docker:login'
|
|
27
|
+
after 'deploy:finishing', 'docker:logout'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc 'Log in to Docker Hub'
|
|
31
|
+
task :login do
|
|
32
|
+
on roles(:app) do
|
|
33
|
+
execute(:docker, 'login', '-u', '$DOCKER_USERNAME', '-p', '$DOCKER_PASSWORD')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
desc 'Log out of Docker Hub'
|
|
38
|
+
task :logout do
|
|
39
|
+
on roles(:app) do
|
|
40
|
+
execute(:docker, 'logout')
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
desc 'Prune unused images/containers'
|
|
45
|
+
task :prune do
|
|
46
|
+
on roles(:app) do
|
|
47
|
+
execute(:docker, 'system', 'prune', '-af')
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Capistrano plugin hook to set default values
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
set :docker_compose_file, fetch(:docker_compose_file, 'docker-compose.yml')
|
|
7
|
+
|
|
8
|
+
set :docker_compose_migrate_use_hooks, fetch(:docker_compose_migrate_use_hooks, true)
|
|
9
|
+
set :migration_role, fetch(:migration_role, :db)
|
|
10
|
+
set :migration_servers, -> { primary(fetch(:migration_role)) }
|
|
11
|
+
set :migration_command, fetch(:migration_command, 'db:migrate')
|
|
12
|
+
|
|
13
|
+
set :docker_compose_seed_use_hooks, fetch(:docker_compose_seed_use_hooks, false)
|
|
14
|
+
set :seed_command, fetch(:migration_command, 'db:seed')
|
|
15
|
+
|
|
16
|
+
set :docker_compose_build_use_hooks, fetch(:docker_compose_build_use_hooks, true)
|
|
17
|
+
set :build_roles, fetch(:build_roles, [:app])
|
|
18
|
+
set :dereference_files, fetch(:dereference_files)
|
|
19
|
+
set :dereference_dirs, fetch(:dereference_dirs, [])
|
|
20
|
+
|
|
21
|
+
set :docker_compose_rabbitmq_use_hooks, fetch(:docker_compose_rabbit_use_hooks, false)
|
|
22
|
+
set :rabbitmq_role, fetch(:rabbitmq_role, :app)
|
|
23
|
+
set :rabbitmq_servers, -> { primary(fetch(:rabbitmq_role)) }
|
|
24
|
+
set :rabbitmq_command, fetch(:rabbitmq_command, 'rabbitmq:setup')
|
|
25
|
+
|
|
26
|
+
set :docker_compose_restart_use_hooks, fetch(:docker_compose_restart_use_hooks, true)
|
|
27
|
+
|
|
28
|
+
set :copy_assets_role, fetch(:copy_assets_role, :app)
|
|
29
|
+
set :assets_path, fetch(:assets_path, 'public/assets')
|
|
30
|
+
set :docker_compose_copy_assets_use_hooks, fetch(:docker_compose_copy_assets_use_hooks, true)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Integrate hooks into Capistrano
|
|
35
|
+
namespace :deploy do
|
|
36
|
+
before :starting, :add_docker_hooks do
|
|
37
|
+
invoke 'docker_compose:add_migrate_hooks' if fetch(:docker_compose_migrate_use_hooks)
|
|
38
|
+
invoke 'docker_compose:add_seed_hooks' if fetch(:docker_compose_seed_use_hooks)
|
|
39
|
+
invoke 'docker_compose:add_build_hooks' if fetch(:docker_compose_build_use_hooks)
|
|
40
|
+
invoke 'docker_compose:add_rabbitmq_hooks' if fetch(:docker_compose_rabbitmq_use_hooks)
|
|
41
|
+
invoke 'docker_compose:add_restart_hooks' if fetch(:docker_compose_restart_use_hooks)
|
|
42
|
+
invoke 'docker_compose:add_copy_assets_hooks' if fetch(:docker_compose_copy_assets_use_hooks)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
namespace :docker_compose do
|
|
47
|
+
task :add_migrate_hooks do
|
|
48
|
+
after 'deploy:publishing', 'docker_compose:migrate'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
task :add_seed_hooks do
|
|
52
|
+
after 'deploy:publishing', 'docker_compose:seed'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
task :add_build_hooks do
|
|
56
|
+
after 'deploy:updating', 'docker_compose:build'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
task :add_rabbitmq_hooks do
|
|
60
|
+
after 'deploy:publishing', 'docker_compose:setup_rabbitmq'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
task :add_restart_hooks do
|
|
64
|
+
after 'deploy:publishing', 'docker_compose:restart'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
task :add_copy_assets_hooks do
|
|
68
|
+
after 'deploy:publishing', 'docker_compose:copy_assets'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
desc 'Migrate database'
|
|
72
|
+
task :migrate do
|
|
73
|
+
on fetch(:migration_servers) do
|
|
74
|
+
within current_path do
|
|
75
|
+
execute(:docker, 'compose', '-f', fetch(:docker_compose_file), 'run', 'app', 'bin/rails',
|
|
76
|
+
fetch(:migration_command))
|
|
77
|
+
end
|
|
78
|
+
info 'Db migrated'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
desc 'Seed database'
|
|
83
|
+
task :seed do
|
|
84
|
+
on fetch(:migration_servers) do
|
|
85
|
+
within current_path do
|
|
86
|
+
execute(:docker, 'compose', '-f', fetch(:docker_compose_file), 'run', 'app', 'bin/rails',
|
|
87
|
+
fetch(:seed_command))
|
|
88
|
+
end
|
|
89
|
+
info 'Db migrated'
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
desc 'Build images'
|
|
94
|
+
# Docker build does not dereference symlinks.
|
|
95
|
+
task build: [:dereference_linked_files, :dereference_linked_dirs] do
|
|
96
|
+
on roles(fetch(:build_roles)) do
|
|
97
|
+
info 'Building images'
|
|
98
|
+
within release_path do
|
|
99
|
+
execute(:docker, 'compose', '-f', fetch(:docker_compose_file), 'build')
|
|
100
|
+
end
|
|
101
|
+
info 'Docker images built'
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
desc 'Setup RabbitMQ'
|
|
106
|
+
task :setup_rabbitmq do
|
|
107
|
+
on fetch(:rabbitmq_servers) do
|
|
108
|
+
within current_path do
|
|
109
|
+
execute(:docker, 'compose', '-f', fetch(:docker_compose_file), 'run', 'app', 'bin/rake',
|
|
110
|
+
fetch(:rabbitmq_command))
|
|
111
|
+
end
|
|
112
|
+
info 'RabbitMQ setup'
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
desc 'Restart containers (down then up)'
|
|
117
|
+
task restart: [:down, :up]
|
|
118
|
+
|
|
119
|
+
desc 'Start containers'
|
|
120
|
+
task :up do
|
|
121
|
+
on roles(:app) do |server|
|
|
122
|
+
cmd = cmd_with_profiles(server)
|
|
123
|
+
cmd.concat(['up', '-d'])
|
|
124
|
+
within current_path do
|
|
125
|
+
execute(*cmd)
|
|
126
|
+
info 'Containers started'
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
desc 'Tear down containers'
|
|
132
|
+
task :down do
|
|
133
|
+
on roles(:app) do |server|
|
|
134
|
+
cmd = cmd_with_profiles(server)
|
|
135
|
+
cmd.concat(['down'])
|
|
136
|
+
within current_path do
|
|
137
|
+
execute(*cmd)
|
|
138
|
+
info 'Containers down'
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
desc 'Copy assets'
|
|
144
|
+
task :copy_assets do
|
|
145
|
+
assets_path = fetch(:assets_path)
|
|
146
|
+
on roles(fetch(:copy_assets_role)) do
|
|
147
|
+
within current_path do
|
|
148
|
+
# Can't do a direct copy to public/assets because it is a symlink.
|
|
149
|
+
execute(:docker, 'compose', '-f', fetch(:docker_compose_file), 'cp',
|
|
150
|
+
'app:/app/public/assets', '.')
|
|
151
|
+
execute(:rm, '-fr', "#{assets_path}/*")
|
|
152
|
+
execute(:mkdir, assets_path)
|
|
153
|
+
execute(:cp, 'assets/*', "#{assets_path}/")
|
|
154
|
+
end
|
|
155
|
+
info 'Assets copied'
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
desc 'Dereference linked files'
|
|
160
|
+
task :dereference_linked_files do
|
|
161
|
+
dereference_files = fetch(:dereference_files) || fetch(:linked_files, [])
|
|
162
|
+
next if dereference_files.empty?
|
|
163
|
+
|
|
164
|
+
on roles(fetch(:build_roles)) do
|
|
165
|
+
dereference_files.each do |file|
|
|
166
|
+
target = release_path.join(file)
|
|
167
|
+
source = shared_path.join(file)
|
|
168
|
+
execute :rm, target if test "[ -L #{target} ]"
|
|
169
|
+
execute :cp, source, target
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
desc 'Dereference linked directories'
|
|
175
|
+
task :dereference_linked_dirs do
|
|
176
|
+
dereference_dirs = fetch(:dereference_dirs)
|
|
177
|
+
next if dereference_dirs.empty?
|
|
178
|
+
|
|
179
|
+
on roles(fetch(:build_roles)) do
|
|
180
|
+
dereference_dirs.each do |dir|
|
|
181
|
+
target = release_path.join(dir)
|
|
182
|
+
source = shared_path.join(dir)
|
|
183
|
+
next unless test "[ -L #{target} ]"
|
|
184
|
+
|
|
185
|
+
execute :rm, target
|
|
186
|
+
execute :cp, '-r', source, target
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def cmd_with_profiles(server)
|
|
192
|
+
cmd = [:docker, 'compose', '-f', fetch(:docker_compose_file)]
|
|
193
|
+
server.roles.each do |role|
|
|
194
|
+
cmd.concat(['--profile', role.to_s])
|
|
195
|
+
end
|
|
196
|
+
cmd
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Capistrano plugin hook to set default values
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
set :honeybadger_use_hooks, fetch(:honeybadger_use_hooks, true)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Integrate hooks into Capistrano
|
|
11
|
+
namespace :deploy do
|
|
12
|
+
before :starting, :add_honeybadger_hooks do
|
|
13
|
+
invoke 'honeybadger:add_hooks' if fetch(:honeybadger_use_hooks)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
namespace :honeybadger do
|
|
18
|
+
task :add_hooks do
|
|
19
|
+
after 'deploy:finishing', 'honeybadger:notify'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Replaces honeybadger:deploy to use curl instead of invoking ruby.
|
|
23
|
+
# Adapted from https://github.com/honeybadger-io/honeybadger-ruby/blob/master/vendor/capistrano-honeybadger/lib/capistrano/tasks/deploy.cap
|
|
24
|
+
desc 'Notify Honeybadger of a deploy (using the API via curl)'
|
|
25
|
+
task notify: %i[deploy:set_current_revision] do
|
|
26
|
+
fetch(:honeybadger_server) do
|
|
27
|
+
if (s = primary(:app))
|
|
28
|
+
set(:honeybadger_server, s.select?({ exclude: :no_release }) ? s : nil)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if (server = fetch(:honeybadger_server))
|
|
33
|
+
revision = fetch(:current_revision)
|
|
34
|
+
|
|
35
|
+
on server do |_host|
|
|
36
|
+
info 'Notifying Honeybadger of deploy.'
|
|
37
|
+
|
|
38
|
+
honeybadger_config = nil
|
|
39
|
+
within release_path do
|
|
40
|
+
honeybadger_config = capture(:cat, 'config/honeybadger.yml')
|
|
41
|
+
end
|
|
42
|
+
remote_api_key = YAML.safe_load(honeybadger_config)['api_key']
|
|
43
|
+
remote_api_key = capture(:echo, '$HONEYBADGER_API_KEY') if remote_api_key.nil?
|
|
44
|
+
|
|
45
|
+
options = {
|
|
46
|
+
'deploy[environment]' => fetch(:honeybadger_env, fetch(:rails_env, 'production')),
|
|
47
|
+
'deploy[local_username]' => fetch(:honeybadger_user, ENV['USER'] || ENV.fetch('USERNAME', nil)),
|
|
48
|
+
'deploy[revision]' => revision,
|
|
49
|
+
'deploy[repository]' => fetch(:repo_url),
|
|
50
|
+
'api_key' => fetch(:honeybadger_api_key, ENV.fetch('HONEYBADGER_API_KEY', nil)) || remote_api_key
|
|
51
|
+
}
|
|
52
|
+
data = options.to_a.map { |pair| pair.join('=') }.join('&')
|
|
53
|
+
execute(:curl, '--no-progress-meter', '--data', "\"#{data}\"", 'https://api.honeybadger.io/v1/deploys')
|
|
54
|
+
info 'Honeybadger notification complete.'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Capistrano plugin hook to set default values
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
set :shared_configs_use_hooks, fetch(:shared_configs_use_hooks, true)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Integrate hooks into Capistrano
|
|
11
|
+
namespace :deploy do
|
|
12
|
+
before :starting, :add_shared_configs_hooks do
|
|
13
|
+
invoke 'shared_configs:add_hooks' if fetch(:shared_configs_use_hooks)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
namespace :shared_configs do
|
|
18
|
+
task :add_hooks do
|
|
19
|
+
before 'deploy:updating', 'shared_configs:update'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
desc 'ssh to the current directory on the server'
|
|
4
|
+
task :ssh do
|
|
5
|
+
on roles(:app), primary: true do |host|
|
|
6
|
+
command = "cd #{fetch(:deploy_to)}/current && exec $SHELL -l"
|
|
7
|
+
puts command if fetch(:log_level) == :debug
|
|
8
|
+
exec "ssh -l #{host.user} #{host.hostname} -p #{host.port || 22} -t '#{command}'"
|
|
9
|
+
end
|
|
10
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dlss-capistrano-docker
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Justin Littman
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2022-09-28 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: capistrano
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: capistrano-one_time_key
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: capistrano-shared_configs
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: byebug
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rake
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 12.3.3
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 12.3.3
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.0'
|
|
111
|
+
description:
|
|
112
|
+
email:
|
|
113
|
+
- justinlittman@stanford.edu
|
|
114
|
+
executables: []
|
|
115
|
+
extensions: []
|
|
116
|
+
extra_rdoc_files: []
|
|
117
|
+
files:
|
|
118
|
+
- ".gitignore"
|
|
119
|
+
- ".rubocop.yml"
|
|
120
|
+
- Gemfile
|
|
121
|
+
- Gemfile.lock
|
|
122
|
+
- README.md
|
|
123
|
+
- Rakefile
|
|
124
|
+
- dlss-capistrano-docker.gemspec
|
|
125
|
+
- lib/dlss/docker/capistrano.rb
|
|
126
|
+
- lib/dlss/docker/capistrano/tasks/docker.rake
|
|
127
|
+
- lib/dlss/docker/capistrano/tasks/docker_compose.rake
|
|
128
|
+
- lib/dlss/docker/capistrano/tasks/honeybadger.rake
|
|
129
|
+
- lib/dlss/docker/capistrano/tasks/shared_configs.rake
|
|
130
|
+
- lib/dlss/docker/capistrano/tasks/ssh.rake
|
|
131
|
+
homepage: https://github.com/sul-dlss/dlss-capistrano-docker
|
|
132
|
+
licenses:
|
|
133
|
+
- Apache-2.0
|
|
134
|
+
metadata:
|
|
135
|
+
rubygems_mfa_required: 'true'
|
|
136
|
+
post_install_message:
|
|
137
|
+
rdoc_options: []
|
|
138
|
+
require_paths:
|
|
139
|
+
- lib
|
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '3.0'
|
|
145
|
+
- - "<"
|
|
146
|
+
- !ruby/object:Gem::Version
|
|
147
|
+
version: '4'
|
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
153
|
+
requirements: []
|
|
154
|
+
rubygems_version: 3.3.7
|
|
155
|
+
signing_key:
|
|
156
|
+
specification_version: 4
|
|
157
|
+
summary: Capistrano recipes for use in SUL/DLSS projects for docker deployment
|
|
158
|
+
test_files: []
|