capistrano_dockerbuild 1.0.0 → 1.1.1
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 +4 -4
- data/.rubocop.yml +4 -0
- data/Gemfile +1 -1
- data/README-deploy-compose.md +5 -5
- data/README-deploy-swarm.md +18 -13
- data/README.md +27 -15
- data/capistrano-docker-build.gemspec +4 -2
- data/lib/capistrano/dsl/paths.rb +5 -5
- data/lib/capistrano/tasks/dockerbuild.rake +210 -50
- data/lib/capistrano/tasks/dockercompose.rake +0 -2
- data/lib/capistrano/tasks/dockerswarm.rake +0 -1
- data/spec/capistrano/docker/build_spec.rb +8 -8
- data/spec/spec_helper.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ce4c53bd25ff86f3b5e2237b0605b9253b3627a
|
4
|
+
data.tar.gz: 8c139b49008bdc0716fee7999e0d63b36e229234
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7f6fa7928ff96fb9571bba1c0edcfda610e94bb0cd6e7d3a12473ee4a577d40385dc0b785be2bbf1c751026160264a5ac93b5bef065f57530522887f6e0ec6f
|
7
|
+
data.tar.gz: 57a5f9acf9bef342fc51be5b8796abc74742643921f0eaa62cc11c0012aa79130c634d024469f992e1a60e17ebda3a56cf4def2ae69e487f13a10b4b50103c85
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/README-deploy-compose.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
_This content is specific to deployments using docker-compose; if you haven't yet reviewed README.md, you should probably start there._
|
2
2
|
|
3
3
|
# docker:compose
|
4
4
|
|
@@ -11,16 +11,16 @@ There is no blue/green, rolling update, auto rollback on failure, or anything ev
|
|
11
11
|
|
12
12
|
### Roles:
|
13
13
|
|
14
|
-
This
|
14
|
+
This plugin adds the `docker_compose` role, identifying hosts where the docker_compose_file should be copied and ran.
|
15
15
|
|
16
|
-
If the `docker_build` role is defined, it will identify the source of the docker_compose_file
|
16
|
+
If the `docker_build` role is defined, it will identify the source of the docker_compose_file, otherwise the current project directory is the source.
|
17
17
|
|
18
18
|
```ruby
|
19
|
-
# using
|
19
|
+
# using server syntax
|
20
20
|
server 'my.remote.server', roles: %w{docker_compose}
|
21
21
|
server 'my_other.remote.server', roles: %w{docker_compose}
|
22
22
|
|
23
|
-
# or using
|
23
|
+
# or using role syntax
|
24
24
|
role :docker_compose, %w{localhost} # places localhost within the docker_compose role
|
25
25
|
|
26
26
|
# The docker_build role is used to identify the source of the docker_compose_file
|
data/README-deploy-swarm.md
CHANGED
@@ -1,7 +1,24 @@
|
|
1
|
-
|
1
|
+
_This content is specific to deployments using Docker Swarm; if you haven't yet reviewed README.md, you should probably start there._
|
2
2
|
|
3
3
|
# docker:swarm
|
4
4
|
|
5
|
+
This deploy strategy copies a docker-compose.yml file to the docker swarms you specify, and then runs `docker stack up` across the whole lot.
|
6
|
+
|
7
|
+
Deploying to a single swarm member should be enough to deploy across the entire swarm, so choosing one deploy host per swarm is probably the best course of action.
|
8
|
+
|
9
|
+
### Roles:
|
10
|
+
|
11
|
+
This plugin adds the `docker_swarm` role, identifying hosts where the `docker_compose_file` should be copied and ran.
|
12
|
+
|
13
|
+
If the `docker_build` role is defined, it will identify the source of the `docker_compose_file`, otherwise the current project directory is the source.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# using server syntax
|
17
|
+
server 'my.swarm.host', roles: %w{docker_swarm}
|
18
|
+
|
19
|
+
# or using role syntax
|
20
|
+
role :docker_swarm, %w{my.swarm.host}
|
21
|
+
```
|
5
22
|
|
6
23
|
|
7
24
|
|
@@ -16,15 +33,3 @@ set :docker_compose_path -> { deploy_path } # path on remot
|
|
16
33
|
|
17
34
|
set :dockerswarm_deployhook, true # set false to skip default deploy hook; default is true
|
18
35
|
```
|
19
|
-
|
20
|
-
----
|
21
|
-
|
22
|
-
```ruby
|
23
|
-
set :docker_compose_project -> { fetch(:application) } # (required) name of the docker-compose project
|
24
|
-
set :docker_compose_file, 'docker-compose.yml' # name of compose file to use for deploy
|
25
|
-
set :docker_compose_cmd, 'docker-compose' # name/path to `docker-compose` command on host
|
26
|
-
set :docker_compose_opts, nil # general args for `docker-compose`; default is none; (ex: '--project-name myproject --tls')
|
27
|
-
set :docker_compose_up_opts, '-d --no-build --remove-orphans' # args for `docker-compose up` command; these are the defaults
|
28
|
-
set :docker_compose_stop_opts, nil # args for `docker-compose stop` command; default is none; (ex: '--timeout 20')
|
29
|
-
set :dockercompose_deployhook, true # set false to skip default deploy hook; default is true
|
30
|
-
```
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# capistrano_dockerbuild
|
2
2
|
|
3
|
-
Docker image creation, tagging, and repository tasks
|
3
|
+
Docker image creation, tagging, and repository tasks for Capistrano v3
|
4
4
|
|
5
5
|
```sh
|
6
|
-
cap production docker:
|
6
|
+
cap production docker:deploy # build or promote image and push to repository
|
7
7
|
```
|
8
8
|
|
9
9
|
This plugin also hooks into the default `cap <environment> deploy` flow as a build action. See [Usage](#usage) for more details.
|
@@ -47,7 +47,7 @@ role :docker_build, %w{localhost} # role syntax, making localhost the build age
|
|
47
47
|
server 'my.build.server', roles: %w{docker_build} # server syntax, declaring a remote server
|
48
48
|
```
|
49
49
|
|
50
|
-
If no `:docker_build` host is defined, the docker image will be built directly from the current working project directory. A maximum of one `:docker_build` host can be defined
|
50
|
+
If no `:docker_build` host is defined, the docker image will be built directly from the current working project directory. A maximum of one `:docker_build` host can be defined.
|
51
51
|
|
52
52
|
#### Run a deploy:
|
53
53
|
|
@@ -74,27 +74,37 @@ Run `cap -T docker:` for details
|
|
74
74
|
```ruby
|
75
75
|
set :docker_build_image -> { fetch(:application) } # (required) name of the image
|
76
76
|
set :docker_build_opts, nil # additional `docker build` args; default is none; (ex: '--pull --no-cache --force-rm')
|
77
|
-
set :
|
77
|
+
set :docker_build_custom_tag, nil # custom tag name for this build, if any
|
78
|
+
set :docker_build_image_latest_tag?, true # generates a 'latest' tag when true
|
79
|
+
set :docker_build_image_release_tag?, true # generates a release tag when true
|
80
|
+
set :docker_build_image_revision_tag?, true # generates a scm revision tag when true
|
81
|
+
set :docker_build_image_shortrev_tag?, true # generates a short-form scm revision tag when true
|
78
82
|
set :docker_repo_url, nil # name/url of remote docker image repository for push
|
79
|
-
set :docker_build_context, '.' # context passed to `docker build` (
|
83
|
+
set :docker_build_context, '.' # context passed to `docker build` (from :build_dir)
|
80
84
|
set :dockerfile, 'Dockerfile' # name of Dockerfile to use for build
|
81
85
|
set :docker_cmd, 'docker' # name/path to `docker` command on build host
|
82
|
-
set :
|
86
|
+
set :build_dir, '.' # directory within source repository to run builds from on remote build hosts
|
87
|
+
set :docker_build_promote_image, nil # repository/image:tag to promote instead of building a new image
|
83
88
|
set :dockerbuild_deployhook, true # set false to skip default deploy hook; default is true
|
84
89
|
set :dockerbuild_trim_release_roles, true # set false to prevent no_release from being auto-added to all non docker_build servers
|
85
90
|
```
|
86
91
|
|
87
|
-
### Created
|
88
|
-
|
92
|
+
### Created docker image tags
|
93
|
+
|
94
|
+
By default the `docker:build` task creates several image tags on the build host upon completion, all pointing to the same final image. Unless otherwise altered, all created tags are also pushed up to the docker image repository during the `docker:push` task. You may not want your repository (or build host) filled with a ton of tags, so this gem offers a few ways to control that sprawl.
|
95
|
+
|
96
|
+
You can selectively turn off remotely pushed tags by setting these to `false`, as desired:
|
97
|
+
|
98
|
+
- `:docker_build_image_latest_tag?`
|
99
|
+
- `:docker_build_image_release_tag?`
|
100
|
+
- `:docker_build_image_revision_tag?`
|
101
|
+
- `:docker_build_image_shortrev_tag?`
|
102
|
+
|
103
|
+
`:docker_build_custom_tag` is optional; if you don't want a custom tag created, don't set one.
|
89
104
|
|
90
|
-
docker_build_image_latest_tag,
|
91
|
-
docker_build_image_revision_tag,
|
92
|
-
docker_build_image_shortrev_tag,
|
93
|
-
docker_build_image_release_tag,
|
94
|
-
docker_build_image_tag,
|
95
105
|
|
96
106
|
### Deployment to docker-compose, Docker Swarm, Kubernetes, Marathon, etc
|
97
|
-
The primary
|
107
|
+
The primary goal of this gem is currently to provide tasks for Docker image creation and repository push/transfer. However, some deployment tasks are also included, should you decide to use them. Each deploy strategy needs to be specifically enabled by a separate `requires` statement within your Capfile.
|
98
108
|
|
99
109
|
Refer to the specific deployment documentation for details:
|
100
110
|
|
@@ -105,9 +115,11 @@ Refer to the specific deployment documentation for details:
|
|
105
115
|
|
106
116
|
Because.
|
107
117
|
|
118
|
+
There are at least a dozen other Capistrano + Docker gems out there, but none seemed to match my preferred docker philosophy: Docker images should be built once and then promoted up to higher environments as they pass acceptance tests. This gem aims to provide that type of workflow.
|
119
|
+
|
108
120
|
## Development
|
109
121
|
|
110
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
122
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
111
123
|
|
112
124
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
113
125
|
|
@@ -6,12 +6,14 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'capistrano_dockerbuild'
|
9
|
-
spec.version = '1.
|
9
|
+
spec.version = '1.1.1'
|
10
10
|
spec.authors = ['Eric Shorkey']
|
11
11
|
spec.email = ['eric.shorkey@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'docker build/push plugin for Capistrano'
|
14
|
-
spec.description = 'Build, push and deploy
|
14
|
+
spec.description = 'Build, push, promote, and deploy Docker container images with Capistrano.' \
|
15
|
+
' Build images locally or from a build server, rebuild or promote images across deployment environments.' \
|
16
|
+
' Deployments for docker-compose and docker swarm.'
|
15
17
|
spec.homepage = 'https://github.com/eshork/capistrano_dockerbuild'
|
16
18
|
spec.license = 'MIT'
|
17
19
|
|
data/lib/capistrano/dsl/paths.rb
CHANGED
@@ -4,16 +4,16 @@ module Capistrano
|
|
4
4
|
module DSL
|
5
5
|
module Paths
|
6
6
|
|
7
|
-
def
|
8
|
-
fetch(:
|
7
|
+
def build_dir
|
8
|
+
fetch(:build_dir)
|
9
9
|
end
|
10
10
|
|
11
11
|
# directory within which the build is to be executed
|
12
12
|
# respects relative paths (not starting with /)
|
13
13
|
def build_path
|
14
|
-
return deploy_path.join(fetch(:current_directory, 'current')) if
|
15
|
-
return Pathname.new(
|
16
|
-
return deploy_path.join(fetch(:current_directory, 'current'),
|
14
|
+
return deploy_path.join(fetch(:current_directory, 'current')) if build_dir.nil?
|
15
|
+
return Pathname.new(build_dir.strip) if build_dir.strip[0] == '/'
|
16
|
+
return deploy_path.join(fetch(:current_directory, 'current'), build_dir)
|
17
17
|
end
|
18
18
|
|
19
19
|
end
|
@@ -2,6 +2,74 @@
|
|
2
2
|
|
3
3
|
namespace :docker do
|
4
4
|
|
5
|
+
class DockerImage
|
6
|
+
def initialize(repo = nil, name = nil, tag = nil)
|
7
|
+
@repository = repo.nil? || repo.empty? ? nil : repo
|
8
|
+
@name = name.nil? || name.empty? ? nil : name
|
9
|
+
@tag = tag.nil? || tag.empty? ? nil : tag
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
return nil unless @name
|
14
|
+
"#{@repository ? "#{@repository}/" : nil}#{@name}#{@tag ? ":#{@tag}" : nil}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def repo
|
18
|
+
return @repository
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
return @name
|
23
|
+
end
|
24
|
+
|
25
|
+
def tag
|
26
|
+
return @tag
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid?
|
30
|
+
return false if @repository.nil? && @name.nil? && @tag.nil?
|
31
|
+
unless @repository.nil?
|
32
|
+
return false if (@repository =~ /^([\d\w])*(:)?\d*$/).nil?
|
33
|
+
end
|
34
|
+
return false if (@name =~ /^([\d\w])*$/).nil?
|
35
|
+
unless @tag.nil?
|
36
|
+
return false if (@tag =~ /^([\d\w-])*$/).nil?
|
37
|
+
end
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.from_str(str)
|
42
|
+
return new unless str
|
43
|
+
repo_str = repo_from_str(str)
|
44
|
+
name_str = name_from_str(str)
|
45
|
+
tag_str = tag_from_str(str)
|
46
|
+
return new repo_str, name_str, tag_str
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.repo_from_str(str)
|
50
|
+
last_slash = str.rindex('/')
|
51
|
+
return nil unless last_slash
|
52
|
+
return str[0...last_slash]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.name_from_str(str)
|
56
|
+
# remove any repo bits
|
57
|
+
repo_str = repo_from_str(str)
|
58
|
+
str = str.sub("#{repo_str}/", '') if repo_str
|
59
|
+
# remove any tag bits
|
60
|
+
str.split(':')[0]
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.tag_from_str(str)
|
64
|
+
# remove any repo bits
|
65
|
+
repo_str = repo_from_str(str)
|
66
|
+
str = str.sub("#{repo_str}/", '') if repo_str
|
67
|
+
# remove any name bits
|
68
|
+
str_split = str.split(':')
|
69
|
+
return str_split.size > 1 ? str_split[1] : nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
5
73
|
# Any extra command-line opts you'd like to insert into the `docker build` command
|
6
74
|
# Normally has no preset value (fastest option), but a popular full-rebuild-every-time (thorough build) selection is '--pull --no-cache --force-rm'
|
7
75
|
def docker_build_opts
|
@@ -26,13 +94,13 @@ namespace :docker do
|
|
26
94
|
(fetch(:docker_build_image) { fetch(:application) }) || raise('unable to discern docker_build_image name; specify :application or :docker_build_image')
|
27
95
|
end
|
28
96
|
|
29
|
-
def
|
30
|
-
fetch(:
|
97
|
+
def docker_build_custom_tag
|
98
|
+
return nil unless fetch(:docker_build_custom_tag, nil)
|
99
|
+
return "#{docker_build_image}:#{fetch(:docker_build_custom_tag)}"
|
31
100
|
end
|
32
101
|
|
33
|
-
def
|
34
|
-
return fetch(:
|
35
|
-
set(:docker_build_image_tag, "#{docker_build_image}:#{docker_build_tag}")
|
102
|
+
def docker_build_image_latest_tag?
|
103
|
+
return fetch(:docker_build_image_latest_tag?, true)
|
36
104
|
end
|
37
105
|
|
38
106
|
def docker_build_image_latest_tag
|
@@ -40,17 +108,29 @@ namespace :docker do
|
|
40
108
|
set(:docker_build_image_latest_tag, "#{docker_build_image}:latest")
|
41
109
|
end
|
42
110
|
|
111
|
+
def docker_build_image_release_tag?
|
112
|
+
return fetch(:docker_build_image_release_tag?, true)
|
113
|
+
end
|
114
|
+
|
43
115
|
def docker_build_image_release_tag
|
44
116
|
return fetch(:docker_build_image_release_tag) ||
|
45
117
|
set(:docker_build_image_release_tag, "#{docker_build_image}:release-#{release_timestamp}")
|
46
118
|
end
|
47
119
|
|
120
|
+
def docker_build_image_revision_tag?
|
121
|
+
return fetch(:docker_build_image_revision_tag?, true)
|
122
|
+
end
|
123
|
+
|
48
124
|
def docker_build_image_revision_tag
|
49
125
|
return nil unless fetch(:current_revision)
|
50
126
|
return fetch(:docker_build_image_revision_tag) ||
|
51
127
|
set(:docker_build_image_revision_tag, "#{docker_build_image}:REVISION-#{fetch(:current_revision)}")
|
52
128
|
end
|
53
129
|
|
130
|
+
def docker_build_image_shortrev_tag?
|
131
|
+
return fetch(:docker_build_image_shortrev_tag?, true)
|
132
|
+
end
|
133
|
+
|
54
134
|
def docker_build_image_shortrev_tag
|
55
135
|
return nil unless fetch(:current_revision)
|
56
136
|
return fetch(:docker_build_image_shortrev_tag) ||
|
@@ -58,13 +138,13 @@ namespace :docker do
|
|
58
138
|
end
|
59
139
|
|
60
140
|
def docker_build_image_tags
|
61
|
-
[
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
141
|
+
tags = []
|
142
|
+
tags << docker_build_custom_tag if docker_build_custom_tag
|
143
|
+
tags << docker_build_image_release_tag if docker_build_image_release_tag?
|
144
|
+
tags << docker_build_image_revision_tag if docker_build_image_revision_tag?
|
145
|
+
tags << docker_build_image_shortrev_tag if docker_build_image_shortrev_tag?
|
146
|
+
tags << docker_build_image_latest_tag if docker_build_image_latest_tag?
|
147
|
+
return tags.uniq.compact
|
68
148
|
end
|
69
149
|
|
70
150
|
def docker_build_image_tags_opt
|
@@ -84,12 +164,17 @@ namespace :docker do
|
|
84
164
|
docker_build_image_tags.map{|t| docker_repo_tag(t)}
|
85
165
|
end
|
86
166
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
167
|
+
def docker_build_promote_image
|
168
|
+
promote_image_tag = fetch(:docker_build_promote_image, nil)
|
169
|
+
image_name = DockerImage.from_str(promote_image_tag)
|
170
|
+
image_name = DockerImage.new(image_name.repo ? image_name.repo : docker_repo_url,
|
171
|
+
image_name.name ? image_name.name : docker_build_image,
|
172
|
+
image_name.tag ? image_name.tag : docker_build_tag)
|
173
|
+
promote_tag = image_name.to_s
|
174
|
+
return promote_tag
|
91
175
|
end
|
92
176
|
|
177
|
+
|
93
178
|
task :check_docker_build_role do
|
94
179
|
if roles(:docker_build).empty?
|
95
180
|
run_locally do
|
@@ -132,7 +217,7 @@ namespace :docker do
|
|
132
217
|
end
|
133
218
|
end
|
134
219
|
|
135
|
-
task :local_build_deps => [:local_build_warning]
|
220
|
+
task :local_build_deps => [:local_build_warning, :set_current_revision]
|
136
221
|
|
137
222
|
task :build_local => :local_build_deps do
|
138
223
|
current_build_dir = pwd
|
@@ -147,7 +232,7 @@ namespace :docker do
|
|
147
232
|
end
|
148
233
|
end
|
149
234
|
|
150
|
-
task :remote_build_deps => [:check_docker_build_role, :check_docker_build_root]
|
235
|
+
task :remote_build_deps => [:check_docker_build_role, :check_docker_build_root, :set_current_revision]
|
151
236
|
|
152
237
|
task :build_remote => :remote_build_deps do
|
153
238
|
on roles(:docker_build).first do |buildremote|
|
@@ -164,79 +249,154 @@ namespace :docker do
|
|
164
249
|
end
|
165
250
|
end
|
166
251
|
|
167
|
-
|
252
|
+
|
253
|
+
task :set_current_revision => 'deploy:set_current_revision'
|
254
|
+
|
255
|
+
task :get_docker_build_image_id => :set_current_revision do
|
256
|
+
|
257
|
+
run_locally do
|
258
|
+
docker_build_image_tags.each do |image_tag|
|
259
|
+
docker_build_image_id = capture docker_cmd, :image, :ls, '-q', image_tag
|
260
|
+
unless docker_build_image_id.empty?
|
261
|
+
set(:docker_build_image_id, docker_build_image_id)
|
262
|
+
break
|
263
|
+
end
|
264
|
+
end
|
265
|
+
unless fetch(:docker_build_image_id)
|
266
|
+
fatal 'unable to discern image id'
|
267
|
+
raise 'missing image id'
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
desc "Push the 'latest' image to the repository"
|
274
|
+
task :push do
|
168
275
|
if roles(:docker_build).empty?
|
169
|
-
invoke 'docker:
|
276
|
+
invoke 'docker:push_local'
|
170
277
|
else
|
171
|
-
invoke 'docker:
|
278
|
+
invoke 'docker:push_remote'
|
172
279
|
end
|
173
280
|
end
|
174
281
|
|
175
|
-
task :
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
282
|
+
task :push_local => :get_docker_build_image_id do
|
283
|
+
run_locally do
|
284
|
+
unless docker_repo_url
|
285
|
+
warn ':docker_repo_url not defined! No push destination'
|
286
|
+
next
|
287
|
+
end
|
288
|
+
docker_build_image_tags.each do |local_tag|
|
289
|
+
repo_tag = docker_repo_tag(local_tag)
|
290
|
+
next unless repo_tag
|
291
|
+
run_locally do
|
180
292
|
execute docker_cmd, :tag,
|
181
|
-
|
293
|
+
fetch(:docker_build_image_id),
|
294
|
+
repo_tag
|
295
|
+
execute docker_cmd, :push,
|
182
296
|
repo_tag
|
183
297
|
end
|
184
298
|
end
|
185
299
|
end
|
186
300
|
end
|
187
301
|
|
188
|
-
task :
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
302
|
+
task :push_remote => [:check_docker_build_role, :get_docker_build_image_id] do
|
303
|
+
on roles(:docker_build).first do # |buildremote|
|
304
|
+
unless docker_repo_url
|
305
|
+
warn ':docker_repo_url not defined! No push destination'
|
306
|
+
next
|
307
|
+
end
|
308
|
+
docker_build_image_tags.each do |local_tag|
|
309
|
+
repo_tag = docker_repo_tag(local_tag)
|
310
|
+
next unless repo_tag
|
311
|
+
run_locally do
|
193
312
|
execute docker_cmd, :tag,
|
194
|
-
|
313
|
+
fetch(:docker_build_image_id),
|
314
|
+
repo_tag
|
315
|
+
execute docker_cmd, :push,
|
195
316
|
repo_tag
|
196
317
|
end
|
197
318
|
end
|
198
319
|
end
|
199
320
|
end
|
200
321
|
|
201
|
-
desc
|
202
|
-
task :
|
322
|
+
desc 'Build the docker image'
|
323
|
+
task :build do
|
324
|
+
invoke 'docker:build_decision'
|
325
|
+
end
|
326
|
+
|
327
|
+
desc 'Build and push docker image'
|
328
|
+
task :build_push do
|
329
|
+
invoke 'docker:build'
|
330
|
+
invoke 'docker:push'
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
desc 'Promote an existing docker image (pull and retag)'
|
335
|
+
task :promote do
|
203
336
|
if roles(:docker_build).empty?
|
204
|
-
invoke 'docker:
|
337
|
+
invoke 'docker:promote_local'
|
205
338
|
else
|
206
|
-
invoke 'docker:
|
339
|
+
invoke 'docker:promote_remote'
|
207
340
|
end
|
208
341
|
end
|
209
342
|
|
210
|
-
task :
|
343
|
+
task :check_docker_build_promote_image do
|
344
|
+
unless fetch :docker_build_promote_image
|
345
|
+
run_locally do
|
346
|
+
fatal ':docker_build_promote_image setting is required for promote task'
|
347
|
+
raise 'missing :docker_build_promote_image'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
unless DockerImage.from_str(docker_build_promote_image).valid?
|
351
|
+
run_locally do
|
352
|
+
fatal ":docker_build_promote_image setting is not valid: '#{fetch(:docker_build_promote_image)}' => '#{docker_build_promote_image}'"
|
353
|
+
raise 'invalid :docker_build_promote_image'
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
task :promote_local => :check_docker_build_promote_image do
|
211
359
|
run_locally do
|
212
|
-
|
360
|
+
source_tag = docker_build_promote_image
|
361
|
+
info "Promoting image: #{source_tag}"
|
362
|
+
execute docker_cmd, :pull, source_tag
|
363
|
+
|
213
364
|
docker_repo_tags.each do |repo_tag|
|
365
|
+
next if repo_tag == source_tag
|
366
|
+
info "Promoted to: #{repo_tag}"
|
367
|
+
execute docker_cmd, :tag,
|
368
|
+
source_tag,
|
369
|
+
repo_tag
|
214
370
|
execute docker_cmd, :push,
|
215
371
|
repo_tag
|
216
372
|
end
|
373
|
+
|
217
374
|
end
|
218
375
|
end
|
219
376
|
|
220
|
-
task :
|
377
|
+
task :promote_remote => :check_docker_build_promote_image do
|
221
378
|
on roles(:docker_build).first do # |buildremote|
|
222
|
-
|
379
|
+
source_tag = docker_build_promote_image
|
380
|
+
info "Promoting image: #{source_tag}"
|
381
|
+
execute docker_cmd, :pull, source_tag
|
382
|
+
|
223
383
|
docker_repo_tags.each do |repo_tag|
|
384
|
+
next if repo_tag == source_tag
|
385
|
+
info "Promoted to: #{repo_tag}"
|
386
|
+
execute docker_cmd, :tag,
|
387
|
+
source_tag,
|
388
|
+
repo_tag
|
224
389
|
execute docker_cmd, :push,
|
225
390
|
repo_tag
|
226
391
|
end
|
392
|
+
|
227
393
|
end
|
228
394
|
end
|
229
395
|
|
230
|
-
desc 'Build the docker container image'
|
231
|
-
task :build do
|
232
|
-
invoke 'docker:build_decision'
|
233
|
-
end
|
234
396
|
|
235
|
-
desc '
|
236
|
-
task :build_push
|
237
|
-
|
238
|
-
invoke 'docker:push'
|
239
|
-
end
|
397
|
+
desc '(alias for docker:build_push)'
|
398
|
+
task :deploy => :build_push
|
399
|
+
|
240
400
|
|
241
401
|
# Default `cap env deploy` flow hook
|
242
402
|
task :capdeploy_hook do
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'byebug'
|
4
3
|
require 'tempfile'
|
5
4
|
|
6
5
|
namespace :docker do
|
@@ -94,7 +93,6 @@ namespace :docker do
|
|
94
93
|
download! docker_compose_path.join(docker_compose_file), tmp_file_path
|
95
94
|
end
|
96
95
|
else
|
97
|
-
# byebug
|
98
96
|
invoke 'docker:compose:local_source_warning'
|
99
97
|
run_locally do
|
100
98
|
warn "fetching #{docker_compose_file}"
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
RSpec.describe Capistrano::
|
6
|
-
it 'has a version number' do
|
7
|
-
|
8
|
-
end
|
5
|
+
# RSpec.describe Capistrano::Dockerbuild do
|
6
|
+
# it 'has a version number' do
|
7
|
+
# expect(Capistrano::Docker::Build::VERSION).not_to be nil
|
8
|
+
# end
|
9
9
|
|
10
|
-
it 'does something useful' do
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
10
|
+
# it 'does something useful' do
|
11
|
+
# expect(false).to eq(true)
|
12
|
+
# end
|
13
|
+
# end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano_dockerbuild
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Shorkey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capistrano
|
@@ -52,8 +52,9 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '12.0'
|
55
|
-
description: Build, push and deploy
|
56
|
-
|
55
|
+
description: Build, push, promote, and deploy Docker container images with Capistrano.
|
56
|
+
Build images locally or from a build server, rebuild or promote images across deployment
|
57
|
+
environments. Deployments for docker-compose and docker swarm.
|
57
58
|
email:
|
58
59
|
- eric.shorkey@gmail.com
|
59
60
|
executables:
|