docker-publish 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/LICENSE +22 -0
- data/README.md +2 -0
- data/docker-publish.gemspec +14 -0
- data/lib/build/build.rb +22 -0
- data/lib/build/composer.rb +59 -0
- data/lib/build/docker.rb +43 -0
- data/lib/build/symfony/doctrine.rb +41 -0
- data/lib/build/symfony/symfony.rb +30 -0
- data/lib/deploy/deploy.rb +9 -0
- data/lib/deploy/docker_compose.rb +34 -0
- data/lib/docker_publish.rb +19 -0
- data/lib/infrastructure/google_cloud_platform/google_cloud_platform.rb +55 -0
- data/lib/infrastructure/google_cloud_platform/google_cloud_storage.rb +49 -0
- data/lib/infrastructure/google_cloud_platform/startup.sh.dist +12 -0
- data/lib/infrastructure/infrastructure.rb +10 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 603e9552a43527a5befd9f7dd8077cab7693615b
|
4
|
+
data.tar.gz: 11cbe4ff2ee9a4e46fe7a0484fc41a2388d04b01
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ae492d4d47e98671a6e645aa6af0150f303e4d7892a6474a0bb98fabeac3e510c1120d1d0efcfe5cbc4d6552bba2b04c338936f2f08bc5e931a836b9a3d784e1
|
7
|
+
data.tar.gz: bad2e64239a7808f90baea8813fe1274dbbebc1765fca7fba22ce27cc8c42b5e07c9ea7116e9f11ec3c40df503801dcb3e0824a9b64e449c4165dc6142c6e903
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 VJ Patel
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'docker-publish'
|
3
|
+
s.version = `git describe --abbrev=0`.strip
|
4
|
+
s.date = `date +"%Y-%m-%d"`.strip
|
5
|
+
s.summary = 'Rake and Capistrano tasks'
|
6
|
+
s.description = 'Build and Deployment tasks for use with Rake, Capistrano and Docker'
|
7
|
+
s.authors = ['VJ Patel']
|
8
|
+
s.email = 'meetthevj@gmail.com'
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
s.homepage = 'http://rubygems.org/gems/docker-publish'
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.add_runtime_dependency 'gcloud',
|
13
|
+
['= 0.1.0']
|
14
|
+
end
|
data/lib/build/build.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class Build
|
2
|
+
|
3
|
+
# @return [Composer]
|
4
|
+
def self.composer
|
5
|
+
Composer
|
6
|
+
end
|
7
|
+
|
8
|
+
# @return [Docker]
|
9
|
+
def self.docker
|
10
|
+
Docker
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Symfony]
|
14
|
+
def self.symfony
|
15
|
+
Symfony
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'build/composer'
|
21
|
+
require 'build/docker'
|
22
|
+
require 'build/symfony/symfony'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Composer
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [string] data_container_name
|
8
|
+
# @param [hash] env_hash
|
9
|
+
def development(data_container_name, env_hash)
|
10
|
+
puts '-- Installing Composer development dependencies'
|
11
|
+
docker_command = self.get_docker_command(data_container_name, env_hash) + 'install --verbose --profile'
|
12
|
+
puts '---- Running: ' << docker_command
|
13
|
+
fail 'Composer development installation failed' unless system docker_command
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [string] data_container_name
|
17
|
+
# @param [hash] env_hash
|
18
|
+
def production(data_container_name, env_hash)
|
19
|
+
puts '---- Installing Composer production dependencies'
|
20
|
+
docker_command = self.get_docker_command(data_container_name, env_hash) + 'install --no-dev --optimize-autoloader --no-interaction --verbose --profile'
|
21
|
+
puts '---- Running: ' << docker_command
|
22
|
+
fail 'Composer production installation failed' unless system docker_command
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
# @param [string] data_container_name
|
27
|
+
# @param [hash] env_hash
|
28
|
+
# @return [string]
|
29
|
+
def get_docker_command(data_container_name, env_hash)
|
30
|
+
puts '---- Launching Composer container'
|
31
|
+
docker_env_vars = env_hash.map{|k,v| "#{k}=#{v}"}.join(' --env ')
|
32
|
+
docker_command = "docker run --rm --volumes-from #{data_container_name} "
|
33
|
+
if docker_env_vars.length > 5
|
34
|
+
docker_command << "--env #{docker_env_vars} "
|
35
|
+
end
|
36
|
+
docker_command << 'vjftw/composer '
|
37
|
+
|
38
|
+
docker_command
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [hash] args
|
42
|
+
# @return [hash]
|
43
|
+
def convert_env_args_to_env_hash(args)
|
44
|
+
env_hash = {}
|
45
|
+
|
46
|
+
# do first arg
|
47
|
+
env_var = args[:env].split('=')
|
48
|
+
env_hash[env_var[0].to_sym] = env_var[1]
|
49
|
+
|
50
|
+
# do rest of args
|
51
|
+
args.extras.each do |x|
|
52
|
+
env_var = x.split('=')
|
53
|
+
env_hash[env_var[0].to_sym] = env_var[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
env_hash
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/build/docker.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class Docker
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [string] image_id
|
8
|
+
# @param [string] tag
|
9
|
+
# @return [string] The tag we just tagged the container with
|
10
|
+
def tag(image_id, tag)
|
11
|
+
command = "docker tag #{image_id} #{tag}"
|
12
|
+
puts command
|
13
|
+
system command
|
14
|
+
tag
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [string] tag
|
18
|
+
# @return [string] The tag we just pushed up
|
19
|
+
def push(tag)
|
20
|
+
command = "docker push #{tag}"
|
21
|
+
puts command
|
22
|
+
system command
|
23
|
+
tag
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [string] docker_file_path
|
27
|
+
# @return [string] The ID of the image that was built in Docker
|
28
|
+
def build_data_container(docker_file_path)
|
29
|
+
command = "docker build #{docker_file_path}"
|
30
|
+
output = `#{command}`
|
31
|
+
|
32
|
+
puts output
|
33
|
+
|
34
|
+
output_match = /(Successfully built )(.*)/.match(output)
|
35
|
+
|
36
|
+
fail 'Docker failed to build the container!' unless output_match
|
37
|
+
|
38
|
+
puts "Built Data Container Image: #{output_match[2]}"
|
39
|
+
|
40
|
+
output_match[2]
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Doctrine
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [string] data_container_name
|
8
|
+
# @param [string] db_container_name
|
9
|
+
def create_database(data_container_name, db_container_name = nil)
|
10
|
+
puts '-- Creating Symfony Doctrine database'
|
11
|
+
docker_command = self.get_docker_command(data_container_name, db_container_name) << 'doctrine:database:create'
|
12
|
+
puts '---- Running: ' << docker_command
|
13
|
+
output = `#{docker_command}`
|
14
|
+
print output
|
15
|
+
fail 'Database creation failed!' unless /(exists|Created)/.match(output)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [string] data_container_name
|
19
|
+
# @param [string] db_container_name
|
20
|
+
def run_migrations(data_container_name, db_container_name = nil)
|
21
|
+
puts '-- Running Symfony Doctrine migrations'
|
22
|
+
docker_command = self.get_docker_command(data_container_name, db_container_name) << 'doctine:migrations:migrate --no-interaction'
|
23
|
+
puts '---- Running: ' << docker_command
|
24
|
+
fail 'Database migrations failed!' unless system docker_command
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
# @param [string] data_container_name
|
29
|
+
# @param [string] db_container_name
|
30
|
+
# @return [string]
|
31
|
+
def get_docker_command(data_container_name, db_container_name = nil)
|
32
|
+
docker_command = "docker run --rm --volumes-from #{data_container_name} "
|
33
|
+
if db_container_name != nil
|
34
|
+
docker_command << "--link #{db_container_name}:#{db_container_name} "
|
35
|
+
end
|
36
|
+
docker_command << 'vjftw/php-cli app/console --ansi '
|
37
|
+
|
38
|
+
docker_command
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Symfony
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@doctrine = Doctrine.new
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Doctrine]
|
8
|
+
def doctrine
|
9
|
+
@doctrine
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [string] data_container_name
|
13
|
+
def purge_cache(data_container_name)
|
14
|
+
puts `docker run --rm --volumes-from #{data_container_name} vjftw/data /bin/bash -l -c "mkdir -p app/cache"`
|
15
|
+
puts `docker run --rm --volumes-from #{data_container_name} vjftw/data /bin/bash -l -c "rm -rf app/cache/*"`
|
16
|
+
puts `docker run --rm --volumes-from #{data_container_name} vjftw/data /bin/bash -l -c "chmod -R 777 app/cache"`
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [string] data_container_name
|
20
|
+
# @param [string] command
|
21
|
+
def run_console_command(data_container_name, command)
|
22
|
+
docker_command = "docker run --rm --volumes-from #{data_container_name} vjftw/php-cli app/console --ansi #{command}"
|
23
|
+
|
24
|
+
puts docker_command
|
25
|
+
|
26
|
+
`#{docker_command}`
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'build/symfony/doctrine'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class DockerCompose
|
2
|
+
|
3
|
+
def initialize(project_name, app_name)
|
4
|
+
@project_name = project_name
|
5
|
+
@app_name = app_name
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param [string] dist_file_path
|
10
|
+
# @param [string] duty
|
11
|
+
# @param [int] port
|
12
|
+
# @param [string] image_tag
|
13
|
+
def generate_compose_yaml(dist_file_path, duty, port, image_tag)
|
14
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
15
|
+
commit = `git rev-parse --short HEAD`.strip
|
16
|
+
path = File.dirname(dist_file_path)
|
17
|
+
file_path = "#{path}/#{@app_name}-#{branch}-#{commit}_#{duty}.yaml"
|
18
|
+
|
19
|
+
dist = File.read(dist_file_path)
|
20
|
+
|
21
|
+
dist = dist.gsub('<port>', port.to_s)
|
22
|
+
dist = dist.gsub('<image>', image_tag)
|
23
|
+
|
24
|
+
out_file = File.new(file_path, 'w')
|
25
|
+
out_file.puts(dist)
|
26
|
+
out_file.close
|
27
|
+
|
28
|
+
puts "Generated: #{file_path} \n Contents: #{dist}"
|
29
|
+
|
30
|
+
file_path
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class DockerPublish
|
2
|
+
|
3
|
+
def self.build
|
4
|
+
Build
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.deploy
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.infrastructure
|
12
|
+
Infrastructure
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'infrastructure/infrastructure'
|
18
|
+
require 'build/build'
|
19
|
+
require 'deploy/deploy'
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class GoogleCloudPlatform
|
2
|
+
|
3
|
+
# @param [string] project_name
|
4
|
+
# @param [string] app_name
|
5
|
+
def initialize(project_name, app_name)
|
6
|
+
@project_name = project_name
|
7
|
+
@app_name = app_name
|
8
|
+
@credentials = ENV['GOOGLE_CLOUD_KEYFILE']
|
9
|
+
unless credentials
|
10
|
+
puts 'Google Cloud credentials file not set. Run export GOOGLE_CLOUD_KEYFILE=<your_keyfile>.json'
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
@google_cloud_storage = GoogleCloudStorage.new(@project_name, @app_name, @credentials)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [string]
|
17
|
+
def get_container_tag
|
18
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
19
|
+
commit = `git rev-parse --short HEAD`.strip
|
20
|
+
|
21
|
+
tag = "gcr.io/#{@project_name}/#{@app_name}:#{branch}-#{commit}"
|
22
|
+
|
23
|
+
puts tag
|
24
|
+
|
25
|
+
tag
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [string]
|
29
|
+
def generate_startup_script
|
30
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
31
|
+
|
32
|
+
dist = File.read('infrastructure/google_cloud_platform/startup.sh.dist')
|
33
|
+
|
34
|
+
dist = dist.gsub('<bucket_name>', @app_name)
|
35
|
+
dist = dist.gsub('<app_name>', @app_name)
|
36
|
+
dist = dist.gsub('<primary_yaml>', self.get_yaml_filename('primary', true))
|
37
|
+
dist = dist.gsub('<backup_yaml>', self.get_yaml_filename('backup', true))
|
38
|
+
|
39
|
+
filename = "#{branch}-startup.sh"
|
40
|
+
out_file = File.new(filename, 'w')
|
41
|
+
out_file.puts(dist)
|
42
|
+
out_file.close
|
43
|
+
|
44
|
+
puts "Generated: #{filename} \n Contents: #{dist}"
|
45
|
+
|
46
|
+
filename
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [GoogleCloudStorage]
|
50
|
+
def storage
|
51
|
+
@google_cloud_storage
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'infrastructure/google_cloud_platform/google_cloud_storage'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class GoogleCloudStorage
|
2
|
+
|
3
|
+
# @param [string] project_name
|
4
|
+
# @param [string] app_name
|
5
|
+
# @param [string] credentials_path
|
6
|
+
def initialize(project_name, app_name, credentials_path)
|
7
|
+
@project_name = project_name
|
8
|
+
@app_name = app_name
|
9
|
+
@credentials = credentials_path
|
10
|
+
|
11
|
+
@storage = Gcloud.storage @project_name, @credentials
|
12
|
+
|
13
|
+
@bucket = get_bucket
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
# @return [Bucket]
|
18
|
+
def get_bucket
|
19
|
+
buckets = @storage.buckets
|
20
|
+
buckets.each do |bucket|
|
21
|
+
if bucket.name == @app_name
|
22
|
+
return bucket
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@storage.create_bucket @app_name, retries: 3
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [string] filepath
|
30
|
+
# @param [string] storage_path
|
31
|
+
# @return [File]
|
32
|
+
def put_file(filepath, storage_path)
|
33
|
+
puts "Putting #{filename} on Google Cloud Storage"
|
34
|
+
@bucket.create_file filepath, storage_path
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [string] existing_filepath
|
38
|
+
# @param [string] new_filepath
|
39
|
+
# @return [File]
|
40
|
+
def copy_file(existing_filepath, new_filepath)
|
41
|
+
existing_file = @bucket.find_file existing_filepath
|
42
|
+
|
43
|
+
puts "Copying #{existing_filepath} to #{new_filepath}"
|
44
|
+
existing_file.copy new_filepath
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
require 'gcloud/storage'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
gsutil cp gs://<bucket_name>/docker-compose/<primary_yaml> .
|
4
|
+
gsutil cp gs://<bucket_name>/docker-compose/<backup_yaml> .
|
5
|
+
|
6
|
+
# Pull Primary Containers and start them (faster service availability)
|
7
|
+
docker-compose pull -p <app_name> -f <primary_yaml>
|
8
|
+
docker-compose up -p <app_name> -f <primary_yaml> -d
|
9
|
+
|
10
|
+
# Pull Backup containers and start them
|
11
|
+
docker-compose pull -p <app_name> -f <backup_yaml>
|
12
|
+
docker-compose up -p <app_name> -f <backup_yaml> -d
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docker-publish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- VJ Patel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gcloud
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
description: Build and Deployment tasks for use with Rake, Capistrano and Docker
|
28
|
+
email: meetthevj@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- ".gitignore"
|
34
|
+
- LICENSE
|
35
|
+
- README.md
|
36
|
+
- docker-publish.gemspec
|
37
|
+
- lib/build/build.rb
|
38
|
+
- lib/build/composer.rb
|
39
|
+
- lib/build/docker.rb
|
40
|
+
- lib/build/symfony/doctrine.rb
|
41
|
+
- lib/build/symfony/symfony.rb
|
42
|
+
- lib/deploy/deploy.rb
|
43
|
+
- lib/deploy/docker_compose.rb
|
44
|
+
- lib/docker_publish.rb
|
45
|
+
- lib/infrastructure/google_cloud_platform/google_cloud_platform.rb
|
46
|
+
- lib/infrastructure/google_cloud_platform/google_cloud_storage.rb
|
47
|
+
- lib/infrastructure/google_cloud_platform/startup.sh.dist
|
48
|
+
- lib/infrastructure/infrastructure.rb
|
49
|
+
homepage: http://rubygems.org/gems/docker-publish
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 2.4.6
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: Rake and Capistrano tasks
|
73
|
+
test_files: []
|