Module: DockerDeploy

Defined in:
lib/docker_deploy.rb,
lib/docker_deploy/task.rb,
lib/docker_deploy/shell.rb,
lib/docker_deploy/stage.rb,
lib/docker_deploy/context.rb,
lib/docker_deploy/service.rb,
lib/docker_deploy/version.rb,
lib/docker_deploy/local_stage.rb,
lib/docker_deploy/remote_stage.rb

Defined Under Namespace

Classes: Context, LocalStage, RemoteStage, Service, Stage

Constant Summary collapse

VERSION =
"0.3.1"

Class Method Summary collapse

Class Method Details

.format_params(pattern, enumerable) ⇒ Object



16
17
18
19
20
21
# File 'lib/docker_deploy.rb', line 16

def self.format_params(pattern, enumerable)
  enumerable.map do |args|
    args = [args].flatten.map { |v| Shellwords.escape(v) }
    pattern % args
  end.join(" ")
end

.shell(server, command = nil) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/docker_deploy/shell.rb', line 2

def self.shell(server, command = nil)
  Net::SSH.start('app1.projectpuzzle.com', 'ubuntu') do |ssh|
    channel = ssh.open_channel do |ch|
      ch.on_data do |c, data|
        $stdout.print data
      end

      ch.on_extended_data do |c, type, data|
        $stderr.print data
      end

      ch.request_pty

      if command
        ch.exec(command)
      else
        ch.send_channel_request "shell"
      end
    end

    read, write = UNIXSocket.pair

    Thread.new(write) do |write|
      loop do
        buf = $stdin.raw { |r| r.readpartial(1) }
        write.write(buf)
      end
    end

    read.extend(Net::SSH::BufferedIo)

    ssh.listen_to(read)

    ssh.loop do
      buf = read.read_available
      channel.send_data buf unless buf.empty?

      ssh.busy?
    end
  end
end

.task(ns = :docker, &block) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/docker_deploy/task.rb', line 2

def self.task(ns = :docker, &block)
  main = TOPLEVEL_BINDING.eval("self")

  context = Context.new
  context.instance_eval(&block)

  main.instance_eval do
    namespace ns do

      desc "Builds the application into a docker image"
      task :build do
        sh "docker build -t #{context.image}:#{context.revision} -t #{context.image}:latest ."
      end

      desc "Push the application's docker image to the docker registry"
      task :push do
        sh "docker push #{context.image}"
      end

      context.stages.each do |stage|
        namespace stage.name do

          desc "deploy the application"
          task deploy: stage.deploy

          desc "Stop the application and remove its container"
          task :stop do
            stage.run "docker inspect #{stage.container} 2>&1 > /dev/null && docker kill #{stage.container} && docker rm #{stage.container} || true"
          end

          desc "Start the application in a container using the latest image."
          task :start do
            stage.run "docker run -d #{stage.port_mappings} #{stage.link_mappings} #{stage.options} --name #{stage.container} #{context.image}:latest"

            puts "\n\nstarted: #{stage.host}\n"
          end

          desc "Restart the running container."
          task restart: [:stop, :start]

          stage.services.each do |service|
            namespace service.name do
              desc "Stop the #{service.name} service and remove its container"
              task :stop do
                stage.run "docker inspect #{service.container} 2>&1 > /dev/null && docker kill #{service.container} && docker rm #{service.container} || true"
              end

              desc "Start the #{service.name} service in a container using the latest image."
              task :start do
                stage.run "docker run -d #{service.port_mappings} #{stage.link_mappings} #{stage.options} --name #{service.container} #{context.image}:latest #{service.command}"
              end

              desc "Restart the #{service.name} service."
              task restart: [:stop, :start]

              desc "Tail log of the #{service.name} service."
              task :tail do
                stage.run "docker logs --tail 50 -f #{service.container}"
              end
            end
          end

          desc "Run migrations in the latest image."
          task :migrate do
            stage.shell "docker run #{stage.link_mappings} #{stage.options} -i -t --rm=true #{context.image}:latest bundle exec rake db:create db:migrate"
          end

          desc "Run a Rails console in a container"
          task :console do
            stage.shell "docker run #{stage.options} -i -t --rm=true #{stage.link_mappings} #{context.image}:latest bundle exec rails console"
          end

          desc "Run a shell in a container"
          task :shell do
            stage.shell "docker run #{stage.options} -i -t --rm=true #{stage.link_mappings} #{context.image}:latest /bin/bash"
          end

          desc "Tail log files"
          task :tail do
            stage.run "docker logs --tail 50 -f #{stage.container}"
          end

          if stage.is_a?(RemoteStage)
            desc "Pull down code from the docker registry"
            task :pull do
              stage.run "docker pull #{context.image}"
            end

            desc "SSH into a host server"
            task :ssh do
              stage.shell
            end
          end
        end
      end
    end
  end
end