deployless 0.0.2 → 0.0.4

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: 0e90092e1f7b282631146db071f6f160f6710b9c9d5e0c0e91a2f4d8c213a2af
4
+ data.tar.gz: 43f10ccfb7c4c22c391a72006f4c7a034b43f0b1716a1c65afa064e72ae0d138
5
5
  SHA512:
6
- metadata.gz: b230388676174384f56d044272b83eaa32b0bd2600224a2997ea3d632aa2fcd7b2265dcfe6318682812772612a7aacc923a991f944646a2242cdaf2a3f60ff80
7
- data.tar.gz: e1d73bacec3fa78d4494a96a616f1dac3d8e84c663bf1b5926f5168a7a893109176b11cfa310a8451305dd2df24474318ad01963ceb9885355cf4494b7b14a31
6
+ metadata.gz: b630343cce61bb6a67f1429701e22fbaf92df7d73057f268a87eb9186189aabf77e2f1b5fbe00b6e11f9af2864e70cfa4a92e2e50b2992dafad8bfc6f33e8e1e
7
+ data.tar.gz: acfb13ca4f5040f3a44c776cd9370d42e995b156851230020d9810ae4f58e7eefb0e2c043a209c54b734466fd18f13b7b2a15a561b1eb1e04961a96db3a2398d
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,69 @@ 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
42
+
43
+ configuration[environment][:environment_variables] = {
44
+ secret_key_base: SecureRandom.hex(64),
45
+ rails_env: environment,
46
+ rake_env: environment,
47
+ rails_log_to_stdout: 'enabled',
48
+ rails_serve_static_files: 'enabled'
49
+ }
54
50
  end
55
51
 
56
- dokku.configure_domain
57
- dokku.configure_ssl
58
- dokku.print_instructions
52
+ TTY::File.create_file('.deployless.yml', configuration.to_yaml)
53
+ TTY::File.safe_append_to_file(".gitignore", ".deployless.yml")
54
+ when 'production', 'staging'
55
+ case command.params['task']
56
+ when 'console'
57
+ config = YAML.load_file('.deployless.yml')
58
+ raise ArgumentError, "Environment #{command.params['command']} is not configured" if config[command.params['command'].to_sym].nil?
59
+
60
+ provider = ::Deployless::Providers::DokkuProvider.new(
61
+ config: config,
62
+ environment: command.params['command']
63
+ )
64
+ provider.run_console
65
+ when 'prepare'
66
+ config = YAML.load_file('.deployless.yml')
67
+ raise ArgumentError, "Environment #{command.params['command']} is not configured" if config[command.params['command'].to_sym].nil?
68
+
69
+ provider = ::Deployless::Providers::DokkuProvider.new(
70
+ config: config,
71
+ environment: command.params['command']
72
+ )
73
+ provider.configure_environment
74
+ when 'update-env'
75
+ config = YAML.load_file('.deployless.yml')
76
+ raise ArgumentError, "Environment #{command.params['command']} is not configured" if config[command.params['command'].to_sym].nil?
77
+
78
+ provider = ::Deployless::Providers::DokkuProvider.new(
79
+ config: config,
80
+ environment: command.params['command']
81
+ )
82
+ provider.update_environment_variables
83
+ else
84
+ puts 'Unknown task'
85
+ end
59
86
  else
60
87
  puts 'Unknown command'
61
88
  end
@@ -0,0 +1,186 @@
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
+ configure
18
+ end
19
+
20
+ def run_console
21
+ server_ip = env_config.fetch(:server_ip)
22
+
23
+ puts "Connecting to #{@environment} rails console..."
24
+ system("ssh -t dokku@#{server_ip} enter #{app_name} web rails c")
25
+ end
26
+
27
+ def configure_environment
28
+ install
29
+ add_ssh_key
30
+ create_app
31
+ update_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
+ def update_environment_variables
51
+ environment_variables = env_config.fetch(:environment_variables)
52
+
53
+ app = app_name
54
+ on [env_config.fetch(:server_ip)] do |host|
55
+ execute :dokku, 'config:set', app, environment_variables.map { |key, value| "#{key.to_s.upcase}=#{value}" }.join(' ')
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def configure
62
+ SSHKit::Backend::Netssh.configure do |ssh|
63
+ ssh.connection_timeout = 30
64
+ ssh.ssh_options = {
65
+ user: env_config.fetch(:server_username),
66
+ keys: [env_config.fetch(:ssh_key_path)], # Fixed array syntax for keys
67
+ forward_agent: false,
68
+ auth_methods: %w(publickey password keyboard-interactive) # Added additional auth methods
69
+ }
70
+ end
71
+ end
72
+
73
+ def install
74
+ on [env_config.fetch(:server_ip)] do |host|
75
+ unless test "dokku"
76
+ execute :wget, '-NP', '.', 'https://dokku.com/bootstrap.sh'
77
+ execute :sudo, "DOKKU_TAG=#{VERSION}", 'bash', 'bootstrap.sh'
78
+ end
79
+ end
80
+ end
81
+
82
+ def add_ssh_key
83
+ public_key = File.read(File.expand_path(env_config.fetch(:ssh_key_path) + '.pub'))
84
+
85
+ on [env_config.fetch(:server_ip)] do |host|
86
+ unless test :dokku, 'ssh-keys:list', 'admin'
87
+ execute "echo '#{public_key}' | sudo dokku ssh-keys:add admin"
88
+ end
89
+ end
90
+ end
91
+
92
+ def create_app
93
+ app = app_name
94
+ on [env_config.fetch(:server_ip)] do |host|
95
+ if test :dokku, 'apps:exists', app
96
+ raise AppAlreadyExists, "App #{app} is already created"
97
+ else
98
+ execute :dokku, 'apps:create', app
99
+ end
100
+ end
101
+ end
102
+
103
+ def install_postgres
104
+ app = app_name
105
+ on [env_config.fetch(:server_ip)] do |host|
106
+ unless test :dokku, 'postgres'
107
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-postgres.git'
108
+ end
109
+
110
+ unless test :dokku, 'postgres:exists', "#{app}-db"
111
+ execute :dokku, 'postgres:create', "#{app}-db"
112
+ end
113
+
114
+ unless test :dokku, 'postgres:linked', "#{app}-db", app
115
+ execute :dokku, 'postgres:link', "#{app}-db", app
116
+ end
117
+ end
118
+ end
119
+
120
+ def install_redis
121
+ app = app_name
122
+ on [env_config.fetch(:server_ip)] do |host|
123
+ unless test :dokku, 'redis'
124
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-redis.git'
125
+ end
126
+
127
+ unless test :dokku, 'redis:exists', "#{app}-redis"
128
+ execute :dokku, 'redis:create', "#{app}-redis"
129
+ end
130
+
131
+ unless test :dokku, 'redis:linked', "#{app}-redis", app
132
+ execute :dokku, 'redis:link', "#{app}-redis", app
133
+ end
134
+ end
135
+ end
136
+
137
+ def configure_domain
138
+ domain = env_config.fetch(:domain)
139
+ app = app_name
140
+
141
+ on [env_config.fetch(:server_ip)] do |host|
142
+ unless test("dokku domains:report #{app} | grep #{domain}")
143
+ execute :dokku, 'domains:clear-global'
144
+ execute :dokku, 'domains:clear', app
145
+ execute :dokku, 'domains:add', app, domain
146
+ end
147
+ end
148
+ end
149
+
150
+ def configure_ssl
151
+ email = env_config.fetch(:email)
152
+ app = app_name
153
+
154
+ on [env_config.fetch(:server_ip)] do |host|
155
+ unless test :dokku, 'letsencrypt'
156
+ execute :sudo, 'dokku', 'plugin:install', 'https://github.com/dokku/dokku-letsencrypt.git'
157
+ end
158
+
159
+ unless test("dokku letsencrypt:list | grep #{app}")
160
+ execute :dokku, 'letsencrypt:set', app, 'email', email
161
+ execute :dokku, 'letsencrypt:enable', app
162
+ end
163
+ end
164
+ end
165
+
166
+ def print_instructions
167
+ puts "Configure deployment by adding git remote:"
168
+ puts "git remote add dokku dokku@#{env_config.fetch(:server_ip)}:#{app_name}"
169
+ puts "Then you can deploy by running:"
170
+ puts "git push dokku main"
171
+ end
172
+
173
+ def env_config
174
+ @config.fetch(@environment.to_sym)
175
+ end
176
+
177
+ def app_name
178
+ if @environment == 'production'
179
+ @config.fetch(:app_name)
180
+ else
181
+ "#{@config.fetch(:app_name)}-#{@environment}"
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
@@ -3,7 +3,8 @@ module Deployless
3
3
  module_function
4
4
 
5
5
  def to_s
6
- '0.0.2'
6
+ '0.0.4'
7
7
  end
8
8
  end
9
9
  end
10
+
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.4
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