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 +4 -4
- data/bin/dpls +42 -32
- data/lib/deployless/providers/dokku_provider.rb +194 -0
- data/lib/deployless/version.rb +1 -1
- data/lib/deployless.rb +6 -1
- metadata +2 -2
- data/lib/deployless/dokku.rb +0 -104
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcace00a79090e96ceb2880e81bd88b47135f8bc24a7df05ade8c8d74c80eeff
|
4
|
+
data.tar.gz: b45efffec748c79fb102ca229eb920fccc0fa3acc1ef92f89a902d5ad16f43cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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(:
|
27
|
+
key(:support_for_staging_environment).enum_select("Support for staging environment?:", ["Yes", "No"], required: true)
|
33
28
|
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
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
|
data/lib/deployless/version.rb
CHANGED
data/lib/deployless.rb
CHANGED
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.
|
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/
|
112
|
+
- lib/deployless/providers/dokku_provider.rb
|
113
113
|
- lib/deployless/version.rb
|
114
114
|
homepage: https://github.com/impactahead/deployless
|
115
115
|
licenses:
|
data/lib/deployless/dokku.rb
DELETED
@@ -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
|