docker-publish 0.0.1
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 +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: []
|