conjure 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +8 -0
- data/lib/conjure/provision/docker/host.rb +1 -1
- data/lib/conjure/provision/docker/image.rb +35 -2
- data/lib/conjure/provision/docker/template.rb +4 -0
- data/lib/conjure/provision/instance.rb +3 -2
- data/lib/conjure/provision/passenger.rb +37 -8
- data/lib/conjure/provision/postgres.rb +29 -3
- data/lib/conjure/provision/server.rb +5 -5
- data/lib/conjure/provision/templates/application-no-ssl.conf.erb +1 -1
- data/lib/conjure/provision/templates/application-ssl.conf.erb +10 -10
- data/lib/conjure/service/cloud_server.rb +0 -1
- data/lib/conjure/version.rb +1 -1
- metadata +38 -39
- data/lib/conjure/notes.txt +0 -201
data/History.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### Version 0.2.9
|
2
|
+
2015-06-24
|
3
|
+
|
4
|
+
* Add ssl_hostname and instance_size provisioning options
|
5
|
+
* Use volumes to store data for provisioned containers
|
6
|
+
* Make provisioned containers restart on reboot
|
7
|
+
* Upgrade provisioned Ruby version to 2.2
|
8
|
+
|
1
9
|
### Version 0.2.8
|
2
10
|
2014-10-31
|
3
11
|
|
@@ -18,7 +18,7 @@ module Conjure
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def started_container_id(image_name, daemon_command, run_options = nil)
|
21
|
-
all_options = "
|
21
|
+
all_options = "#{run_options.to_s} #{image_name} #{daemon_command}"
|
22
22
|
@platform.run("docker run #{all_options}").strip
|
23
23
|
end
|
24
24
|
|
@@ -9,13 +9,46 @@ module Conjure
|
|
9
9
|
@name = image_name
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def start_volume(options = {})
|
13
|
+
@docker_host.started_container_id @name, "/bin/true", daemon_options(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_daemon(command, options = {})
|
17
|
+
container_id = @docker_host.started_container_id @name, command, daemon_options(options)
|
14
18
|
sleep 2
|
15
19
|
ip_address = @docker_host.container_ip_address container_id
|
16
20
|
raise "Container failed to start" unless ip_address.present?
|
17
21
|
ip_address
|
18
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def volume_options(options)
|
27
|
+
"-d " + run_options(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def daemon_options(options)
|
31
|
+
"-d --restart=always " + run_options(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def run_options(options)
|
35
|
+
[
|
36
|
+
mapped_options("--link", options[:linked_containers]),
|
37
|
+
("--name #{options[:name]}" if options[:name]),
|
38
|
+
mapped_options("-p", options[:ports]),
|
39
|
+
listed_options("--volumes-from", options[:volume_containers]),
|
40
|
+
].flatten.compact.join(" ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def listed_options(command, values)
|
44
|
+
values ||= []
|
45
|
+
values.map { |v| "#{command} #{v}" }
|
46
|
+
end
|
47
|
+
|
48
|
+
def mapped_options(command, values)
|
49
|
+
values ||= {}
|
50
|
+
values.map { |from, to| "#{command} #{from}:#{to}" }
|
51
|
+
end
|
19
52
|
end
|
20
53
|
end
|
21
54
|
end
|
@@ -18,7 +18,7 @@ module Conjure
|
|
18
18
|
if options[:local]
|
19
19
|
platform = LocalDocker.new
|
20
20
|
else
|
21
|
-
platform = Server.create "#{@app_name}-#{@rails_env}"
|
21
|
+
platform = Server.create "#{@app_name}-#{@rails_env}", @options
|
22
22
|
end
|
23
23
|
|
24
24
|
database = Postgres.new(platform)
|
@@ -39,7 +39,8 @@ module Conjure
|
|
39
39
|
:ip_address => ip_address,
|
40
40
|
:port => port,
|
41
41
|
:user => "app",
|
42
|
-
:rails_env => @rails_env
|
42
|
+
:rails_env => @rails_env,
|
43
|
+
:pending_files => webserver.pending_files,
|
43
44
|
}
|
44
45
|
end
|
45
46
|
|
@@ -13,22 +13,52 @@ module Conjure
|
|
13
13
|
@nginx_directives = options[:nginx_directives] || {}
|
14
14
|
@system_packages = options[:system_packages] || []
|
15
15
|
@rubygems_version = options[:rubygems_version]
|
16
|
+
@use_ssl = !!options[:ssl_hostname]
|
17
|
+
@ssl_hostname = options[:ssl_hostname] || "unknown"
|
16
18
|
end
|
17
19
|
|
18
20
|
def start
|
19
|
-
@ip_address =
|
21
|
+
@ip_address = server_template.build(@platform).start_daemon("/sbin/my_init", start_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pending_files
|
25
|
+
return [] unless @use_ssl
|
26
|
+
[
|
27
|
+
"/etc/ssl/certs/application.crt",
|
28
|
+
"/etc/ssl/certs/root_and_intermediates.crt",
|
29
|
+
"/etc/ssl/private/application.key",
|
30
|
+
"/etc/ssl/dhparam.pem",
|
31
|
+
]
|
20
32
|
end
|
21
33
|
|
22
34
|
private
|
23
35
|
|
24
36
|
def start_options
|
25
|
-
{
|
37
|
+
{
|
38
|
+
:linked_containers => @database.container_link,
|
39
|
+
:name => "passenger",
|
40
|
+
:ports => {80 => 80, 443 => 443, 2222 => 22},
|
41
|
+
:volume_containers => [data_container_name],
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def data_container_name
|
46
|
+
data_template.build(@platform).start_volume(:name => "passenger_data")
|
47
|
+
"passenger_data"
|
26
48
|
end
|
27
49
|
|
28
|
-
def
|
50
|
+
def data_template
|
51
|
+
file = Docker::Template.new("conjure/passenger-ruby22:1.0.0")
|
52
|
+
file.add_file_data database_yml, "/home/app/application/shared/config/database.yml"
|
53
|
+
file.add_file_data secrets_yml, "/home/app/application/shared/config/secrets.yml"
|
54
|
+
file.volume "/home/app/application"
|
55
|
+
file
|
56
|
+
end
|
57
|
+
|
58
|
+
def server_template
|
29
59
|
public_key = File.expand_path("~/.ssh/id_rsa.pub")
|
30
60
|
raise "Error: ~/.ssh/id_rsa.pub must exist." unless File.exist?(public_key)
|
31
|
-
file = Docker::Template.new("conjure/passenger-
|
61
|
+
file = Docker::Template.new("conjure/passenger-ruby22:1.0.0")
|
32
62
|
file.run apt_command if apt_command
|
33
63
|
file.run rubygems_command if rubygems_command
|
34
64
|
file.add_file public_key, "/root/.ssh/authorized_keys"
|
@@ -37,9 +67,8 @@ module Conjure
|
|
37
67
|
file.run "chown root.root /root/.ssh/authorized_keys"
|
38
68
|
file.add_file_data nginx_conf, "/etc/nginx/sites-available/application-no-ssl.conf"
|
39
69
|
file.add_file_data nginx_ssl_conf, "/etc/nginx/sites-available/application-ssl.conf"
|
40
|
-
|
41
|
-
file.
|
42
|
-
file.add_file_data secrets_yml, "/home/app/application/shared/config/secrets.yml"
|
70
|
+
which_config = @use_ssl ? "application-ssl" : "application-no-ssl"
|
71
|
+
file.run "ln -s /etc/nginx/sites-available/#{which_config}.conf /etc/nginx/sites-enabled/application.conf"
|
43
72
|
file
|
44
73
|
end
|
45
74
|
|
@@ -75,7 +104,7 @@ module Conjure
|
|
75
104
|
def render_template(name)
|
76
105
|
template_path = File.join File.dirname(__FILE__), "templates", "#{name}.erb"
|
77
106
|
template_data = File.read template_path
|
78
|
-
Erubis::Eruby.new(template_data).result :rails_env => @rails_env
|
107
|
+
Erubis::Eruby.new(template_data).result :rails_env => @rails_env, :ssl_hostname => @ssl_hostname
|
79
108
|
end
|
80
109
|
end
|
81
110
|
end
|
@@ -11,23 +11,49 @@ module Conjure
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def start
|
14
|
-
@ip_address =
|
14
|
+
@ip_address = server_template.build(@platform).start_daemon("/sbin/my_init", start_options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def rails_config
|
18
18
|
{
|
19
19
|
"adapter" => "postgresql",
|
20
20
|
"database" => @name,
|
21
|
-
"host" =>
|
21
|
+
"host" => container_name,
|
22
22
|
"username" => "db",
|
23
23
|
"password" => @password,
|
24
24
|
"template" => "template0",
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
28
|
+
def container_link
|
29
|
+
{container_name => container_name}
|
30
|
+
end
|
31
|
+
|
28
32
|
private
|
29
33
|
|
30
|
-
def
|
34
|
+
def start_options
|
35
|
+
{
|
36
|
+
:name => container_name,
|
37
|
+
:volume_containers => [data_container_name],
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def container_name
|
42
|
+
"postgres"
|
43
|
+
end
|
44
|
+
|
45
|
+
def data_container_name
|
46
|
+
data_template.build(@platform).start_volume(:name => "postgres_data")
|
47
|
+
"postgres_data"
|
48
|
+
end
|
49
|
+
|
50
|
+
def data_template
|
51
|
+
file = Docker::Template.new("conjure/postgres93:1.0.0")
|
52
|
+
file.volume "/var/lib/postgresql/9.3/main"
|
53
|
+
file
|
54
|
+
end
|
55
|
+
|
56
|
+
def server_template
|
31
57
|
file = Docker::Template.new("conjure/postgres93:1.0.0")
|
32
58
|
file.run "echo \"ALTER USER db PASSWORD '#{@password}'\" >/tmp/setpass"
|
33
59
|
file.run "/sbin/my_init -- /sbin/setuser postgres sh -c \"sleep 1; psql -f /tmp/setpass\""
|
@@ -31,23 +31,23 @@ module Conjure
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def install_swap
|
34
|
-
run "dd if=/dev/zero of=/root/swapfile bs=
|
34
|
+
run "dd if=/dev/zero of=/root/swapfile bs=4096 count=524288"
|
35
35
|
run "mkswap /root/swapfile; swapon /root/swapfile"
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.create(name)
|
38
|
+
def self.create(name, options = {})
|
39
39
|
puts "Creating DigitalOcean droplet..."
|
40
|
-
new DigitalOcean::Droplet.new(droplet_options
|
40
|
+
new DigitalOcean::Droplet.new(droplet_options(uniquify(name), options))
|
41
41
|
end
|
42
42
|
|
43
|
-
def self.droplet_options(name)
|
43
|
+
def self.droplet_options(name, options = {})
|
44
44
|
raise "Error: DIGITALOCEAN_API_TOKEN must be set." unless ENV["DIGITALOCEAN_API_TOKEN"]
|
45
45
|
{
|
46
46
|
image: "docker",
|
47
47
|
key_data: key_data,
|
48
48
|
name: name,
|
49
49
|
region: "nyc3",
|
50
|
-
size: "512mb",
|
50
|
+
size: (options[:instance_size] || "512mb"),
|
51
51
|
token: ENV["DIGITALOCEAN_API_TOKEN"],
|
52
52
|
}
|
53
53
|
end
|
@@ -5,23 +5,23 @@ server {
|
|
5
5
|
|
6
6
|
server {
|
7
7
|
listen 443 ssl;
|
8
|
+
server_name <%= ssl_hostname %>;
|
8
9
|
root /home/app/application/current/public;
|
9
10
|
passenger_enabled on;
|
10
11
|
passenger_user app;
|
11
|
-
passenger_ruby /usr/bin/ruby2.
|
12
|
+
passenger_ruby /usr/bin/ruby2.2;
|
12
13
|
passenger_app_env <%= rails_env %>;
|
13
14
|
|
14
15
|
ssl_certificate /etc/ssl/certs/application.crt;
|
15
16
|
ssl_certificate_key /etc/ssl/private/application.key;
|
17
|
+
ssl_session_timeout 1d;
|
18
|
+
ssl_session_cache shared:SSL:50m;
|
19
|
+
ssl_dhparam /etc/ssl/dhparam.pem;
|
16
20
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
17
|
-
ssl_ciphers
|
21
|
+
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
18
22
|
ssl_prefer_server_ciphers on;
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
proxy_set_header X-Real-IP $remote_addr;
|
24
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
25
|
-
proxy_set_header Host $http_host;
|
26
|
-
proxy_redirect off;
|
23
|
+
ssl_stapling on;
|
24
|
+
ssl_stapling_verify on;
|
25
|
+
ssl_trusted_certificate /etc/ssl/certs/root_and_intermediates.crt;
|
26
|
+
resolver 8.8.8.8 8.8.4.4;
|
27
27
|
}
|
data/lib/conjure/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conjure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,16 +9,16 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-06-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: net-scp
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,9 +26,9 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: net-ssh
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: thor
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
@@ -163,54 +163,53 @@ executables:
|
|
163
163
|
extensions: []
|
164
164
|
extra_rdoc_files: []
|
165
165
|
files:
|
166
|
-
- lib/conjure.rb
|
167
|
-
- lib/conjure/instance.rb
|
168
|
-
- lib/conjure/target.rb
|
169
|
-
- lib/conjure/provider.rb
|
170
166
|
- lib/conjure/application.rb
|
167
|
+
- lib/conjure/command.rb
|
171
168
|
- lib/conjure/command_target.rb
|
172
|
-
- lib/conjure/log.rb
|
173
|
-
- lib/conjure/version.rb
|
174
169
|
- lib/conjure/config.rb
|
170
|
+
- lib/conjure/data_set.rb
|
171
|
+
- lib/conjure/digital_ocean/account.rb
|
172
|
+
- lib/conjure/digital_ocean/droplet.rb
|
173
|
+
- lib/conjure/digital_ocean/key.rb
|
174
|
+
- lib/conjure/digital_ocean/key_set.rb
|
175
|
+
- lib/conjure/http_request.rb
|
175
176
|
- lib/conjure/identity.rb
|
176
|
-
- lib/conjure/
|
177
|
+
- lib/conjure/instance.rb
|
178
|
+
- lib/conjure/log.rb
|
179
|
+
- lib/conjure/provider.rb
|
180
|
+
- lib/conjure/provision/docker/host.rb
|
181
|
+
- lib/conjure/provision/docker/image.rb
|
182
|
+
- lib/conjure/provision/docker/template.rb
|
177
183
|
- lib/conjure/provision/instance.rb
|
184
|
+
- lib/conjure/provision/local_docker.rb
|
178
185
|
- lib/conjure/provision/passenger.rb
|
179
186
|
- lib/conjure/provision/postgres.rb
|
180
|
-
- lib/conjure/provision/
|
181
|
-
- lib/conjure/provision/docker/template.rb
|
182
|
-
- lib/conjure/provision/docker/image.rb
|
183
|
-
- lib/conjure/provision/templates/application-ssl.conf.erb
|
187
|
+
- lib/conjure/provision/server.rb
|
184
188
|
- lib/conjure/provision/templates/application-no-ssl.conf.erb
|
185
|
-
- lib/conjure/provision/
|
186
|
-
- lib/conjure/
|
187
|
-
- lib/conjure/
|
188
|
-
- lib/conjure/service/digital_ocean_account.rb
|
189
|
-
- lib/conjure/service/rails_codebase.rb
|
190
|
-
- lib/conjure/service/database/postgres.rb
|
189
|
+
- lib/conjure/provision/templates/application-ssl.conf.erb
|
190
|
+
- lib/conjure/provision.rb
|
191
|
+
- lib/conjure/service/cloud_server.rb
|
191
192
|
- lib/conjure/service/database/mysql.rb
|
192
|
-
- lib/conjure/service/
|
193
|
-
- lib/conjure/service/docker_host.rb
|
193
|
+
- lib/conjure/service/database/postgres.rb
|
194
194
|
- lib/conjure/service/database.rb
|
195
|
-
- lib/conjure/service/
|
195
|
+
- lib/conjure/service/digital_ocean_account.rb
|
196
|
+
- lib/conjure/service/docker_host.rb
|
197
|
+
- lib/conjure/service/docker_shell.rb
|
196
198
|
- lib/conjure/service/forwarded_shell.rb
|
199
|
+
- lib/conjure/service/rails_codebase.rb
|
200
|
+
- lib/conjure/service/rails_console.rb
|
201
|
+
- lib/conjure/service/rails_log_view.rb
|
197
202
|
- lib/conjure/service/rails_server.rb
|
203
|
+
- lib/conjure/service/rake_task.rb
|
198
204
|
- lib/conjure/service/remote_file_set.rb
|
199
205
|
- lib/conjure/service/remote_shell.rb
|
200
|
-
- lib/conjure/service/rails_console.rb
|
201
|
-
- lib/conjure/service/rake_task.rb
|
202
|
-
- lib/conjure/service/docker_shell.rb
|
203
206
|
- lib/conjure/service/repository_link.rb
|
204
207
|
- lib/conjure/service/volume.rb
|
205
|
-
- lib/conjure/
|
206
|
-
- lib/conjure/
|
207
|
-
- lib/conjure/view/table_view.rb
|
208
|
+
- lib/conjure/target.rb
|
209
|
+
- lib/conjure/version.rb
|
208
210
|
- lib/conjure/view/application_view.rb
|
209
|
-
- lib/conjure/
|
210
|
-
- lib/conjure
|
211
|
-
- lib/conjure/digital_ocean/account.rb
|
212
|
-
- lib/conjure/digital_ocean/droplet.rb
|
213
|
-
- lib/conjure/http_request.rb
|
211
|
+
- lib/conjure/view/table_view.rb
|
212
|
+
- lib/conjure.rb
|
214
213
|
- README.md
|
215
214
|
- History.md
|
216
215
|
- License.txt
|
@@ -236,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
235
|
version: 1.3.6
|
237
236
|
requirements: []
|
238
237
|
rubyforge_project:
|
239
|
-
rubygems_version: 1.8.
|
238
|
+
rubygems_version: 1.8.30
|
240
239
|
signing_key:
|
241
240
|
specification_version: 3
|
242
241
|
summary: Magically powerful deployment for Rails applications
|
data/lib/conjure/notes.txt
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
==== New hook-based architecture:
|
2
|
-
1. Proxy app, binds to machine's ports and proxies traffic to other containers
|
3
|
-
2. Deployer app, builds and starts revisions of the app in other containers
|
4
|
-
- Recieves github push notification, builds a new container with the new app revision
|
5
|
-
- Uses a custom-built Dockerfile for the app, designed to rebuild with minimal i/o
|
6
|
-
- After new revision is verified up and running, notifies the proxy to redirect
|
7
|
-
- Could run a small capybara smoke test against the production app
|
8
|
-
- Stops old container. Destroys it? (Rebuilding it should be fast if needed)
|
9
|
-
3. The application itself
|
10
|
-
====
|
11
|
-
|
12
|
-
1. Add area in conjure repo to build and publish docker images
|
13
|
-
- publish "conjure/passenger-ruby21"
|
14
|
-
- publish "conjure/postgres"
|
15
|
-
2. Add isolated conjure commands to work with custom docker images:
|
16
|
-
- "provision [rails-env]"
|
17
|
-
- Creates DO server using DIGITAL_OCEAN_* env vars
|
18
|
-
- Starts conjure/postgres
|
19
|
-
- Installs shared database.yml
|
20
|
-
- Adds 'passenger_app_env ENV' to http{} section of nginx.conf
|
21
|
-
- Starts conjure/passenger-ruby21 linked to postgres
|
22
|
-
- Displays needed Cap info: ip, ssh port, deploy user, app path, rails_env
|
23
|
-
- "addkey [ip] [sshport]"
|
24
|
-
3. Add conjure to client app & run "provision staging"
|
25
|
-
4. Add Cap to client app and configure staging settings
|
26
|
-
5. "cap staging deploy" from client app
|
27
|
-
|
28
|
-
==== Steps to deploy w/ Cap:
|
29
|
-
|
30
|
-
Dockerfile (webserver):
|
31
|
-
Install passenger/nginx
|
32
|
-
Install likely gem dependencies incl. node
|
33
|
-
Install required ruby version
|
34
|
-
Dockerfile (postgres):
|
35
|
-
|
36
|
-
Conjure:
|
37
|
-
Provision DigitalOcean Docker instance
|
38
|
-
|
39
|
-
Postgres:
|
40
|
-
Start postgres container
|
41
|
-
|
42
|
-
Passenger:
|
43
|
-
Start webserver container linked to postgres container
|
44
|
-
Install public key in webserver container
|
45
|
-
Install nginx config for app
|
46
|
-
Install shared database.yml
|
47
|
-
|
48
|
-
Script in app:
|
49
|
-
Capistrano:
|
50
|
-
Deploy current app version
|
51
|
-
|
52
|
-
|
53
|
-
TASKS:
|
54
|
-
Remove "label" from prepared shell creation
|
55
|
-
Alternate way to show per-service progress output
|
56
|
-
Log creation and status from each service
|
57
|
-
Log name and IP from docker container creation in verbose mode only
|
58
|
-
Separate platforms vs services
|
59
|
-
Deployment.deploy should become Deployment.create
|
60
|
-
|
61
|
-
Instead of passing DockerHost objects around, pass something that
|
62
|
-
knows how to provision OS shells (possibly from multiple sources).
|
63
|
-
DigitalOceanAccount etc should be an implementation of this interface.
|
64
|
-
shell = shell_source.prepare_shell do
|
65
|
-
run "cmd"
|
66
|
-
run "cmd2"
|
67
|
-
environment :key => "value"
|
68
|
-
port 80
|
69
|
-
end
|
70
|
-
|
71
|
-
Application - the code to be deployed (in the abstract, i.e. in a
|
72
|
-
repo not yet copied to the server(s)
|
73
|
-
|
74
|
-
Instance - a specific running copy of an application
|
75
|
-
accessed through various interfaces: web address, rails console, etc
|
76
|
-
|
77
|
-
Database - n/a, too ambiguous
|
78
|
-
Dataset - A specific data set
|
79
|
-
accessed through an interface w/ a specific db protocol.
|
80
|
-
|
81
|
-
Deployment should return a shell in the app environment as an
|
82
|
-
interface
|
83
|
-
|
84
|
-
Deployment should return a DataSet (that possible aggregates multiple
|
85
|
-
data sets used by the app). If an app needs a MySQL database, a Redis
|
86
|
-
database, and a local directory of user-uploaded files, all these must
|
87
|
-
stay in sync with each other and so should be aggregated under a
|
88
|
-
single DataSet interface.
|
89
|
-
|
90
|
-
Instance should instantiate and provide subsequent access to all
|
91
|
-
runtime dependencies of the codebase. This includes the web server,
|
92
|
-
data sets, etc. An app's mutable local filesystem should be considered
|
93
|
-
a data set too, and probably also the logs.
|
94
|
-
|
95
|
-
An Application should be something more abstract than the current
|
96
|
-
Codebase. It shouldn't know about the rails environment or the
|
97
|
-
database, it should be little more than a reference to a git repo. The
|
98
|
-
concept of a "codebase" that's checked out onto the deployment
|
99
|
-
server(s) should be something else (maybe just a Volume that a branch
|
100
|
-
of the application gets copied to).
|
101
|
-
|
102
|
-
But where do the database, logger, cron jobs, and other required
|
103
|
-
services get identified and instantiated?
|
104
|
-
|
105
|
-
Conjure's basic job is: deploy [something] [somewhere] using
|
106
|
-
[platforms]. "Something" is a Service, of which Instance and DataSet
|
107
|
-
are both types. "Somewhere" is the desired interface over which the
|
108
|
-
new Service will be accessible. "Platform" is the cloud service, local
|
109
|
-
VMs, and other combined platforms that will be used to do the
|
110
|
-
deployment.
|
111
|
-
|
112
|
-
Need a concept for something that has both stdin and stdout (and
|
113
|
-
stderr) streams ("Console"?). This is what's returned by a rake task
|
114
|
-
or rails console instantiation, to connect it to the user's console,
|
115
|
-
and it can also be returned from a CommandShell to give the user
|
116
|
-
direct access to that as well.
|
117
|
-
|
118
|
-
"Show" output prototype:
|
119
|
-
|
120
|
-
# Showing application status (Conjure v1.2.23)
|
121
|
-
# Origin git@github.com/brianauton/conjure
|
122
|
-
# Authorization OK (using public key)
|
123
|
-
#
|
124
|
-
# Deployed Instances:
|
125
|
-
# Address Environment Branch Revision
|
126
|
-
# 192.168.0.1 production master 3FA4D099 (up to date)
|
127
|
-
#
|
128
|
-
# Data Sets:
|
129
|
-
# Name Status Size
|
130
|
-
# production-2 active 2GB
|
131
|
-
# production-1 archived 2MB
|
132
|
-
|
133
|
-
# Showing instance status (Conjure v1.2.23)
|
134
|
-
# Address 192.168.0.1
|
135
|
-
# Environment production
|
136
|
-
# Branch master
|
137
|
-
# Revision 3FA4D099 (behind by 2 commits)
|
138
|
-
# Uptime 2 days, 3 hours, 17 minutes
|
139
|
-
|
140
|
-
Could have "named" instances ("production-2", user-specified names,
|
141
|
-
etc) but "address" is enough to identify instances for now. Should
|
142
|
-
guess the specified instance by either ip address, subdomain (when
|
143
|
-
supported), or rails_env. Need "deploy" to be a shorthand for either
|
144
|
-
"create" or "update" since "deploy staging" is ambiguous if there's
|
145
|
-
already a staging instance. Maybe "deploy" should be deprecated?
|
146
|
-
|
147
|
-
Needs:
|
148
|
-
Separate commands to "create" and "update" instances
|
149
|
-
Support specific env/branch when creating
|
150
|
-
Preserve existing env/branch when updating
|
151
|
-
Support changing env/branch when updating
|
152
|
-
Support default instance params based on addr/env/other info given
|
153
|
-
Destroy instances
|
154
|
-
Introduce "platforms"
|
155
|
-
Deploy to local docker
|
156
|
-
Deploy to vagrant (?)
|
157
|
-
Progress display
|
158
|
-
Allow specifying SHA for deployment (pull out into object with repo+branch?)
|
159
|
-
Used stored docker images for faster deployment
|
160
|
-
|
161
|
-
|
162
|
-
New Refactor (POODR)
|
163
|
-
|
164
|
-
Application-related models:
|
165
|
-
Application - All revisions of the app in abstract (a repo URL for now)
|
166
|
-
ApplicationVersion - Refers to a specific repo/branch/revision
|
167
|
-
ApplicationSource - Unpacked into a file system for reading/writing
|
168
|
-
|
169
|
-
UserPreferredPlatform - used by Command. Takes all user
|
170
|
-
configuration (command line switches, config file, etc) and produces
|
171
|
-
a Platform used to provision services.
|
172
|
-
|
173
|
-
InstanceFactory - takes a Platform and an ApplicationRevision to deploy on it.
|
174
|
-
queries [something] to ask which services the ApplicationRevision needs.
|
175
|
-
queries Instance to create it with the services
|
176
|
-
Instance - associates an ApplicationVersion with multiple Services that support it.
|
177
|
-
traverses the services to find certain kinds (web service, database)
|
178
|
-
|
179
|
-
|
180
|
-
Acceptance specs that drive Command and watch for specific output
|
181
|
-
Unit specs for Command that expect messages to collaborators
|
182
|
-
|
183
|
-
|
184
|
-
[binary]
|
185
|
-
constructs Command with a CommandResultView
|
186
|
-
|
187
|
-
Command
|
188
|
-
takes status_view (via constant)
|
189
|
-
sends output to status_view
|
190
|
-
|
191
|
-
StatusView
|
192
|
-
takes various *View classes for rendering different types
|
193
|
-
takes output_stream
|
194
|
-
sends output_stream and object for each object rendered
|
195
|
-
sends text output directly to output_stream
|
196
|
-
|
197
|
-
ApplicationView
|
198
|
-
takes output_stream and application
|
199
|
-
|
200
|
-
Cloud server infrastructure tips:
|
201
|
-
http://wblinks.com/notes/aws-tips-i-wish-id-known-before-i-started/
|