docker_compose_deploy 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 +11 -0
- data/Gemfile +4 -0
- data/README.md +15 -0
- data/Rakefile +2 -0
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/docker_compose_deploy.gemspec +27 -0
- data/exe/dcd +6 -0
- data/lib/docker_compose_deploy/actions/backup.rb +43 -0
- data/lib/docker_compose_deploy/actions/deployment.rb +42 -0
- data/lib/docker_compose_deploy/actions/docker_compose/file.rb +32 -0
- data/lib/docker_compose_deploy/actions/hosts.rb +30 -0
- data/lib/docker_compose_deploy/actions/image.rb +41 -0
- data/lib/docker_compose_deploy/actions/server.rb +27 -0
- data/lib/docker_compose_deploy/actions/skeleton.rb +43 -0
- data/lib/docker_compose_deploy/actions.rb +6 -0
- data/lib/docker_compose_deploy/cli.rb +49 -0
- data/lib/docker_compose_deploy/util/color.rb +26 -0
- data/lib/docker_compose_deploy/util/shell.rb +74 -0
- data/lib/docker_compose_deploy/version.rb +3 -0
- data/lib/docker_compose_deploy.rb +40 -0
- data/template/Vagrantfile +8 -0
- data/template/config.yml +80 -0
- data/template/docker-compose.yml +26 -0
- data/template/sites/config/proxy/nginx.conf +36 -0
- data/template/ssh_config_overrides +27 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0c48329c119fc90532529e8a141a52b3cf45b17
|
4
|
+
data.tar.gz: 7489ff60f598b4fe35f69ddf371dc177e1655fed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c584fece997fe67ba5826b8df74f41c48455d5a6b6feb247f557c32858f5a1ab8072f3974898be0b8d8b9bb249618237b3ff9dea044dcd52f583735a315c69d4
|
7
|
+
data.tar.gz: 8ac15de15749951c7a48b01ae6c3f828df6c20cc564a71d5ca50dad59823da647e895b307a67ced72038e4f17971addab037023df435820b670fa8a77fd68f76
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
### Easily deploy a docker-compose.yml
|
2
|
+
|
3
|
+
This gem is a collection of scripts that I use to deploy my personal websites using docker-compose. This gem will help you:
|
4
|
+
|
5
|
+
- Generate a skeleton for you project
|
6
|
+
- Provision a server with Docker and Docker Compose
|
7
|
+
- Test your deployment on a vagrant machine
|
8
|
+
- Deploy your docker-compose project
|
9
|
+
- Backup the data that your applications Generate
|
10
|
+
|
11
|
+
While these scripts are great for your personal projects, they will not help you with zero-downtime deploys, rotating your logs, or any of that other fancy stuff.
|
12
|
+
|
13
|
+
This doesn't provide much over using docker-machine, but it will simplify working with volumes and allow you to test your deployment in a realistic environment.
|
14
|
+
|
15
|
+
### The Skeleton
|
data/Rakefile
ADDED
data/bin/console
ADDED
File without changes
|
data/bin/setup
ADDED
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'docker_compose_deploy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "docker_compose_deploy"
|
8
|
+
spec.version = DockerComposeDeploy::VERSION
|
9
|
+
spec.authors = ["Pete Kinnecom"]
|
10
|
+
spec.email = ["rubygems@k7u7.com"]
|
11
|
+
spec.licenses = ['MIT']
|
12
|
+
|
13
|
+
spec.summary = %q{This helps you deploy a website using docker-compose}
|
14
|
+
spec.homepage = "http://www.petekinnecom.net"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "thor", "~> 0.19"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
end
|
data/exe/dcd
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module DockerComposeDeploy
|
2
|
+
module Actions
|
3
|
+
class Backup < Struct.new(:shell)
|
4
|
+
|
5
|
+
def save
|
6
|
+
shell.notify("Backing up remote ./sites/data directory")
|
7
|
+
shell.notify("This may take a while...")
|
8
|
+
shell.run!("mkdir -p ./backups")
|
9
|
+
|
10
|
+
shell.ssh!("mkdir -p ./sites/backups")
|
11
|
+
shell.ssh!("tar -zcvf ./sites/backups/#{filename} ./sites/data")
|
12
|
+
shell.scp!("#{connection}:./sites/backups/#{filename}", "./backups/#{filename}")
|
13
|
+
shell.ssh!("rm ./sites/backups/#{filename}")
|
14
|
+
|
15
|
+
shell.notify "success"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def tmp_dir
|
21
|
+
@tmp_dir ||= "./tmp".tap do |dir|
|
22
|
+
FileUtils.mkdir_p(dir)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def filename
|
27
|
+
@filename ||= begin
|
28
|
+
time_str = Time.now.strftime("%Y-%m-%d_%H.%M.%S")
|
29
|
+
|
30
|
+
"backup__#{connection}__#{time_str}.tar.gz"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def tmp_file_path
|
35
|
+
File.join(tmp_dir, filename)
|
36
|
+
end
|
37
|
+
|
38
|
+
def connection
|
39
|
+
DockerComposeDeploy.config.connection
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "docker_compose_deploy/actions/docker_compose/file"
|
2
|
+
|
3
|
+
module DockerComposeDeploy
|
4
|
+
module Actions
|
5
|
+
class Deployment < Struct.new(:ignore_pull_failures, :shell)
|
6
|
+
|
7
|
+
def create
|
8
|
+
shell.ssh!("mkdir -p ./sites")
|
9
|
+
shell.ssh!("rm -rf ./sites/config") # bin/deploy is irreversible :)
|
10
|
+
shell.scp!("./sites/config/", "#{connection}:./sites/config", "-r")
|
11
|
+
|
12
|
+
docker_compose.services.each do |service_name|
|
13
|
+
shell.ssh!("mkdir -p ./sites/data/#{service_name}")
|
14
|
+
shell.ssh!("mkdir -p ./sites/log/#{service_name}")
|
15
|
+
end
|
16
|
+
|
17
|
+
shell.scp!(docker_compose.path, "#{connection}:./docker-compose.yml")
|
18
|
+
shell.ssh!("docker-compose down")
|
19
|
+
shell.ssh!("docker-compose pull #{ignore_pull_failures_option}")
|
20
|
+
shell.ssh!("docker-compose up -d")
|
21
|
+
|
22
|
+
shell.notify "success"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def ignore_pull_failures_option
|
28
|
+
if ignore_pull_failures
|
29
|
+
"--ignore-pull-failures"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def docker_compose
|
34
|
+
@docker_compose ||= DockerCompose::File.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def connection
|
38
|
+
DockerComposeDeploy.config.connection
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module DockerComposeDeploy
|
4
|
+
module Actions
|
5
|
+
module DockerCompose
|
6
|
+
class File
|
7
|
+
attr_reader :path
|
8
|
+
def initialize(path="./docker-compose.yml")
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def services
|
13
|
+
if !hash["services"]
|
14
|
+
raise "This is build to work with version 2 or 3 of docker-compose. It requires the 'services' top level key."
|
15
|
+
end
|
16
|
+
|
17
|
+
hash["services"].keys
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def hash
|
23
|
+
@hash ||= YAML.load(string)
|
24
|
+
end
|
25
|
+
|
26
|
+
def string
|
27
|
+
@string ||= ::File.read(@path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DockerComposeDeploy
|
2
|
+
module Actions
|
3
|
+
class Hosts < Struct.new(:shell)
|
4
|
+
|
5
|
+
def hijack
|
6
|
+
return unless DockerComposeDeploy.config.domains.any?
|
7
|
+
|
8
|
+
shell.notify("Creating hosts entries for test_domains")
|
9
|
+
|
10
|
+
host_entries = ["localhost", "vagrant"] + DockerComposeDeploy.config.domains
|
11
|
+
Tempfile.open do |f|
|
12
|
+
host_entries.each do |host|
|
13
|
+
f.puts("127.0.0.1 #{host}")
|
14
|
+
end
|
15
|
+
f.close
|
16
|
+
shell.scp!(f.path, "#{connection}:/tmp/hosts")
|
17
|
+
shell.ssh!("sudo mv /tmp/hosts /etc/hosts")
|
18
|
+
shell.notify("Wrote to /etc/hosts on test server:")
|
19
|
+
shell.puts(`cat #{f.path}`)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def connection
|
26
|
+
DockerComposeDeploy.config.connection
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
module DockerComposeDeploy
|
5
|
+
module Actions
|
6
|
+
class Image < Struct.new(:name, :shell)
|
7
|
+
|
8
|
+
def push
|
9
|
+
shell.notify "Pushing #{name} to remote"
|
10
|
+
|
11
|
+
shell.run!("docker save #{name} > #{tmp_file_path}")
|
12
|
+
shell.run!("bzip2 #{tmp_file_path}")
|
13
|
+
shell.scp!("#{tmp_file_path}.bz2", "#{connection}:/tmp/")
|
14
|
+
shell.run!("rm #{tmp_file_path}.bz2")
|
15
|
+
shell.ssh!("docker load -i /tmp/#{filename}.bz2")
|
16
|
+
|
17
|
+
shell.notify "success"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def tmp_dir
|
23
|
+
@tmp_dir ||= "./tmp".tap do |dir|
|
24
|
+
FileUtils.mkdir_p(dir)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def filename
|
29
|
+
@filename ||= "#{name.gsub('/', '__')}_#{SecureRandom.hex}.tar"
|
30
|
+
end
|
31
|
+
|
32
|
+
def tmp_file_path
|
33
|
+
File.join(tmp_dir, filename)
|
34
|
+
end
|
35
|
+
|
36
|
+
def connection
|
37
|
+
DockerComposeDeploy.config.connection
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module DockerComposeDeploy
|
2
|
+
module Actions
|
3
|
+
class Server < Struct.new(:shell)
|
4
|
+
|
5
|
+
def provision
|
6
|
+
shell.notify("Provisioning: #{connection}")
|
7
|
+
shell.ssh!("sudo groupadd docker")
|
8
|
+
shell.ssh!("sudo usermod -aG docker $USER")
|
9
|
+
shell.ssh!("true", "-O exit") # resets the connection, so that our group changes take effect
|
10
|
+
|
11
|
+
shell.ssh!("wget -qO- https://get.docker.com/ | bash")
|
12
|
+
shell.ssh!("curl -L https://github.com/docker/compose/releases/download/1.11.1/run.sh > ./docker-compose")
|
13
|
+
shell.ssh!("chmod +x docker-compose")
|
14
|
+
shell.ssh!("sudo mv ./docker-compose /usr/local/bin/docker-compose")
|
15
|
+
shell.ssh!("docker-compose -v")
|
16
|
+
|
17
|
+
shell.notify "success"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def connection
|
23
|
+
DockerComposeDeploy.config.connection
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module DockerComposeDeploy
|
2
|
+
module Actions
|
3
|
+
class Skeleton < Struct.new(:name, :shell)
|
4
|
+
|
5
|
+
def create
|
6
|
+
shell.notify("Creating new skeleton")
|
7
|
+
if File.exist?(name)
|
8
|
+
shell.warn("Directory or file: '#{name}' already exists. Exiting.")
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
|
12
|
+
begin
|
13
|
+
Dir.mkdir(name)
|
14
|
+
Dir.rmdir(name)
|
15
|
+
rescue
|
16
|
+
shell.warn("Unable to make directory '#{name}'. Is it a valid directory name? Exiting.")
|
17
|
+
end
|
18
|
+
|
19
|
+
template_path = File.expand_path(File.join(__dir__, "../../../template"))
|
20
|
+
FileUtils.cp_r(template_path, name)
|
21
|
+
shell.notify("Created skeleton app in '#{name}'.")
|
22
|
+
shell.puts <<-MESSAGE
|
23
|
+
To see the skeleton app in action, run the following commands
|
24
|
+
|
25
|
+
# Move into the directory
|
26
|
+
1. cd #{name}
|
27
|
+
|
28
|
+
# Use vagrant to create the virtual machine for testing (it will open a window and will display Ubuntu's desktop)
|
29
|
+
2. vagrant up
|
30
|
+
|
31
|
+
# Install docker and docker-compose on the vagrant machine
|
32
|
+
3. dcd provision
|
33
|
+
|
34
|
+
# Deploy the skeleton app to the vagrant machine
|
35
|
+
4. dcd deploy
|
36
|
+
|
37
|
+
# See the server in action:
|
38
|
+
5. Open firefox on the vagrant machine and visit http://www.test
|
39
|
+
MESSAGE
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require "docker_compose_deploy/actions/deployment"
|
2
|
+
require "docker_compose_deploy/actions/server"
|
3
|
+
require "docker_compose_deploy/actions/backup"
|
4
|
+
require "docker_compose_deploy/actions/image"
|
5
|
+
require "docker_compose_deploy/actions/hosts"
|
6
|
+
require "docker_compose_deploy/actions/skeleton"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "thor"
|
2
|
+
$LOAD_PATH.unshift(File.expand_path("..", __dir__))
|
3
|
+
require "docker_compose_deploy"
|
4
|
+
require "docker_compose_deploy/util/shell"
|
5
|
+
require "docker_compose_deploy/actions"
|
6
|
+
|
7
|
+
module DockerComposeDeploy
|
8
|
+
class CLI < Thor
|
9
|
+
desc "push IMAGE_NAME", "push IMAGE_NAME to configured host"
|
10
|
+
option :e, required: true, default: "test"
|
11
|
+
def push(*image_names)
|
12
|
+
DockerComposeDeploy.configure!(options[:e])
|
13
|
+
shell = Util::Shell.new
|
14
|
+
image_names.each do |image_name|
|
15
|
+
Actions::Image.new(image_name, shell).push
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "deploy", "deploy your docker-compose.yml to configured host"
|
20
|
+
option :e, required: true, default: "test"
|
21
|
+
def deploy
|
22
|
+
DockerComposeDeploy.configure!(options[:e])
|
23
|
+
ignore_pull_failures = DockerComposeDeploy.config.ignore_pull_failures
|
24
|
+
shell = Util::Shell.new
|
25
|
+
|
26
|
+
Actions::Deployment.new(ignore_pull_failures, shell).create
|
27
|
+
Actions::Hosts.new(shell).hijack
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "backup", "backup the data directory of the configured host"
|
31
|
+
option :e, required: true, default: "test"
|
32
|
+
def backup
|
33
|
+
DockerComposeDeploy.configure!(options[:e])
|
34
|
+
Actions::Backup.new(Util::Shell.new).save
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "provision", "provision the host to work with docker"
|
38
|
+
option :e, required: true, default: "test"
|
39
|
+
def provision
|
40
|
+
DockerComposeDeploy.configure!(options[:e])
|
41
|
+
Actions::Server.new(Util::Shell.new).provision
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "new", "create a new docker-compose server skeleton"
|
45
|
+
def new(name)
|
46
|
+
Actions::Skeleton.new(name, Util::Shell.new).create
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DockerComposeDeploy
|
2
|
+
module Util
|
3
|
+
module Color
|
4
|
+
CODES = {
|
5
|
+
red: 31,
|
6
|
+
green: 32,
|
7
|
+
yellow: 33,
|
8
|
+
blue: 34,
|
9
|
+
pink: 35,
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
CODES.each do |color, code|
|
13
|
+
self.send(:define_method, color) do |string|
|
14
|
+
colorize(string, code)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# colorization
|
21
|
+
def colorize(string, color_code)
|
22
|
+
"\e[#{color_code}m#{string}\e[0m"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'docker_compose_deploy/util/color'
|
2
|
+
|
3
|
+
module DockerComposeDeploy
|
4
|
+
module Util
|
5
|
+
class Shell
|
6
|
+
include Color
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
$stderr.sync = true
|
10
|
+
$stdout.sync = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(cmd)
|
14
|
+
puts blue(cmd)
|
15
|
+
IO.popen(cmd) do |io|
|
16
|
+
while (line = io.gets) do
|
17
|
+
puts line
|
18
|
+
end
|
19
|
+
end
|
20
|
+
$?
|
21
|
+
end
|
22
|
+
|
23
|
+
def run!(cmd)
|
24
|
+
if run(cmd) != 0
|
25
|
+
exit("\nCommand failed:\n#{cmd}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def warn(msg)
|
30
|
+
puts red(msg)
|
31
|
+
end
|
32
|
+
|
33
|
+
def notify(msg)
|
34
|
+
puts yellow(msg)
|
35
|
+
end
|
36
|
+
|
37
|
+
def puts(msg)
|
38
|
+
Kernel.puts(msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def exit(msg)
|
42
|
+
warn(msg)
|
43
|
+
Kernel.exit(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
def ssh(cmd)
|
47
|
+
run(ssh_cmd(cmd))
|
48
|
+
end
|
49
|
+
|
50
|
+
def ssh!(cmd, opts="")
|
51
|
+
run!(ssh_cmd(cmd, opts))
|
52
|
+
end
|
53
|
+
|
54
|
+
def scp!(src, dest, opts="")
|
55
|
+
run!("scp -F ~/.ssh/config -F ssh_config_overrides #{opts} #{src} #{dest} > /dev/tty")
|
56
|
+
end
|
57
|
+
|
58
|
+
def confirm?(question)
|
59
|
+
warn "#{question} [Yn]"
|
60
|
+
STDIN.gets.strip.downcase != 'n'
|
61
|
+
end
|
62
|
+
|
63
|
+
def ssh_cmd(cmd, opts)
|
64
|
+
"ssh -F ~/.ssh/config -F ssh_config_overrides #{opts} #{connection} '#{cmd}'"
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def connection
|
70
|
+
DockerComposeDeploy.config.connection
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "docker_compose_deploy/version"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
module DockerComposeDeploy
|
5
|
+
class << self
|
6
|
+
def config
|
7
|
+
@config || raise("Not configured")
|
8
|
+
end
|
9
|
+
|
10
|
+
def configure!(environment)
|
11
|
+
yaml = YAML.load(File.read("./config.yml"))
|
12
|
+
@config = Configuration.new(environment, yaml)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Configuration
|
17
|
+
def initialize(environment, yaml)
|
18
|
+
@environment = environment
|
19
|
+
@yaml = yaml
|
20
|
+
end
|
21
|
+
|
22
|
+
def ignore_pull_failures
|
23
|
+
config_block.fetch("ignore_pull_failures", false)
|
24
|
+
end
|
25
|
+
|
26
|
+
def connection
|
27
|
+
config_block["connection"] || raise("INVALID CONFIG: Environment '#{@environment}' does not specify a connection string in config.yml")
|
28
|
+
end
|
29
|
+
|
30
|
+
def domains
|
31
|
+
config_block.fetch("domains", [])
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def config_block
|
37
|
+
@yaml[@environment] || raise("INVALID ENVIRONMENT: Environment '#{@environment}' is not configured in config.yml")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/template/config.yml
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# Environment configuration
|
2
|
+
#
|
3
|
+
# You can define as many "environments" as you like. I've found
|
4
|
+
# that I only need two. The "test" environment is the vagrant
|
5
|
+
# box, the "production" environment uses my virtual machine on
|
6
|
+
# DigitalOcean.
|
7
|
+
#
|
8
|
+
# When using the `dcd` command, you can specify the environment
|
9
|
+
# using the `-e` flag. Here is an example:
|
10
|
+
#
|
11
|
+
# dcd deploy -e production
|
12
|
+
#
|
13
|
+
# If the `-e` is not set, it will default to "test".
|
14
|
+
#
|
15
|
+
################################################################
|
16
|
+
#
|
17
|
+
# "connection": How we connect to the host machine
|
18
|
+
#
|
19
|
+
# For each, we must configure the connection string that we use
|
20
|
+
# to connect to the host using ssh. The "test" environment is
|
21
|
+
# already setup for the vagrant host. You need to configure the
|
22
|
+
# production environment.
|
23
|
+
#
|
24
|
+
################################################################
|
25
|
+
#
|
26
|
+
# "ignore_pull_failures": Pull Failures configuration
|
27
|
+
#
|
28
|
+
# For each environment we can also set the "ignore_pull_failures"
|
29
|
+
# flag. This flag is used when deploying your docker-compose.yml.
|
30
|
+
#
|
31
|
+
# We run `docker-compose pull` to pull down the latest
|
32
|
+
# images from hub.docker.com. If you have decided instead
|
33
|
+
# to push your images directly to your host (using
|
34
|
+
# `dcd push image_name`) then these images will fail to be pulled
|
35
|
+
# from hub.docker.com (since they were never put there).
|
36
|
+
#
|
37
|
+
# If images cannot be pulled, then `docker-compose pull` will
|
38
|
+
# consider this an error. Setting `ignore_pull_failures` to `true`
|
39
|
+
# will tell docker-compose to ignore any errors generated while
|
40
|
+
# pulling down the latest image.
|
41
|
+
#
|
42
|
+
# If you are using hub.docker.com, leave this as false.
|
43
|
+
#
|
44
|
+
# If you are using `dcd push image_name` then set this to true
|
45
|
+
#
|
46
|
+
################################################################
|
47
|
+
#
|
48
|
+
# "domains" => Urls to hijack on the host machine
|
49
|
+
#
|
50
|
+
# It can be tricky to ensure that the nginx configuration that
|
51
|
+
# your proxy is using is routing things to the correct docker
|
52
|
+
# container.
|
53
|
+
#
|
54
|
+
# In order to help test things on the vagrant machine, we add
|
55
|
+
# the listed domains to the /etc/hosts file of the machine.
|
56
|
+
# We can then use firefox on the vagrant machine to visit one
|
57
|
+
# of the domains and the request will be routed back to our
|
58
|
+
# nginx proxy.
|
59
|
+
#
|
60
|
+
# Add an entry here for each subdomain that you have on your
|
61
|
+
# production server. Notice how the three domains specified
|
62
|
+
# here are present in the sites/config/proxy/nginx.conf file.
|
63
|
+
#
|
64
|
+
# Note that you can specify any domain, but using the ".test"
|
65
|
+
# domain will keep things clear while testing.
|
66
|
+
#
|
67
|
+
# You should have no reason to add domains for your production
|
68
|
+
# server.
|
69
|
+
#
|
70
|
+
|
71
|
+
test:
|
72
|
+
connection: "vagrant@default"
|
73
|
+
ignore_pull_failures: false
|
74
|
+
domains:
|
75
|
+
- www.test
|
76
|
+
- site1.test
|
77
|
+
- site2.test
|
78
|
+
production:
|
79
|
+
connection: "user@yourserver"
|
80
|
+
ignore_pull_failures: false
|
@@ -0,0 +1,26 @@
|
|
1
|
+
version: '3'
|
2
|
+
services:
|
3
|
+
proxy:
|
4
|
+
image: nginx:1.11.10
|
5
|
+
command: ["nginx", "-c", "/mnt/config/nginx.conf", "-g", "daemon off;"]
|
6
|
+
volumes:
|
7
|
+
- ./sites/config/proxy:/mnt/config
|
8
|
+
- ./sites/data/proxy:/mnt/data
|
9
|
+
- ./sites/log/proxy:/mnt/log
|
10
|
+
ports:
|
11
|
+
- 80:80
|
12
|
+
depends_on:
|
13
|
+
- site1
|
14
|
+
- site2
|
15
|
+
site1:
|
16
|
+
image: petekinnecom/compose_deploy_site:1.0
|
17
|
+
volumes:
|
18
|
+
- ./sites/config/site1:/mnt/config
|
19
|
+
- ./sites/data/site1:/mnt/data
|
20
|
+
- ./sites/log/site1:/mnt/log
|
21
|
+
site2:
|
22
|
+
image: petekinnecom/compose_deploy_site:2.0
|
23
|
+
volumes:
|
24
|
+
- ./sites/config/site2:/mnt/config
|
25
|
+
- ./sites/data/site2:/mnt/data
|
26
|
+
- ./sites/log/site2:/mnt/log
|
@@ -0,0 +1,36 @@
|
|
1
|
+
events {
|
2
|
+
worker_connections 1024;
|
3
|
+
}
|
4
|
+
|
5
|
+
http {
|
6
|
+
access_log /mnt/log/access.log;
|
7
|
+
error_log /mnt/log/error.log;
|
8
|
+
|
9
|
+
server {
|
10
|
+
listen 80;
|
11
|
+
server_name www.*;
|
12
|
+
|
13
|
+
location / {
|
14
|
+
add_header Content-Type text/html;
|
15
|
+
return 200 "<a href='http://site1.test'>site1</a> or <a href='http://site2.test'>site2</a>";
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
server {
|
20
|
+
listen 80;
|
21
|
+
server_name site1.*;
|
22
|
+
|
23
|
+
location / {
|
24
|
+
proxy_pass http://site1/;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
server {
|
29
|
+
listen 80;
|
30
|
+
server_name site2.*;
|
31
|
+
|
32
|
+
location / {
|
33
|
+
proxy_pass http://site2/;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This keeps the connection alive for two seconds
|
2
|
+
# after each usage. This improves performance.
|
3
|
+
|
4
|
+
Host *
|
5
|
+
ControlPath ~/.ssh/sock-%r@%h:%p
|
6
|
+
ControlMaster auto
|
7
|
+
ControlPersist 2
|
8
|
+
|
9
|
+
# The following configuration for the "default" host works
|
10
|
+
# with the default Vagrant file and vagrant 1.9.1. If you
|
11
|
+
# cannot connect using:
|
12
|
+
#
|
13
|
+
# ssh -F ssh_config_overrides vagrant@default
|
14
|
+
#
|
15
|
+
# Then replace this Host definition with the output from
|
16
|
+
# the command: `vagrant ssh-config`
|
17
|
+
|
18
|
+
Host default
|
19
|
+
HostName 127.0.0.1
|
20
|
+
User vagrant
|
21
|
+
Port 2222
|
22
|
+
UserKnownHostsFile /dev/null
|
23
|
+
StrictHostKeyChecking no
|
24
|
+
PasswordAuthentication no
|
25
|
+
IdentityFile .vagrant/machines/default/virtualbox/private_key
|
26
|
+
IdentitiesOnly yes
|
27
|
+
LogLevel FATAL
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docker_compose_deploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pete Kinnecom
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-17 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: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- rubygems@k7u7.com
|
58
|
+
executables:
|
59
|
+
- dcd
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- bin/console
|
68
|
+
- bin/setup
|
69
|
+
- docker_compose_deploy.gemspec
|
70
|
+
- exe/dcd
|
71
|
+
- lib/docker_compose_deploy.rb
|
72
|
+
- lib/docker_compose_deploy/actions.rb
|
73
|
+
- lib/docker_compose_deploy/actions/backup.rb
|
74
|
+
- lib/docker_compose_deploy/actions/deployment.rb
|
75
|
+
- lib/docker_compose_deploy/actions/docker_compose/file.rb
|
76
|
+
- lib/docker_compose_deploy/actions/hosts.rb
|
77
|
+
- lib/docker_compose_deploy/actions/image.rb
|
78
|
+
- lib/docker_compose_deploy/actions/server.rb
|
79
|
+
- lib/docker_compose_deploy/actions/skeleton.rb
|
80
|
+
- lib/docker_compose_deploy/cli.rb
|
81
|
+
- lib/docker_compose_deploy/util/color.rb
|
82
|
+
- lib/docker_compose_deploy/util/shell.rb
|
83
|
+
- lib/docker_compose_deploy/version.rb
|
84
|
+
- template/Vagrantfile
|
85
|
+
- template/config.yml
|
86
|
+
- template/docker-compose.yml
|
87
|
+
- template/sites/config/proxy/nginx.conf
|
88
|
+
- template/ssh_config_overrides
|
89
|
+
homepage: http://www.petekinnecom.net
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.5.2
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: This helps you deploy a website using docker-compose
|
113
|
+
test_files: []
|
114
|
+
has_rdoc:
|