docker_deploy 0.1.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 +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +83 -0
- data/Rakefile +2 -0
- data/docker_deploy.gemspec +23 -0
- data/lib/docker_deploy.rb +33 -0
- data/lib/docker_deploy/context.rb +38 -0
- data/lib/docker_deploy/stage.rb +48 -0
- data/lib/docker_deploy/task.rb +72 -0
- data/lib/docker_deploy/version.rb +3 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9c0a6af4b603facef00bb395c7598fbc4265605a
|
4
|
+
data.tar.gz: fc8a912ed44073f881859ae0934d9b59411daa52
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0eb9eb0c1975c9cdcb44a9e10507046593caa4298ccd683e5c2e2367d9ed9a6e58f6fe936b83108c246b881c3104e06565546ce3b74cbd7a6f29563658fe3d9e
|
7
|
+
data.tar.gz: 0555bb0bce47a2a169fa29c24e72d35af502a1c6535a0fae1b9269b6eabdad1efc73a2d57cc803be1c3725922eb6690a4f28a55b5f6e2c251ab79853101649d5
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jonas Nicklas and Lisa Hammarström
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# DockerDeploy
|
2
|
+
|
3
|
+
Deploy docker containers via Rake. This is especially useful for dockerized
|
4
|
+
Ruby applications.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
``` ruby
|
11
|
+
gem 'docker_deploy'
|
12
|
+
```
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
In your Rakefile define your deployment setup like this:
|
17
|
+
|
18
|
+
``` ruby
|
19
|
+
DockerDeploy.task do
|
20
|
+
image "elabs/projectpuzzle"
|
21
|
+
|
22
|
+
env "RAILS_ENV" => "production"
|
23
|
+
|
24
|
+
port 80 => 3000
|
25
|
+
|
26
|
+
stage :staging do
|
27
|
+
server "ubuntu@staging.projectpuzzle.com"
|
28
|
+
|
29
|
+
env "CANONICAL_HOST" => "staging.projectpuzzle.com"
|
30
|
+
|
31
|
+
host "http://staging.projectpuzzle.com"
|
32
|
+
end
|
33
|
+
|
34
|
+
stage :production do
|
35
|
+
server "ubuntu@app1.projectpuzzle.com"
|
36
|
+
server "ubuntu@app2.projectpuzzle.com"
|
37
|
+
|
38
|
+
env "CANONICAL_HOST" => "projectpuzzle.com"
|
39
|
+
|
40
|
+
host "http://projectpuzzle.com"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
If you're packaging a Rails application you might want to add this in
|
46
|
+
`lib/tasks/docker.rake` instead.
|
47
|
+
|
48
|
+
DockerDeploy has now generated a ton of rake tasks for you. You can inspect
|
49
|
+
which ones are available by running:
|
50
|
+
|
51
|
+
``` sh
|
52
|
+
rake -T docker
|
53
|
+
```
|
54
|
+
|
55
|
+
To deploy your application to the server, the server must have docker installed
|
56
|
+
and running and available without `sudo`. See the docker documentation on setting
|
57
|
+
this up. Try running:
|
58
|
+
|
59
|
+
```
|
60
|
+
rake docker:staging:deploy
|
61
|
+
```
|
62
|
+
|
63
|
+
This should package your application, send it to the docker registry, pull it down
|
64
|
+
on the remote server and finally run it as a docker container.
|
65
|
+
|
66
|
+
## Adding a Dockerfile
|
67
|
+
|
68
|
+
These instructions assume you already have a Dockerfile set up. If you want to
|
69
|
+
package a Rails application, this might give you something to get you started:
|
70
|
+
|
71
|
+
``` dockerfile
|
72
|
+
FROM rails:onbuild
|
73
|
+
RUN bundle exec rake assets:precompile
|
74
|
+
```
|
75
|
+
|
76
|
+
## Known issues
|
77
|
+
|
78
|
+
* The `console` task is currently broken. We were unable to figure out how to
|
79
|
+
create an interactive session via `sshkit`.
|
80
|
+
|
81
|
+
## License
|
82
|
+
|
83
|
+
[MIT](LICENSE.txt)
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'docker_deploy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "docker_deploy"
|
8
|
+
spec.version = DockerDeploy::VERSION
|
9
|
+
spec.authors = ["Jonas Nicklas", "Lisa Hammarström"]
|
10
|
+
spec.email = ["jonas.nicklas@gmail.com", "lisa@elabs.se"]
|
11
|
+
spec.summary = %q{Deploy Docker containers via Rake}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "sshkit", "~> 1.5"
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "sshkit"
|
2
|
+
require "sshkit/dsl"
|
3
|
+
require "shellwords"
|
4
|
+
|
5
|
+
require "docker_deploy/version"
|
6
|
+
require "docker_deploy/context"
|
7
|
+
require "docker_deploy/stage"
|
8
|
+
require "docker_deploy/task"
|
9
|
+
|
10
|
+
# Improvement on the broken piece of crap text formatter in SSHKit.
|
11
|
+
class PlainFormatter < SSHKit::Formatter::Abstract
|
12
|
+
def initialize(io = $stdout)
|
13
|
+
@io = io
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(obj)
|
17
|
+
if obj.is_a?(SSHKit::Command)
|
18
|
+
@io.write(obj.stdout)
|
19
|
+
else
|
20
|
+
@io.write(obj.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :<<, :write
|
25
|
+
end
|
26
|
+
|
27
|
+
SSHKit.configure do |config|
|
28
|
+
config.output = PlainFormatter.new($stdout)
|
29
|
+
config.command_map["docker"] = "/usr/bin/env docker"
|
30
|
+
# config.output_verbosity = Logger::DEBUG
|
31
|
+
end
|
32
|
+
|
33
|
+
SSHKit::Backend::Netssh.config.pty = true
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module DockerDeploy
|
2
|
+
class Context
|
3
|
+
attr_reader :stages, :variables, :ports
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@stages = []
|
7
|
+
@variables = {}
|
8
|
+
@ports = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def env(variables = {})
|
12
|
+
@variables.merge!(variables)
|
13
|
+
end
|
14
|
+
|
15
|
+
def port(ports = {})
|
16
|
+
@ports.merge!(ports)
|
17
|
+
end
|
18
|
+
|
19
|
+
def image(name = nil)
|
20
|
+
@image = name if name
|
21
|
+
@image
|
22
|
+
end
|
23
|
+
|
24
|
+
def container
|
25
|
+
@image.split("/").last
|
26
|
+
end
|
27
|
+
|
28
|
+
def revision
|
29
|
+
@revision ||= `git rev-parse HEAD`.chomp[0...8]
|
30
|
+
end
|
31
|
+
|
32
|
+
def stage(name, &block)
|
33
|
+
stage = Stage.new(self, name)
|
34
|
+
stage.instance_eval(&block)
|
35
|
+
@stages << stage
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module DockerDeploy
|
2
|
+
class Stage
|
3
|
+
attr_reader :name, :servers, :variables
|
4
|
+
|
5
|
+
def initialize(context, name)
|
6
|
+
@context = context
|
7
|
+
@name = name
|
8
|
+
@servers = []
|
9
|
+
@variables = {}
|
10
|
+
@ports = {}
|
11
|
+
@deploy = ["docker:build", "docker:push", :pull, :restart]
|
12
|
+
end
|
13
|
+
|
14
|
+
def env(variables = {})
|
15
|
+
@variables.merge!(variables)
|
16
|
+
end
|
17
|
+
|
18
|
+
def port(ports = {})
|
19
|
+
@ports.merge!(ports)
|
20
|
+
end
|
21
|
+
|
22
|
+
def deploy(sequence = nil)
|
23
|
+
@deploy = sequence if sequence
|
24
|
+
@deploy
|
25
|
+
end
|
26
|
+
|
27
|
+
def host(name = nil)
|
28
|
+
@host = name if name
|
29
|
+
@host
|
30
|
+
end
|
31
|
+
|
32
|
+
def server(server)
|
33
|
+
@servers << SSHKit::Host.new(server)
|
34
|
+
end
|
35
|
+
|
36
|
+
def mappings
|
37
|
+
@context.ports.merge(@ports).each_with_object("") do |(from, to), s|
|
38
|
+
s << " -p %d:%d " % [from, to]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def options
|
43
|
+
@context.variables.merge(@variables).each_with_object("") do |(k, v), s|
|
44
|
+
s << " -e %s=%s " % [Shellwords.escape(k), Shellwords.escape(v)] if v.present?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module DockerDeploy
|
2
|
+
def self.task(ns = :docker, &block)
|
3
|
+
main = TOPLEVEL_BINDING.eval("self")
|
4
|
+
|
5
|
+
context = Context.new
|
6
|
+
context.instance_eval(&block)
|
7
|
+
|
8
|
+
main.instance_eval do
|
9
|
+
namespace ns do
|
10
|
+
|
11
|
+
desc "Builds the application into a docker image"
|
12
|
+
task :build do
|
13
|
+
sh "docker build -t #{context.image}:#{context.revision} -t #{context.image}:latest ."
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Push the application's docker image to the docker registry"
|
17
|
+
task :push do
|
18
|
+
sh "docker push #{context.image}"
|
19
|
+
end
|
20
|
+
|
21
|
+
context.stages.each do |stage|
|
22
|
+
namespace stage.name do
|
23
|
+
|
24
|
+
desc "deploy the application"
|
25
|
+
task deploy: stage.deploy
|
26
|
+
|
27
|
+
desc "Pull down code from the docker registry"
|
28
|
+
task :pull do
|
29
|
+
on stage.servers do
|
30
|
+
execute :docker, "pull #{context.image}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Stop the application and remove its container"
|
35
|
+
task :stop do
|
36
|
+
on stage.servers do
|
37
|
+
execute :docker, "inspect #{context.container} 2>&1 > /dev/null && docker stop #{context.container} && docker rm #{context.container} || true"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Start the application in a container using the latest image."
|
42
|
+
task :start do
|
43
|
+
on stage.servers do
|
44
|
+
execute :docker, "run -d #{stage.mappings} #{stage.options} --name #{context.container} #{context.image}:latest"
|
45
|
+
|
46
|
+
puts "\n\nStarted: #{stage.host}\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Run migrations in the latest image."
|
51
|
+
task :migrate do
|
52
|
+
on stage.servers.first do
|
53
|
+
execute :docker, "run #{stage.options} -i -t --rm=true #{context.image}:latest bundle exec rake db:create db:migrate"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Run a Rails console in the container"
|
58
|
+
task :console do
|
59
|
+
puts "Console is currently broken :("
|
60
|
+
puts "Run:\n"
|
61
|
+
puts "ssh #{stage.servers.first}"
|
62
|
+
puts "docker run #{stage.options} -i -t --rm=true #{context.image}:latest bundle exec rails console"
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Restart the running container."
|
66
|
+
task restart: [:stop, :start]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docker_deploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonas Nicklas
|
8
|
+
- Lisa Hammarström
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-10-31 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sshkit
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.5'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.5'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.6'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.6'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
description:
|
57
|
+
email:
|
58
|
+
- jonas.nicklas@gmail.com
|
59
|
+
- lisa@elabs.se
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- docker_deploy.gemspec
|
70
|
+
- lib/docker_deploy.rb
|
71
|
+
- lib/docker_deploy/context.rb
|
72
|
+
- lib/docker_deploy/stage.rb
|
73
|
+
- lib/docker_deploy/task.rb
|
74
|
+
- lib/docker_deploy/version.rb
|
75
|
+
homepage: ''
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.2.2
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Deploy Docker containers via Rake
|
99
|
+
test_files: []
|