deployless 0.0.2 → 0.0.3

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 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