dockerploy 0.0.2
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 +15 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +43 -0
- data/Rakefile +7 -0
- data/bin/dockerploy +7 -0
- data/d.sh +3 -0
- data/dockerploy.gemspec +28 -0
- data/lib/dockerploy.rb +16 -0
- data/lib/dockerploy/cli.rb +54 -0
- data/lib/dockerploy/configuration.rb +54 -0
- data/lib/dockerploy/core_ext/hash.rb +27 -0
- data/lib/dockerploy/deploy.rb +77 -0
- data/lib/dockerploy/image.rb +25 -0
- data/lib/dockerploy/shell_client.rb +16 -0
- data/lib/dockerploy/ssh_client.rb +53 -0
- data/lib/dockerploy/version.rb +4 -0
- data/spec/fixtures/config.yml +16 -0
- data/spec/fixtures/config_with_env_file.yml +17 -0
- data/spec/fixtures/config_with_tagging.yml +17 -0
- data/spec/fixtures/config_with_volumes.yml +20 -0
- data/spec/fixtures/test.yml +2 -0
- data/spec/lib/dockerploy/cli_spec.rb +57 -0
- data/spec/lib/dockerploy/deploy_spec.rb +76 -0
- data/spec/spec_helper.rb +10 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTcwNmE2ZjEzM2Q3ZjBhZTEzZDA1NGVjODU3OWI1ODBhODZlMzc3Mw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjY2ZWNmNzM2Y2Y2Y2Q2ZjZkNTM4OTMyZWY1MTRhNmFhMWExMzhmNw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDc0Zjk0MWFlYzM1N2YyOTZjZjk1MThmMmEzOTQxOGZkZmNjMTJmMzVhODhj
|
10
|
+
NjcxODk0ODZjYTE0ZjliOGNlOWFlNDAxYzE3ZGIxY2EyYWI0MzM4MjRlMDBl
|
11
|
+
YjYzMDc2OThmMjYzZjc3Mjc3Y2IzMjNiYjQ2NDg1NTBjNTk5NjE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YTdjOGQ5YmUzYTk0MTM3OWE5MGFkNjAyOWE1NTBiNTAxMGVhYTI4NTYyZTli
|
14
|
+
NWE1ODMzMGU4MGE5Mjk5NDk4NGI4MTAxZjY5MzZhYTM5YWQyMTM1MGI3MmU2
|
15
|
+
YTQ4NTU1YTRlNTM1NGU0MDcwMzFiNWZjOGVkODBhYTdjMTQ5MDQ=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Sunjin Lee
|
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,43 @@
|
|
1
|
+
# Dockerploy
|
2
|
+
|
3
|
+
Deploy dockerized an application
|
4
|
+
[](https://travis-ci.org/viki-org/dockerploy)
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'dockerploy'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install dockerploy
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
To build an image
|
22
|
+
|
23
|
+
dockerploy build
|
24
|
+
|
25
|
+
To push an image
|
26
|
+
|
27
|
+
dockerploy push
|
28
|
+
|
29
|
+
To pull an image on server
|
30
|
+
|
31
|
+
dockerploy pull staging
|
32
|
+
|
33
|
+
To deploy an application
|
34
|
+
|
35
|
+
dockerploy deploy staging
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
1. Fork it
|
40
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
41
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
42
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
43
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/dockerploy
ADDED
data/dockerploy.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dockerploy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'dockerploy'
|
8
|
+
spec.version = Dockerploy::VERSION
|
9
|
+
spec.authors = ['Sunjin Lee']
|
10
|
+
spec.email = ['styner32@gmail.com']
|
11
|
+
spec.description = 'Deploy dockerized an application'
|
12
|
+
spec.summary = 'Deploy dockerized an application'
|
13
|
+
spec.homepage = 'https://github.com/viki-org/dockerploy'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^spec\//)
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 1.9.3'
|
22
|
+
spec.add_dependency 'thor', '~> 0.19'
|
23
|
+
spec.add_dependency 'mono_logger', '~> 1.1.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
end
|
data/lib/dockerploy.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'dockerploy/core_ext/hash'
|
2
|
+
|
3
|
+
require 'dockerploy/version'
|
4
|
+
require 'dockerploy/ssh_client'
|
5
|
+
require 'dockerploy/shell_client'
|
6
|
+
require 'dockerploy/cli'
|
7
|
+
require 'mono_logger'
|
8
|
+
|
9
|
+
# Dockerploy
|
10
|
+
module Dockerploy
|
11
|
+
extend self
|
12
|
+
|
13
|
+
attr_accessor :logger
|
14
|
+
end
|
15
|
+
|
16
|
+
Dockerploy.logger = MonoLogger.new(STDOUT)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'dockerploy'
|
2
|
+
require 'thor'
|
3
|
+
require 'yaml'
|
4
|
+
require 'dockerploy/configuration'
|
5
|
+
require 'dockerploy/deploy'
|
6
|
+
require 'dockerploy/image'
|
7
|
+
|
8
|
+
module Dockerploy
|
9
|
+
# The command-line interface for Dockerploy
|
10
|
+
class CLI < Thor
|
11
|
+
class_option :config, aliases: ['-c'], type: :string
|
12
|
+
|
13
|
+
def initialize(args = [], opts = {}, config = {})
|
14
|
+
super(args, opts, config)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'ps ENVIRONMENT', 'Show running containers'
|
18
|
+
def ps(environment)
|
19
|
+
config = configuration(environment.to_sym)
|
20
|
+
return unless config.servers
|
21
|
+
config.servers.each do |server|
|
22
|
+
ssh_client = SSHClient.new(server[:host], server[:username], server[:password], server[:port])
|
23
|
+
ssh_client.command(sprintf('docker ps | grep %s', config.application_name))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'build', 'build an image'
|
28
|
+
def build
|
29
|
+
Image.new(configuration).build
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'push', 'push an image'
|
33
|
+
def push
|
34
|
+
Image.new(configuration).push
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'pull', 'pull an image'
|
38
|
+
def pull(environment)
|
39
|
+
Image.new(configuration(environment.to_sym)).pull
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'deploy', 'deploy an application'
|
43
|
+
def deploy(environment)
|
44
|
+
config = configuration(environment.to_sym)
|
45
|
+
Deploy.new(config).deploy
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def configuration(env = nil)
|
51
|
+
@configuration ||= Configuration.new(env: env)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Dockerploy
|
2
|
+
class Configuration
|
3
|
+
NoEnvError = Class.new(StandardError)
|
4
|
+
FileNotFound = Class.new(StandardError)
|
5
|
+
DEFAULT_CONFIG_FILE = 'docker/config.yml'.freeze
|
6
|
+
|
7
|
+
attr_reader :env, :application_name, :docker_host, :image_name
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@config_file = options.fetch(:config_file, DEFAULT_CONFIG_FILE)
|
11
|
+
@env = options.fetch(:env)
|
12
|
+
@env = @env.to_sym if @env
|
13
|
+
raise FileNotFound unless File.exist?(@config_file)
|
14
|
+
config = YAML.load_file(@config_file).symbolize_keys
|
15
|
+
@application_name = config.fetch(:application_name)
|
16
|
+
@docker_host = config.fetch(:docker_host)
|
17
|
+
@image_name = config.fetch(:image_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def servers
|
21
|
+
raise NoEnvError if @env.nil?
|
22
|
+
options[@env][:servers]
|
23
|
+
end
|
24
|
+
|
25
|
+
def volumes
|
26
|
+
raise NoEnvError if @env.nil?
|
27
|
+
options[@env][:volumes]
|
28
|
+
end
|
29
|
+
|
30
|
+
def env_file
|
31
|
+
raise NoEnvError if @env.nil?
|
32
|
+
options[@env][:env_file]
|
33
|
+
end
|
34
|
+
|
35
|
+
def branch
|
36
|
+
raise NoEnvError if @env.nil?
|
37
|
+
options[@env][:branch]
|
38
|
+
end
|
39
|
+
|
40
|
+
def tagging?
|
41
|
+
raise NoEnvError if @env.nil?
|
42
|
+
options[@env][:tagging]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def options
|
48
|
+
@options ||= begin
|
49
|
+
raise FileNotFound unless File.exist?(@config_file)
|
50
|
+
YAML.load_file(@config_file).symbolize_keys
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Extentions for hash
|
2
|
+
class Hash
|
3
|
+
def symbolize_keys
|
4
|
+
_deep_transform_keys_in_object(self) do |key|
|
5
|
+
begin
|
6
|
+
key.to_sym
|
7
|
+
rescue StandardError
|
8
|
+
key
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def _deep_transform_keys_in_object(object, &block)
|
16
|
+
case object
|
17
|
+
when Hash
|
18
|
+
object.each_with_object({}) do |(key, value), result|
|
19
|
+
result[yield(key)] = _deep_transform_keys_in_object(value, &block)
|
20
|
+
end
|
21
|
+
when Array
|
22
|
+
object.map { |e| _deep_transform_keys_in_object(e, &block) }
|
23
|
+
else
|
24
|
+
object
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Dockerploy
|
2
|
+
class Deploy
|
3
|
+
SSH_PORT = 22
|
4
|
+
HTTP_PORT = 80
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy(ssh_client, server)
|
11
|
+
container_name = sprintf('%s_%s', @config.application_name, server[:container][:http_port])
|
12
|
+
ssh_client.command(sprintf('docker rm -f %s', container_name))
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(ssh_client, server)
|
16
|
+
option_delimiter = ' '
|
17
|
+
command = sprintf('docker run -d --name %s_%s', @config.application_name, server[:container][:http_port])
|
18
|
+
command << option_delimiter + hostname_option
|
19
|
+
command << option_delimiter + port_option(server)
|
20
|
+
command << option_delimiter + volume_option
|
21
|
+
command << option_delimiter + environment_variables_option
|
22
|
+
command << option_delimiter + @config.image_name
|
23
|
+
ssh_client.command(command)
|
24
|
+
end
|
25
|
+
|
26
|
+
def deploy
|
27
|
+
create_tag if @config.tagging?
|
28
|
+
@config.servers.each do |server|
|
29
|
+
ssh_client = SSHClient.new(server[:host], server[:username], server[:password], server[:port])
|
30
|
+
destroy(ssh_client, server)
|
31
|
+
run(ssh_client, server)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def create_tag
|
38
|
+
tag_name = sprintf('%s-%s', @config.env, Time.now.strftime('%Y%m%dT%H%M'))
|
39
|
+
command = sprintf('git tag %s %s && git push origin %s', tag_name, @config.branch, tag_name)
|
40
|
+
ShellClient.new.command(command)
|
41
|
+
end
|
42
|
+
|
43
|
+
def volume_option
|
44
|
+
volumes = @config.volumes
|
45
|
+
result = ''
|
46
|
+
if volumes
|
47
|
+
volumes.each { |volume| result << sprintf('-v %s:%s ', volume[:volume][:host], volume[:volume][:guest]) }
|
48
|
+
end
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def environment_variables_option
|
53
|
+
env_file = @config.env_file
|
54
|
+
result = ''
|
55
|
+
if env_file
|
56
|
+
if File.exist?(env_file)
|
57
|
+
environment_variables = YAML.load_file(env_file).symbolize_keys
|
58
|
+
environment_variables.each do |k, v|
|
59
|
+
result << sprintf("-e %s='%s' ", k.upcase, v)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
result.strip
|
64
|
+
end
|
65
|
+
|
66
|
+
def port_option(server)
|
67
|
+
container_config = server[:container]
|
68
|
+
result = ''
|
69
|
+
result << sprintf('-p %s:%s:%s ', container_config[:host], container_config[:ssh_port], SSH_PORT)
|
70
|
+
result << sprintf('-p %s:%s:%s', container_config[:host], container_config[:http_port], HTTP_PORT)
|
71
|
+
end
|
72
|
+
|
73
|
+
def hostname_option
|
74
|
+
sprintf('--hostname %s', @config.application_name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Dockerploy
|
2
|
+
class Image
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
end
|
6
|
+
|
7
|
+
def build
|
8
|
+
command = sprintf('env DOCKER_HOST=%s docker build -t %s .', @config.docker_host, @config.image_name)
|
9
|
+
ShellClient.new.command(command)
|
10
|
+
end
|
11
|
+
|
12
|
+
def push
|
13
|
+
command = sprintf('env DOCKER_HOST=%s docker push %s', @config.docker_host, @config.image_name)
|
14
|
+
ShellClient.new.command(command)
|
15
|
+
end
|
16
|
+
|
17
|
+
def pull
|
18
|
+
return unless @config.servers
|
19
|
+
@config.servers.each do |server|
|
20
|
+
ssh_client = SSHClient.new(server[:host], server[:username], server[:password], server[:port])
|
21
|
+
ssh_client.command(sprintf('docker pull %s', @config.image_name))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dockerploy
|
2
|
+
# Wrapper for local shell command
|
3
|
+
class ShellClient
|
4
|
+
def initialize
|
5
|
+
end
|
6
|
+
|
7
|
+
def command(command)
|
8
|
+
system(command)
|
9
|
+
unless $?.success?
|
10
|
+
Dockerploy.logger.info sprintf('Exit Code: %d', $?.exitstatus)
|
11
|
+
return false
|
12
|
+
end
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
module Dockerploy
|
4
|
+
# Wrapper for shell command over ssh
|
5
|
+
class SSHClient
|
6
|
+
attr_accessor :host, :username, :password, :port
|
7
|
+
|
8
|
+
def initialize(host, username, password, port = 22)
|
9
|
+
@host = host
|
10
|
+
@username = username
|
11
|
+
@password = password
|
12
|
+
@port = port
|
13
|
+
end
|
14
|
+
|
15
|
+
def command(command)
|
16
|
+
exit_code = nil
|
17
|
+
Dockerploy.logger.info sprintf('From server: %s Running: %s', @host, command)
|
18
|
+
with_ssh(command) do |c, ssh|
|
19
|
+
Dockerploy.logger.info 'Output: '
|
20
|
+
ssh.open_channel do |channel|
|
21
|
+
channel.exec(c) do |_, success|
|
22
|
+
abort "FAILED: couldn't execute command (ssh.channel.exec)" unless success
|
23
|
+
|
24
|
+
channel.on_data do |_, data|
|
25
|
+
print data
|
26
|
+
end
|
27
|
+
|
28
|
+
channel.on_extended_data do |_, _, data|
|
29
|
+
print data
|
30
|
+
end
|
31
|
+
|
32
|
+
channel.on_request('exit-status') do |_, data|
|
33
|
+
exit_code = data.read_long
|
34
|
+
end
|
35
|
+
end
|
36
|
+
ssh.loop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
result = exit_code == 0
|
41
|
+
Dockerploy.logger.info sprintf('Exit Code: %d', exit_code) unless result
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def with_ssh(command, &block)
|
48
|
+
Net::SSH.start(@host, @username, password: @password, port: @port) do |ssh|
|
49
|
+
block.call(command, ssh)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
test:
|
6
|
+
branch: master
|
7
|
+
servers:
|
8
|
+
- host: server.host
|
9
|
+
username: server_user
|
10
|
+
password: server_pass
|
11
|
+
port: 2000
|
12
|
+
role: server_role
|
13
|
+
container:
|
14
|
+
host: container.host
|
15
|
+
ssh_port: 1022
|
16
|
+
http_port: 8080
|
@@ -0,0 +1,17 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
test:
|
6
|
+
branch: master
|
7
|
+
env_file: spec/fixtures/test.yml
|
8
|
+
servers:
|
9
|
+
- host: server.host
|
10
|
+
username: server_user
|
11
|
+
password: server_pass
|
12
|
+
port: 2000
|
13
|
+
role: server_role
|
14
|
+
container:
|
15
|
+
host: container.host
|
16
|
+
ssh_port: 1022
|
17
|
+
http_port: 8080
|
@@ -0,0 +1,17 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
test:
|
6
|
+
branch: test-branch
|
7
|
+
tagging: true
|
8
|
+
servers:
|
9
|
+
- host: server.host
|
10
|
+
username: server_user
|
11
|
+
password: server_pass
|
12
|
+
port: 2000
|
13
|
+
role: server_role
|
14
|
+
container:
|
15
|
+
host: container.host
|
16
|
+
ssh_port: 1022
|
17
|
+
http_port: 8080
|
@@ -0,0 +1,20 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
test:
|
6
|
+
branch: master
|
7
|
+
volumes:
|
8
|
+
- volume:
|
9
|
+
host: /opt/app/shared/log
|
10
|
+
guest: /var/log
|
11
|
+
servers:
|
12
|
+
- host: server.host
|
13
|
+
username: server_user
|
14
|
+
password: server_pass
|
15
|
+
port: 2000
|
16
|
+
role: server_role
|
17
|
+
container:
|
18
|
+
host: container.host
|
19
|
+
ssh_port: 1022
|
20
|
+
http_port: 8080
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dockerploy
|
4
|
+
describe CLI do
|
5
|
+
let(:fixture_path) { 'spec/fixtures/config.yml' }
|
6
|
+
before do
|
7
|
+
stub_const('Dockerploy::Configuration::DEFAULT_CONFIG_FILE', fixture_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#ps' do
|
11
|
+
it 'runs docker ps in servers' do
|
12
|
+
expect_any_instance_of(SSHClient).to receive(:command).with('docker ps | grep app')
|
13
|
+
cli = described_class.new
|
14
|
+
cli.ps('test')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#build' do
|
19
|
+
it 'runs docker build' do
|
20
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker build -t docker/image .'
|
21
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
22
|
+
cli = described_class.new
|
23
|
+
cli.build
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#push' do
|
28
|
+
it 'pushes the image' do
|
29
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker push docker/image'
|
30
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
31
|
+
cli = described_class.new
|
32
|
+
cli.push
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#pull' do
|
37
|
+
it 'pulls the image' do
|
38
|
+
expect_any_instance_of(SSHClient).to receive(:command).with('docker pull docker/image')
|
39
|
+
cli = described_class.new
|
40
|
+
cli.pull('test')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#deploy' do
|
45
|
+
it 'creates a container on server' do
|
46
|
+
expect_any_instance_of(SSHClient).to receive(:command).with('docker rm -f app_8080')
|
47
|
+
expected_command = <<-SHELL
|
48
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image
|
49
|
+
SHELL
|
50
|
+
expected_command.chomp!
|
51
|
+
expect_any_instance_of(SSHClient).to receive(:command).with(expected_command)
|
52
|
+
cli = described_class.new
|
53
|
+
cli.deploy('test')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dockerploy
|
4
|
+
describe Deploy do
|
5
|
+
let(:fixture_path) { 'spec/fixtures/config.yml' }
|
6
|
+
let(:config) { Configuration.new(env: 'test') }
|
7
|
+
let(:ssh_client) { double(command: double) }
|
8
|
+
let(:shell_client) { double(command: double) }
|
9
|
+
subject { described_class.new(config) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
stub_const('Dockerploy::Configuration::DEFAULT_CONFIG_FILE', fixture_path)
|
13
|
+
allow(SSHClient).to receive(:new).and_return(ssh_client)
|
14
|
+
allow(ShellClient).to receive(:new).and_return(shell_client)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#deploy' do
|
18
|
+
it 'destroys a container' do
|
19
|
+
expected_command = 'docker rm -f app_8080'
|
20
|
+
expect(ssh_client).to receive(:command).with(expected_command)
|
21
|
+
subject.deploy
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'creates a container on server' do
|
25
|
+
expected_command = <<-SHELL
|
26
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image
|
27
|
+
SHELL
|
28
|
+
expected_command.chomp!
|
29
|
+
expect(ssh_client).to receive(:command).with(expected_command)
|
30
|
+
subject.deploy
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'an environment file exists' do
|
34
|
+
let(:fixture_path) { 'spec/fixtures/config_with_env_file.yml' }
|
35
|
+
|
36
|
+
it 'creates a container with environment variables' do
|
37
|
+
expected_command = <<-SHELL
|
38
|
+
docker run -d --name app_8080 --hostname app \
|
39
|
+
-p container.host:1022:22 -p container.host:8080:80 \
|
40
|
+
-e BRANCH='master' -e APP_ENV='test' docker/image
|
41
|
+
SHELL
|
42
|
+
expected_command.chomp!
|
43
|
+
expect(ssh_client).to receive(:command).with(expected_command)
|
44
|
+
subject.deploy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'volumes exists' do
|
49
|
+
let(:fixture_path) { 'spec/fixtures/config_with_volumes.yml' }
|
50
|
+
|
51
|
+
it 'creates a container with volumes' do
|
52
|
+
expected_command = <<-SHELL
|
53
|
+
docker run -d --name app_8080 --hostname app \
|
54
|
+
-p container.host:1022:22 -p container.host:8080:80 \
|
55
|
+
-v /opt/app/shared/log:/var/log \
|
56
|
+
docker/image
|
57
|
+
SHELL
|
58
|
+
expected_command.chomp!
|
59
|
+
expect(ssh_client).to receive(:command).with(expected_command)
|
60
|
+
subject.deploy
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'tagging is true' do
|
65
|
+
let(:fixture_path) { 'spec/fixtures/config_with_tagging.yml' }
|
66
|
+
|
67
|
+
it 'pushes a tags to the repository' do
|
68
|
+
timestamp = Time.now.strftime('%Y%m%dT%H%M')
|
69
|
+
expect(shell_client).to receive(:command).with(
|
70
|
+
"git tag test-#{timestamp} test-branch && git push origin test-#{timestamp}").and_return(true)
|
71
|
+
subject.deploy
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'dockerploy'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
Dir['#{File.dirname(__FILE__)}/support/**/*.rb'].each { |f| require f }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.raise_errors_for_deprecations!
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dockerploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sunjin Lee
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.19'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.19'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mono_logger
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
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: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
description: Deploy dockerized an application
|
84
|
+
email:
|
85
|
+
- styner32@gmail.com
|
86
|
+
executables:
|
87
|
+
- dockerploy
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- .rspec
|
93
|
+
- .rubocop.yml
|
94
|
+
- .travis.yml
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- bin/dockerploy
|
100
|
+
- d.sh
|
101
|
+
- dockerploy.gemspec
|
102
|
+
- lib/dockerploy.rb
|
103
|
+
- lib/dockerploy/cli.rb
|
104
|
+
- lib/dockerploy/configuration.rb
|
105
|
+
- lib/dockerploy/core_ext/hash.rb
|
106
|
+
- lib/dockerploy/deploy.rb
|
107
|
+
- lib/dockerploy/image.rb
|
108
|
+
- lib/dockerploy/shell_client.rb
|
109
|
+
- lib/dockerploy/ssh_client.rb
|
110
|
+
- lib/dockerploy/version.rb
|
111
|
+
- spec/fixtures/config.yml
|
112
|
+
- spec/fixtures/config_with_env_file.yml
|
113
|
+
- spec/fixtures/config_with_tagging.yml
|
114
|
+
- spec/fixtures/config_with_volumes.yml
|
115
|
+
- spec/fixtures/test.yml
|
116
|
+
- spec/lib/dockerploy/cli_spec.rb
|
117
|
+
- spec/lib/dockerploy/deploy_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
homepage: https://github.com/viki-org/dockerploy
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.9.3
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.1.10
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: Deploy dockerized an application
|
143
|
+
test_files:
|
144
|
+
- spec/fixtures/config.yml
|
145
|
+
- spec/fixtures/config_with_env_file.yml
|
146
|
+
- spec/fixtures/config_with_tagging.yml
|
147
|
+
- spec/fixtures/config_with_volumes.yml
|
148
|
+
- spec/fixtures/test.yml
|
149
|
+
- spec/lib/dockerploy/cli_spec.rb
|
150
|
+
- spec/lib/dockerploy/deploy_spec.rb
|
151
|
+
- spec/spec_helper.rb
|
152
|
+
has_rdoc:
|