deployless 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aab6d3d445d5d9e5cff066a80cbdfb755223a78213501c7c8d5298a6de4ca770
4
- data.tar.gz: c8cd0548721f23df5816c120d2c4aa5e9f7d04181efced5e2eb51fde483e5687
3
+ metadata.gz: bcace00a79090e96ceb2880e81bd88b47135f8bc24a7df05ade8c8d74c80eeff
4
+ data.tar.gz: b45efffec748c79fb102ca229eb920fccc0fa3acc1ef92f89a902d5ad16f43cc
5
5
  SHA512:
6
- metadata.gz: b230388676174384f56d044272b83eaa32b0bd2600224a2997ea3d632aa2fcd7b2265dcfe6318682812772612a7aacc923a991f944646a2242cdaf2a3f60ff80
7
- data.tar.gz: e1d73bacec3fa78d4494a96a616f1dac3d8e84c663bf1b5926f5168a7a893109176b11cfa310a8451305dd2df24474318ad01963ceb9885355cf4494b7b14a31
6
+ metadata.gz: 34f41ca5148c5e350a054900788f8ec2530bd1fdca6d8df4086d19b465e0d34d096d4c8ac07f1de06859d211baa0466640365d03bedbab7c3329ce80ebbb8b9f
7
+ data.tar.gz: 86fd43372c7603a8695dafa02545e435b5cc3396720998c2ecd90fe80bac8e9792aee6ce8fc063fa0751d8f7158a3ec1952328eaec10e2764eacc3d989204044
data/bin/dpls CHANGED
@@ -1,10 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'tty-option'
4
- require 'tty-prompt'
5
- require 'tty-file'
6
- require 'yaml'
7
-
8
3
  require_relative '../lib/deployless'
9
4
 
10
5
  class Command
@@ -13,6 +8,10 @@ class Command
13
8
  argument :command do
14
9
  desc "The command to run"
15
10
  end
11
+
12
+ argument :task do
13
+ desc "The task to run"
14
+ end
16
15
  end
17
16
 
18
17
  command = Command.new
@@ -21,41 +20,52 @@ command.parse(ARGV)
21
20
  case command.params['command']
22
21
  when 'init'
23
22
  prompt = TTY::Prompt.new
24
- result = prompt.collect do
23
+ configuration = prompt.collect do
25
24
  key(:deployment_setup).enum_select("Deployment setup:", ["Dokku"], required: true)
26
25
  key(:background_job_processor).enum_select("Background job processor:", ["None", "Sidekiq"], required: true)
27
- key(:production_server_ip).ask("Production server IP:", required: true)
28
- key(:production_server_username).ask("Production server username:", required: true, default: 'ubuntu')
29
- key(:ssh_key_path).ask("SSH key path:", required: true, default: '~/.ssh/id_rsa')
30
- key(:email).ask("Email:", required: true)
31
26
  key(:app_name).ask("Application name:", required: true)
32
- key(:domain).ask("Domain:", required: true)
27
+ key(:support_for_staging_environment).enum_select("Support for staging environment?:", ["Yes", "No"], required: true)
33
28
  end
34
29
 
35
- TTY::File.create_file('.deployless.yml', result.to_yaml)
36
- TTY::File.safe_append_to_file(".gitignore", ".deployless.yml")
37
- when 'prepare'
38
- prompt = TTY::Prompt.new
39
- config = YAML.load_file('.deployless.yml')
40
- dokku = ::Deployless::Dokku.new(config)
41
- dokku.configure
42
- dokku.install
43
- dokku.add_ssh_key
44
- dokku.create_app
45
- dokku.set_initial_environment_variables
46
- dokku.install_postgres
47
- result = "No"
48
-
49
- while result == "No"
50
- result = prompt.enum_select("Add DNS record for the domain #{config.fetch(:domain)} - type: A, value: #{config.fetch(:production_server_ip)}. Is it done?", ["Yes", "No"], required: true)
51
- if result == "No"
52
- puts "Please add DNS record for the domain #{config.fetch(:domain)} - type: A, value: #{config.fetch(:production_server_ip)} and confirm when done."
30
+ environments = %i[production]
31
+ environments << :staging if configuration.fetch(:support_for_staging_environment) == 'Yes'
32
+
33
+ environments.each do |environment|
34
+ puts "Configuring #{environment} environment"
35
+ configuration[environment] = prompt.collect do
36
+ key(:server_ip).ask("Server IP:", required: true)
37
+ key(:ssh_key_path).ask("SSH key path:", required: true, default: '~/.ssh/id_rsa')
38
+ key(:server_username).ask("Server username:", required: true, default: 'ubuntu')
39
+ key(:email).ask("Email:", required: true)
40
+ key(:domain).ask("Domain:", required: true)
53
41
  end
54
42
  end
55
43
 
56
- dokku.configure_domain
57
- dokku.configure_ssl
58
- dokku.print_instructions
44
+ TTY::File.create_file('.deployless.yml', configuration.to_yaml)
45
+ TTY::File.safe_append_to_file(".gitignore", ".deployless.yml")
46
+ when 'production', 'staging'
47
+ case command.params['task']
48
+ when 'console'
49
+ config = YAML.load_file('.deployless.yml')
50
+ raise ArgumentError, "Environment #{command.params['command']} is not configured" if config[command.params['command'].to_sym].nil?
51
+
52
+ provider = ::Deployless::Providers::DokkuProvider.new(
53
+ config: config,
54
+ environment: command.params['command']
55
+ )
56
+ provider.run_console
57
+ when 'prepare'
58
+ config = YAML.load_file('.deployless.yml')
59
+ raise ArgumentError, "Environment #{command.params['command']} is not configured" if config[command.params['command'].to_sym].nil?
60
+
61
+ provider = ::Deployless::Providers::DokkuProvider.new(
62
+ config: config,
63
+ environment: command.params['command']
64
+ )
65
+ provider.configure_environment
66
+ else
67
+ puts 'Unknown task'
68
+ end
59
69
  else
60
70
  puts 'Unknown command'
61
71
  end
@@ -0,0 +1,194 @@
1
+ require 'sshkit'
2
+ require 'sshkit/dsl'
3
+ require 'securerandom'
4
+
5
+ module Deployless
6
+ module Providers
7
+ class DokkuProvider
8
+ include SSHKit::DSL
9
+
10
+ AppAlreadyExists = Class.new(StandardError)
11
+
12
+ VERSION = '0.35.12'
13
+
14
+ def initialize(config:, environment:)
15
+ @config = config
16
+ @environment = environment
17
+ end
18
+
19
+ def run_console
20
+ server_ip = env_config.fetch(:server_ip)
21
+
22
+ puts "Connecting to #{@environment} rails console..."
23
+ system("ssh -t dokku@#{server_ip} enter #{app_name} web rails c")
24
+ end
25
+
26
+ def configure_environment
27
+ configure
28
+ install
29
+ add_ssh_key
30
+ create_app
31
+ set_initial_environment_variables
32
+ install_postgres
33
+ install_redis if @config.fetch(:background_job_processor) == 'Sidekiq'
34
+
35
+ result = "No"
36
+ prompt = TTY::Prompt.new
37
+
38
+ while result == "No"
39
+ result = prompt.enum_select("Add DNS record for the domain #{env_config.fetch(:domain)} - type: A, value: #{env_config.fetch(:server_ip)}. Is it done?", ["Yes", "No"], required: true)
40
+ if result == "No"
41
+ puts "Please add DNS record for the domain #{env_config.fetch(:domain)} - type: A, value: #{env_config.fetch(:server_ip)} and confirm when done."
42
+ end
43
+ end
44
+
45
+ configure_domain
46
+ configure_ssl
47
+ print_instructions
48
+ end
49
+
50
+ private
51
+
52
+ def configure
53
+ SSHKit::Backend::Netssh.configure do |ssh|
54
+ ssh.connection_timeout = 30
55
+ ssh.ssh_options = {
56
+ user: env_config.fetch(:server_username),
57
+ keys: %w(env_config.fetch(:ssh_key_path)),
58
+ forward_agent: false,
59
+ auth_methods: %w(publickey)
60
+ }
61
+ end
62
+ end
63
+
64
+ def install
65
+ on [env_config.fetch(:server_ip)] do |host|
66
+ unless test "dokku"
67
+ execute :wget, '-NP', '.', 'https://dokku.com/bootstrap.sh'
68
+ execute :sudo, "DOKKU_TAG=#{VERSION}", 'bash', 'bootstrap.sh'
69
+ end
70
+ end
71
+ end
72
+
73
+ def add_ssh_key
74
+ public_key = File.read(File.expand_path(env_config.fetch(:ssh_key_path) + '.pub'))
75
+
76
+ on [env_config.fetch(:server_ip)] do |host|
77
+ unless test :dokku, 'ssh-keys:list', 'admin'
78
+ execute "echo '#{public_key}' | sudo dokku ssh-keys:add admin"
79
+ end
80
+ end
81
+ end
82
+
83
+ def create_app
84
+ app = app_name
85
+ on [env_config.fetch(:server_ip)] do |host|
86
+ if test :dokku, 'apps:exists', app
87
+ raise AppAlreadyExists, "App #{app} is already created"
88
+ else
89
+ execute :dokku, 'apps:create', app
90
+ end
91
+ end
92
+ end
93
+
94
+ def set_initial_environment_variables
95
+ secret_key_base = SecureRandom.hex(64)
96
+
97
+ environment_variables = {
98
+ 'SECRET_KEY_BASE' => secret_key_base,
99
+ 'RAILS_ENV' => @environment,
100
+ 'RAKE_ENV' => @environment,
101
+ 'RAILS_LOG_TO_STDOUT' => 'enabled',
102
+ 'RAILS_SERVE_STATIC_FILES' => 'enabled'
103
+ }
104
+
105
+ app = app_name
106
+ on [env_config.fetch(:server_ip)] do |host|
107
+ execute :dokku, 'config:set', app, environment_variables.map { |key, value| "#{key}=#{value}" }.join(' ')
108
+ end
109
+ end
110
+
111
+ def install_postgres
112
+ app = app_name
113
+ on [env_config.fetch(:server_ip)] do |host|
114
+ unless test :dokku, 'postgres'
115
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-postgres.git'
116
+ end
117
+
118
+ unless test :dokku, 'postgres:exists', "#{app}-db"
119
+ execute :dokku, 'postgres:create', "#{app}-db"
120
+ end
121
+
122
+ unless test :dokku, 'postgres:linked', "#{app}-db", app
123
+ execute :dokku, 'postgres:link', "#{app}-db", app
124
+ end
125
+ end
126
+ end
127
+
128
+ def install_redis
129
+ app = app_name
130
+ on [env_config.fetch(:server_ip)] do |host|
131
+ unless test :dokku, 'redis'
132
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-redis.git'
133
+ end
134
+
135
+ unless test :dokku, 'redis:exists', "#{app}-redis"
136
+ execute :dokku, 'redis:create', "#{app}-redis"
137
+ end
138
+
139
+ unless test :dokku, 'redis:linked', "#{app}-redis", app
140
+ execute :dokku, 'redis:link', "#{app}-redis", app
141
+ end
142
+ end
143
+ end
144
+
145
+ def configure_domain
146
+ domain = env_config.fetch(:domain)
147
+ app = app_name
148
+
149
+ on [env_config.fetch(:server_ip)] do |host|
150
+ unless test("dokku domains:report #{app} | grep #{domain}")
151
+ execute :dokku, 'domains:clear-global'
152
+ execute :dokku, 'domains:clear', app
153
+ execute :dokku, 'domains:add', app, domain
154
+ end
155
+ end
156
+ end
157
+
158
+ def configure_ssl
159
+ email = env_config.fetch(:email)
160
+ app = app_name
161
+
162
+ on [env_config.fetch(:server_ip)] do |host|
163
+ unless test :dokku, 'letsencrypt'
164
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-letsencrypt.git'
165
+ end
166
+
167
+ unless test("dokku letsencrypt:list | grep #{app}")
168
+ execute :dokku, 'letsencrypt:set', app, 'email', email
169
+ execute :dokku, 'letsencrypt:enable', app
170
+ end
171
+ end
172
+ end
173
+
174
+ def print_instructions
175
+ puts "Configure deployment by adding git remote:"
176
+ puts "git remote add dokku dokku@#{env_config.fetch(:server_ip)}:#{app_name}"
177
+ puts "Then you can deploy by running:"
178
+ puts "git push dokku main"
179
+ end
180
+
181
+ def env_config
182
+ @config.fetch(@environment.to_sym)
183
+ end
184
+
185
+ def app_name
186
+ if @environment == 'production'
187
+ @config.fetch(:app_name)
188
+ else
189
+ "#{@config.fetch(:app_name)}-#{@environment}"
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
@@ -3,7 +3,7 @@ module Deployless
3
3
  module_function
4
4
 
5
5
  def to_s
6
- '0.0.2'
6
+ '0.0.3'
7
7
  end
8
8
  end
9
9
  end
data/lib/deployless.rb CHANGED
@@ -1 +1,6 @@
1
- require_relative 'deployless/dokku'
1
+ require 'tty-option'
2
+ require 'tty-prompt'
3
+ require 'tty-file'
4
+ require 'yaml'
5
+
6
+ require_relative 'deployless/providers/dokku_provider'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deployless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paweł Dąbrowski
@@ -109,7 +109,7 @@ extra_rdoc_files: []
109
109
  files:
110
110
  - bin/dpls
111
111
  - lib/deployless.rb
112
- - lib/deployless/dokku.rb
112
+ - lib/deployless/providers/dokku_provider.rb
113
113
  - lib/deployless/version.rb
114
114
  homepage: https://github.com/impactahead/deployless
115
115
  licenses:
@@ -1,104 +0,0 @@
1
- require 'sshkit'
2
- require 'sshkit/dsl'
3
- require 'securerandom'
4
-
5
- module Deployless
6
- class Dokku
7
- include SSHKit::DSL
8
-
9
- def initialize(config)
10
- @config = config
11
- end
12
-
13
- def configure
14
- SSHKit::Backend::Netssh.configure do |ssh|
15
- ssh.connection_timeout = 30
16
- ssh.ssh_options = {
17
- user: @config.fetch(:production_server_username),
18
- keys: %w(@config.fetch(:ssh_key_path)),
19
- forward_agent: false,
20
- auth_methods: %w(publickey)
21
- }
22
- end
23
- end
24
-
25
- def install
26
- on [@config.fetch(:production_server_ip)] do |host|
27
- execute :wget, '-NP', '.', 'https://dokku.com/bootstrap.sh'
28
- execute :sudo, 'DOKKU_TAG=v0.35.12', 'bash', 'bootstrap.sh'
29
- end
30
- end
31
-
32
- def add_ssh_key
33
- public_key = File.read(File.expand_path(@config.fetch(:ssh_key_path) + '.pub'))
34
-
35
- on [@config.fetch(:production_server_ip)] do |host|
36
- execute "echo '#{public_key}' | sudo dokku ssh-keys:add admin"
37
- end
38
- end
39
-
40
- def create_app
41
- app_name = @config.fetch(:app_name)
42
-
43
- on [@config.fetch(:production_server_ip)] do |host|
44
- execute :dokku, 'apps:create', app_name
45
- end
46
- end
47
-
48
- def set_initial_environment_variables
49
- app_name = @config.fetch(:app_name)
50
- secret_key_base = SecureRandom.hex(64)
51
-
52
- environment_variables = {
53
- 'SECRET_KEY_BASE' => secret_key_base,
54
- 'RAILS_ENV' => 'production',
55
- 'RAKE_ENV' => 'production',
56
- 'RAILS_LOG_TO_STDOUT' => 'enabled',
57
- 'RAILS_SERVE_STATIC_FILES' => 'enabled'
58
- }
59
-
60
- on [@config.fetch(:production_server_ip)] do |host|
61
- execute :dokku, 'config:set', app_name, environment_variables.map { |key, value| "#{key}=#{value}" }.join(' ')
62
- end
63
- end
64
-
65
- def install_postgres
66
- app_name = @config.fetch(:app_name)
67
-
68
- on [@config.fetch(:production_server_ip)] do |host|
69
- execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-postgres.git'
70
- execute :dokku, 'postgres:create', "#{app_name}-db"
71
- execute :dokku, 'postgres:link', "#{app_name}-db", app_name
72
- end
73
- end
74
-
75
- def configure_domain
76
- domain = @config.fetch(:domain)
77
- app_name = @config.fetch(:app_name)
78
-
79
- on [@config.fetch(:production_server_ip)] do |host|
80
- execute :dokku, 'domains:clear-global'
81
- execute :dokku, 'domains:clear', app_name
82
- execute :dokku, 'domains:add', app_name, domain
83
- end
84
- end
85
-
86
- def configure_ssl
87
- email = @config.fetch(:email)
88
- app_name = @config.fetch(:app_name)
89
-
90
- on [@config.fetch(:production_server_ip)] do |host|
91
- execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-letsencrypt.git'
92
- execute :dokku, 'letsencrypt:set', app_name, 'email', email
93
- execute :dokku, 'letsencrypt:enable', app_name
94
- end
95
- end
96
-
97
- def print_instructions
98
- puts "Configure deployment by adding git remote:"
99
- puts "git remote add dokku dokku@#{@config.fetch(:production_server_ip)}:#{@config.fetch(:app_name)}"
100
- puts "Then you can deploy by running:"
101
- puts "git push dokku main"
102
- end
103
- end
104
- end