capistrano-nuxt2 0.2.17
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +222 -0
- data/Rakefile +3 -0
- data/lib/capistrano/nuxt2/base_helpers.rb +120 -0
- data/lib/capistrano/nuxt2/certbot.rb +1 -0
- data/lib/capistrano/nuxt2/nginx.rb +1 -0
- data/lib/capistrano/nuxt2/nginx_helpers.rb +56 -0
- data/lib/capistrano/nuxt2/nuxt.rb +1 -0
- data/lib/capistrano/nuxt2/nuxt3.rb +1 -0
- data/lib/capistrano/nuxt2/proxy_nginx.rb +1 -0
- data/lib/capistrano/nuxt2/version.rb +5 -0
- data/lib/capistrano/nuxt2/vue.rb +1 -0
- data/lib/capistrano/nuxt2.rb +9 -0
- data/lib/capistrano/tasks/certbot.rake +256 -0
- data/lib/capistrano/tasks/nginx.rake +209 -0
- data/lib/capistrano/tasks/nuxt.rake +159 -0
- data/lib/capistrano/tasks/nuxt3.rake +332 -0
- data/lib/capistrano/tasks/proxy_nginx.rake +415 -0
- data/lib/capistrano/tasks/vue.rake +125 -0
- data/lib/generators/capistrano/nuxt2/templates/nginx/https_ssl_options.erb +29 -0
- data/lib/generators/capistrano/nuxt2/templates/nginx.conf.erb +176 -0
- data/lib/generators/capistrano/nuxt2/templates/nginx_app_conf.erb +46 -0
- data/lib/generators/capistrano/nuxt2/templates/nginx_proxy_conf.erb +137 -0
- data/lib/generators/capistrano/nuxt2/templates/nuxt3_ssr_service.erb +38 -0
- data/lib/tasks/capistrano/nuxt2_tasks.rake +4 -0
- metadata +124 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
namespace :load do
|
|
2
|
+
task :defaults do
|
|
3
|
+
set :certbot_roles, -> { :web }
|
|
4
|
+
set :certbot_path, -> { "~" }
|
|
5
|
+
set :certbot_domains, -> { fetch(:nginx_major_domain,false) ? [fetch(:nginx_major_domain)] + Array(fetch(:nginx_domains)) : Array(fetch(:nginx_domains)) }
|
|
6
|
+
set :certbot_www_domains, -> { false }
|
|
7
|
+
set :certbot_webroot, -> { "#{shared_path}" }
|
|
8
|
+
set :certbot_job_log, -> { "#{shared_path}/log/lets_encrypt_cron.log" }
|
|
9
|
+
set :certbot_job_type, -> { 'systemd' } # systemd / cron
|
|
10
|
+
set :certbot_email, -> { "" }
|
|
11
|
+
# set :certbot_dh_path, -> { fetch(:nginx_diffie_hellman_path, "/etc/ssl/certs/dhparam.pem")}
|
|
12
|
+
# set :certbot_dh_size, -> { 4096 }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
namespace :certbot do
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Helper method to get the email address
|
|
20
|
+
def fetch_certbot_email
|
|
21
|
+
certbot_email = fetch(:certbot_email, "").strip
|
|
22
|
+
if certbot_email.empty?
|
|
23
|
+
puts "⚠️ No email address is set for Let's Encrypt!"
|
|
24
|
+
puts "➡️ A valid email is required to receive expiration notifications."
|
|
25
|
+
puts "➡️ Please enter a valid email address:"
|
|
26
|
+
ask(:certbot_email, "Enter email for Let's Encrypt:")
|
|
27
|
+
set(:certbot_email, fetch(:certbot_email)) # Store response
|
|
28
|
+
end
|
|
29
|
+
fetch(:certbot_email)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Helper method to determine if `--expand` should be used
|
|
33
|
+
def fetch_certbot_expand_option
|
|
34
|
+
certbot_domains = Array(fetch(:certbot_domains))
|
|
35
|
+
use_www_domains = fetch(:certbot_www_domains, false)
|
|
36
|
+
|
|
37
|
+
should_expand = false
|
|
38
|
+
if use_www_domains || certbot_domains.length > 1
|
|
39
|
+
puts "🔍 It looks like you already have certificates or are adding new domains."
|
|
40
|
+
puts "➡️ If you want to expand an existing certificate with new domains, select 'yes'."
|
|
41
|
+
ask(:certbot_expand, "Use `--expand`? (yes/no):")
|
|
42
|
+
should_expand = fetch(:certbot_expand).downcase.strip == "yes"
|
|
43
|
+
end
|
|
44
|
+
should_expand ? "--expand" : ""
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Helper method to generate domain arguments
|
|
48
|
+
def fetch_certbot_domain_args
|
|
49
|
+
certbot_domains = Array(fetch(:certbot_domains))
|
|
50
|
+
use_www_domains = fetch(:certbot_www_domains, false)
|
|
51
|
+
|
|
52
|
+
certbot_domains.map do |d|
|
|
53
|
+
base_domain = d.gsub(/^\*?\./, "")
|
|
54
|
+
domain_entry = "-d #{base_domain}"
|
|
55
|
+
domain_entry += "-d www.#{base_domain}" if use_www_domains
|
|
56
|
+
domain_entry
|
|
57
|
+
end.join(" ")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
62
|
+
|
|
63
|
+
desc "Install certbot LetsEncrypt"
|
|
64
|
+
task :install do
|
|
65
|
+
on roles fetch(:certbot_roles) do
|
|
66
|
+
within fetch(:certbot_path) do
|
|
67
|
+
execute :sudo, "apt update"
|
|
68
|
+
execute :sudo, "apt install -y certbot"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
desc "Generate LetsEncrypt certificate"
|
|
75
|
+
task :generate do
|
|
76
|
+
on roles fetch(:certbot_roles) do
|
|
77
|
+
certbot_email = fetch_certbot_email
|
|
78
|
+
expand_option = fetch_certbot_expand_option
|
|
79
|
+
domain_args = fetch_certbot_domain_args
|
|
80
|
+
|
|
81
|
+
execute :sudo, "certbot --non-interactive --agree-tos --allow-subset-of-names --email #{certbot_email} certonly --webroot -w #{fetch(:certbot_webroot)} #{domain_args} #{expand_option}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
desc "Delete LetsEncrypt certificate"
|
|
87
|
+
task :delete do
|
|
88
|
+
on roles fetch(:certbot_roles) do
|
|
89
|
+
# 1️⃣ Email check with explanation
|
|
90
|
+
puts "⚠️ This will delete the certificates for the domain: #{Array(fetch(:certbot_domains))[0]}"
|
|
91
|
+
ask(:certbot_delete_cert, "Are you sure? (yes|no):")
|
|
92
|
+
if fetch(:certbot_delete_cert).to_s.downcase == "yes"
|
|
93
|
+
# Execute Certbot delete
|
|
94
|
+
puts "🔍 Deleting certificate... #{Array(fetch(:certbot_domains))[0]}"
|
|
95
|
+
execute :sudo, "certbot --non-interactive delete --cert-name #{ Array(fetch(:certbot_domains))[0] }"
|
|
96
|
+
else
|
|
97
|
+
puts "🔍 Skipping certificate deletion..."
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
desc "Upload and setup LetsEncrypt Auto-renew-job"
|
|
105
|
+
task :setup_auto_renew do
|
|
106
|
+
on roles fetch(:certbot_roles) do
|
|
107
|
+
if fetch(:certbot_job_type, 'systemd') == 'cron'
|
|
108
|
+
# just once a week
|
|
109
|
+
execute :sudo, "echo '0 0 * * 0 root certbot renew --no-self-upgrade --allow-subset-of-names --post-hook \"systemctl restart nginx\" >> #{ fetch(:certbot_job_log) } 2>&1' | cat > #{ fetch(:certbot_path) }/lets_encrypt_cronjob"
|
|
110
|
+
execute :sudo, "mv -f #{ fetch(:certbot_path) }/lets_encrypt_cronjob /etc/cron.d/lets_encrypt"
|
|
111
|
+
execute :sudo, "chown -f root:root /etc/cron.d/lets_encrypt"
|
|
112
|
+
execute :sudo, "chmod -f 0644 /etc/cron.d/lets_encrypt"
|
|
113
|
+
else
|
|
114
|
+
## enable systemd timer (every 12 hours)
|
|
115
|
+
execute :sudo, "systemctl enable certbot.timer"
|
|
116
|
+
execute :sudo, "systemctl start certbot.timer"
|
|
117
|
+
## restart nginx if renewed
|
|
118
|
+
execute :sudo, "mkdir -p /etc/systemd/system/certbot.service.d"
|
|
119
|
+
execute :sudo, "echo -e '[Service]\nExecStartPost=/bin/systemctl restart nginx' | sudo tee /etc/systemd/system/certbot.service.d/override.conf"
|
|
120
|
+
execute :sudo, "systemctl daemon-reload"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
desc "Show logs for LetsEncrypt Auto-renew-job"
|
|
126
|
+
task :auto_renew_logs do
|
|
127
|
+
on roles fetch(:certbot_roles) do
|
|
128
|
+
if fetch(:certbot_job_type, 'systemd') == 'cron'
|
|
129
|
+
execute :sudo, "tail -n 50 #{fetch(:certbot_job_log)}"
|
|
130
|
+
else
|
|
131
|
+
execute :sudo, "journalctl -u certbot.timer --no-pager --since '7 days ago'"
|
|
132
|
+
execute :sudo, "journalctl -u certbot.service --no-pager --since '7 days ago'"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
desc "Remove LetsEncrypt Auto-renew-job"
|
|
138
|
+
task :remove_auto_renew do
|
|
139
|
+
on roles fetch(:certbot_roles) do
|
|
140
|
+
if fetch(:certbot_job_type, 'systemd') == 'cron'
|
|
141
|
+
execute :sudo, "rm -f /etc/cron.d/lets_encrypt"
|
|
142
|
+
else
|
|
143
|
+
execute :sudo, "systemctl stop certbot.timer"
|
|
144
|
+
execute :sudo, "systemctl disable certbot.timer"
|
|
145
|
+
execute :sudo, "rm -rf /etc/systemd/system/certbot.service.d"
|
|
146
|
+
execute :sudo, "systemctl daemon-reload"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
desc "Dry-Run Renew LetsEncrypt"
|
|
153
|
+
task :dry_renew do
|
|
154
|
+
on roles fetch(:certbot_roles) do
|
|
155
|
+
# execute :sudo, "#{ fetch(:certbot_path) }/certbot-auto renew --dry-run"
|
|
156
|
+
output = capture(:sudo, "certbot renew --dry-run")
|
|
157
|
+
puts "#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#"
|
|
158
|
+
output.each_line do |line|
|
|
159
|
+
puts line
|
|
160
|
+
end
|
|
161
|
+
puts "#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
desc "Renew LetsEncrypt certificates"
|
|
167
|
+
task :renew do
|
|
168
|
+
on roles fetch(:certbot_roles) do
|
|
169
|
+
# execute :sudo, "#{ fetch(:certbot_path) }/certbot-auto renew --dry-run"
|
|
170
|
+
output = capture(:sudo, "certbot renew")
|
|
171
|
+
puts "#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#"
|
|
172
|
+
output.each_line do |line|
|
|
173
|
+
puts line
|
|
174
|
+
end
|
|
175
|
+
puts "#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# => ECDH (X25519) is automatically used → No need to generate DH params.
|
|
181
|
+
## desc "Generate Strong Diffie-Hellman Group"
|
|
182
|
+
## task :generate_dhparam do
|
|
183
|
+
## on roles fetch(:certbot_roles) do
|
|
184
|
+
## dh_path = fetch(:certbot_dh_path).to_s.split("/")
|
|
185
|
+
## dh_path.pop
|
|
186
|
+
## execute :sudo, "mkdir -p #{dh_path.join("/")}"
|
|
187
|
+
## # Set key size (default to 4096 if not specified)
|
|
188
|
+
## dh_key_size = fetch(:certbot_dh_size, 4096)
|
|
189
|
+
## # Check if DH params already exist
|
|
190
|
+
## if test("[ -f #{fetch(:certbot_dh_path)} ]")
|
|
191
|
+
## puts "✅ DH parameters already exist at #{fetch(:certbot_dh_path)}, skipping generation."
|
|
192
|
+
## else
|
|
193
|
+
## puts "🔐 Generating #{dh_key_size}-bit Diffie-Hellman parameters..."
|
|
194
|
+
## execute :sudo, "openssl dhparam -out #{fetch(:certbot_dh_path)} #{dh_key_size}"
|
|
195
|
+
## end
|
|
196
|
+
## end
|
|
197
|
+
## end
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
desc "Check if TLS 1.3 is correctly enabled on the server"
|
|
201
|
+
task :check_tls do
|
|
202
|
+
on roles fetch(:certbot_roles) do
|
|
203
|
+
domain = fetch(:nginx_major_domain, fetch(:nginx_domains).first)
|
|
204
|
+
|
|
205
|
+
puts "🔍 Checking TLS 1.3 for #{domain}..."
|
|
206
|
+
result = capture("curl -v --tlsv1.3 --tls-max 1.3 https://#{domain} 2>&1")
|
|
207
|
+
|
|
208
|
+
if result.include?("SSL connection using TLSv1.3")
|
|
209
|
+
puts "✅ TLS 1.3 is enabled and working for #{domain}!"
|
|
210
|
+
else
|
|
211
|
+
puts "❌ WARNING: TLS 1.3 may not be working! Check your Nginx SSL settings."
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
desc 'Get the DNS challenge txt-entry'
|
|
218
|
+
task :dns_challenge_get do
|
|
219
|
+
on roles fetch(:certbot_roles) do
|
|
220
|
+
within release_path do
|
|
221
|
+
|
|
222
|
+
certbot_email = fetch_certbot_email
|
|
223
|
+
expand_option = fetch_certbot_expand_option
|
|
224
|
+
domain_args = fetch_certbot_domain_args
|
|
225
|
+
user = fetch(:user, "deploy") # Adjust to your user
|
|
226
|
+
|
|
227
|
+
puts "cmd: sudo certbot certonly --manual --preferred-challenges=dns --agree-tos --dry-run --email #{certbot_email} #{domain_args} #{expand_option}"
|
|
228
|
+
|
|
229
|
+
puts "🔄 Starting interactive Certbot session..."
|
|
230
|
+
system("ssh -t #{user}@#{host.hostname} 'sudo certbot certonly --manual --preferred-challenges=dns --agree-tos --dry-run --email #{certbot_email} #{domain_args} #{expand_option}'")
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
desc 'Run Certbot to validate the DNS challenge'
|
|
236
|
+
task :dns_challenge_validate do
|
|
237
|
+
on roles fetch(:certbot_roles) do
|
|
238
|
+
within release_path do
|
|
239
|
+
certbot_email = fetch_certbot_email
|
|
240
|
+
expand_option = fetch_certbot_expand_option
|
|
241
|
+
domain_args = fetch_certbot_domain_args
|
|
242
|
+
user = fetch(:user, "deploy") # Adjust to your user
|
|
243
|
+
|
|
244
|
+
puts "cmd: sudo certbot certonly --manual --preferred-challenges=dns --agree-tos --email #{certbot_email} #{domain_args} #{expand_option}"
|
|
245
|
+
|
|
246
|
+
puts "🔄 Starting interactive Certbot session..."
|
|
247
|
+
system("ssh -t #{user}@#{host.hostname} 'sudo certbot certonly --manual --preferred-challenges=dns --agree-tos --email #{certbot_email} #{domain_args} #{expand_option}'")
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
require 'capistrano/nuxt2/base_helpers'
|
|
2
|
+
require 'capistrano/nuxt2/nginx_helpers'
|
|
3
|
+
include Capistrano::Nuxt2::BaseHelpers
|
|
4
|
+
include Capistrano::Nuxt2::NginxHelpers
|
|
5
|
+
|
|
6
|
+
namespace :load do
|
|
7
|
+
task :defaults do
|
|
8
|
+
set :nginx_domains, -> { [] }
|
|
9
|
+
set :nginx_major_domain, -> { false }
|
|
10
|
+
set :nginx_remove_www, -> { true }
|
|
11
|
+
set :nginx_use_ssl, -> { false }
|
|
12
|
+
|
|
13
|
+
# also allow http access, if ssl is enabled (full http block will be created, but only if this is set to true)
|
|
14
|
+
set :nginx_also_allow_http, -> { false }
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
set :nginx_roles, -> { :web }
|
|
18
|
+
set :nginx_log_folder, -> { "log" }
|
|
19
|
+
set :nginx_root_folder, -> { "www" } # Nuxt default: "dist"
|
|
20
|
+
set :nginx_template, -> { :default }
|
|
21
|
+
|
|
22
|
+
# Define Nginx Site Name
|
|
23
|
+
set :nginx_site_name, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
|
|
24
|
+
set :nginx_app_fallback_site, -> { "404.html" } # Fallback: Nuxt.js default "404.html" page .. Vue default is "index.html"
|
|
25
|
+
|
|
26
|
+
# SSL Paths
|
|
27
|
+
set :nginx_ssl_cert, -> { "/etc/letsencrypt/live/#{ cert_domain }/fullchain.pem" }
|
|
28
|
+
set :nginx_ssl_key, -> { "/etc/letsencrypt/live/#{ cert_domain }/privkey.pem" }
|
|
29
|
+
set :nginx_ocsp_stapling, -> { false } # let's encrypt does not support stapling since 2025
|
|
30
|
+
|
|
31
|
+
# SSL Paths for old domain certificates, if major domain is set
|
|
32
|
+
set :nginx_other_ssl_cert, -> { "/etc/letsencrypt/live/#{ cert_domain }/fullchain.pem" }
|
|
33
|
+
set :nginx_other_ssl_key, -> { "/etc/letsencrypt/live/#{ cert_domain }/privkey.pem" }
|
|
34
|
+
|
|
35
|
+
set :nginx_hooks, -> { true }
|
|
36
|
+
set :allow_well_known, -> { true }
|
|
37
|
+
|
|
38
|
+
# SSL strict security settings
|
|
39
|
+
set :nginx_strict_security, -> { fetch(:nginx_use_ssl, false) }
|
|
40
|
+
|
|
41
|
+
# SSL Cipher Suite
|
|
42
|
+
set :nginx_ssl_ciphers, -> {
|
|
43
|
+
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" \
|
|
44
|
+
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:" \
|
|
45
|
+
"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:" \
|
|
46
|
+
"ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
append :linked_dirs, fetch(:nginx_root_folder), fetch(:nginx_log_folder)
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
namespace :nginx do
|
|
55
|
+
|
|
56
|
+
namespace :site do
|
|
57
|
+
desc "Upload Nginx site configuration"
|
|
58
|
+
task :upload do
|
|
59
|
+
on release_roles fetch(:nginx_roles) do
|
|
60
|
+
config_file = fetch(:nginx_template)
|
|
61
|
+
target_config = fetch(:nginx_site_name)
|
|
62
|
+
|
|
63
|
+
puts "📤 Uploading Nginx config: #{target_config}..."
|
|
64
|
+
|
|
65
|
+
if config_file == :default
|
|
66
|
+
template2go("nginx.conf", "/tmp/#{target_config}")
|
|
67
|
+
else
|
|
68
|
+
template2go(config_file, "/tmp/#{target_config}")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
execute :sudo, :mv, "/tmp/#{target_config}", "/etc/nginx/sites-available/#{target_config}"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
desc "Enable Nginx site (creates symlink)"
|
|
76
|
+
task :enable do
|
|
77
|
+
on release_roles fetch(:nginx_roles) do
|
|
78
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_site_name)}"
|
|
79
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_site_name)}"
|
|
80
|
+
|
|
81
|
+
unless test "[ -h #{enabled_path} ]"
|
|
82
|
+
puts "🔗 Enabling Nginx site..."
|
|
83
|
+
execute :sudo, :ln, "-s", available_path, enabled_path
|
|
84
|
+
invoke "nginx:service:reload"
|
|
85
|
+
else
|
|
86
|
+
puts "✅ Nginx site is already enabled!"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
desc "Disable Nginx site (removes symlink)"
|
|
92
|
+
task :disable do
|
|
93
|
+
on release_roles fetch(:nginx_roles) do
|
|
94
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_site_name)}"
|
|
95
|
+
|
|
96
|
+
if test "[ -h #{enabled_path} ]"
|
|
97
|
+
puts "🚫 Disabling Nginx site..."
|
|
98
|
+
execute :sudo, :rm, "-f", enabled_path
|
|
99
|
+
invoke "nginx:service:reload"
|
|
100
|
+
else
|
|
101
|
+
puts "⚠️ Nginx site is not enabled!"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
desc "Remove Nginx site configuration"
|
|
107
|
+
task :remove do
|
|
108
|
+
on release_roles fetch(:nginx_roles) do
|
|
109
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_site_name)}"
|
|
110
|
+
|
|
111
|
+
if test "[ -f #{available_path} ]"
|
|
112
|
+
puts "🗑 Removing Nginx site configuration..."
|
|
113
|
+
execute :sudo, :rm, "-f", available_path
|
|
114
|
+
else
|
|
115
|
+
puts "⚠️ Nginx site configuration does not exist!"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## Initiate Task, no desc .. so not in cap -T list
|
|
122
|
+
task :prepare do
|
|
123
|
+
on roles fetch(:nginx_roles) do
|
|
124
|
+
puts "⚙️ Ensuring Nginx directories exist..."
|
|
125
|
+
execute :sudo, "mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled"
|
|
126
|
+
invoke "nginx:site:upload"
|
|
127
|
+
puts "✅ Nginx setup completed! Enable it when ready with `cap nginx:site:enable`"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
namespace :service do
|
|
134
|
+
|
|
135
|
+
%w[start stop restart reload].each do |command|
|
|
136
|
+
desc "#{command.capitalize} nginx service"
|
|
137
|
+
task command do
|
|
138
|
+
on release_roles fetch(:nginx_roles) do
|
|
139
|
+
puts "🔄 Running: systemctl #{command} nginx..."
|
|
140
|
+
execute :sudo, "systemctl #{command} nginx"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
desc "Check nginx configuration"
|
|
146
|
+
task :check_config do
|
|
147
|
+
on release_roles fetch(:nginx_roles) do
|
|
148
|
+
puts "🧐 Checking nginx configuration..."
|
|
149
|
+
execute :sudo, "nginx -t"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
desc "Check nginx status"
|
|
154
|
+
task :check_status do
|
|
155
|
+
on release_roles fetch(:nginx_roles) do
|
|
156
|
+
puts "🔍 Checking nginx status..."
|
|
157
|
+
execute :sudo, "systemctl status nginx --no-pager"
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
desc "Update Apps Nginx (Upload, Enable if needed, Restart)"
|
|
165
|
+
task :update do
|
|
166
|
+
on release_roles fetch(:nginx_roles) do
|
|
167
|
+
puts "🔄 Reconfiguring Nginx..."
|
|
168
|
+
invoke "nginx:site:upload"
|
|
169
|
+
|
|
170
|
+
unless test "[ -h /etc/nginx/sites-enabled/#{fetch(:nginx_site_name)} ]"
|
|
171
|
+
invoke "nginx:site:enable"
|
|
172
|
+
else
|
|
173
|
+
puts "🔗 Site already enabled, skipping enable step!"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
invoke "nginx:service:restart"
|
|
177
|
+
puts "✅ Nginx reconfiguration complete!"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
desc "Fix Nginx folder rights .. if permission problem occurs"
|
|
183
|
+
task :fix_folder_rights do
|
|
184
|
+
on release_roles fetch(:nginx_roles) do
|
|
185
|
+
execute :sudo, "chmod o+x /home/#{fetch(:user)}"
|
|
186
|
+
execute :sudo, "chmod o+x #{fetch(:deploy_to)}"
|
|
187
|
+
execute :sudo, "chmod o+x #{current_path}"
|
|
188
|
+
execute :sudo, "chmod o+x #{shared_path}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
### Add nginx setup to the main setup task
|
|
197
|
+
task :setup do
|
|
198
|
+
invoke 'nginx:site:prepare'
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
namespace :deploy do
|
|
204
|
+
after 'deploy:finishing', :restart_nginx_app do
|
|
205
|
+
if fetch(:nginx_hooks)
|
|
206
|
+
invoke "nginx:update"
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require 'capistrano/nuxt2/base_helpers'
|
|
2
|
+
include Capistrano::Nuxt2::BaseHelpers
|
|
3
|
+
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
|
|
7
|
+
set :nuxt_stat_file, -> { "_builded_app" }
|
|
8
|
+
set :nuxt_logs_file, -> { "_builded_logs" }
|
|
9
|
+
set :nuxt_done_file, -> { "_builded_frontend" }
|
|
10
|
+
|
|
11
|
+
set :nuxt_use_nvm, -> { false }
|
|
12
|
+
set :nuxt_nvm_path, -> { "~/.nvm" }
|
|
13
|
+
set :nuxt_nvm_version, -> { "18.19.0" }
|
|
14
|
+
set :nuxt_nvm_script, -> { "$HOME/.nvm/nvm.sh" }
|
|
15
|
+
|
|
16
|
+
set :nuxt_app_roles, -> { :app }
|
|
17
|
+
|
|
18
|
+
## Maybe nonsense .. builds `APP_NAME_STG_DEPLOY_MODE`
|
|
19
|
+
set :nuxt_stage_env_var, -> { build_deploy_env_var }
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
append :linked_files, fetch(:nuxt_stat_file), fetch(:nuxt_logs_file), fetch(:nuxt_done_file)
|
|
23
|
+
append :linked_dirs, 'node_modules' # , '.nuxt', 'dist'
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
namespace :nuxt do
|
|
30
|
+
|
|
31
|
+
desc "output env var and stage"
|
|
32
|
+
task :output_env do
|
|
33
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
34
|
+
puts "🔧 Nuxt.js stage: #{fetch(:stage)}"
|
|
35
|
+
puts "🔧 Nuxt.js deploy mode: #{fetch(:nuxt_stage_env_var)}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
desc "Install dependencies"
|
|
40
|
+
task :install_dependencies do
|
|
41
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
42
|
+
within release_path do
|
|
43
|
+
execute :echo, "'installing|deploy' > #{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
44
|
+
execute :rm, "-rf node_modules/*"
|
|
45
|
+
execute :rm, "-rf #{shared_path}/node_modules/*"
|
|
46
|
+
if fetch(:nuxt_use_nvm, false)
|
|
47
|
+
env_vars = fetch(:default_env).map { |k, v| "#{k}=#{v}" }.join(" ")
|
|
48
|
+
nvm_prefix = "source #{fetch(:nuxt_nvm_script)} && nvm use #{fetch(:nuxt_nvm_version)}"
|
|
49
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && env #{env_vars} npm install')
|
|
50
|
+
else
|
|
51
|
+
execute :npm, "install"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
desc "Build Nuxt.js app"
|
|
59
|
+
task :build do
|
|
60
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
61
|
+
within release_path do
|
|
62
|
+
execute :echo, "'building|deploy' > #{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
63
|
+
if fetch(:nuxt_use_nvm, false)
|
|
64
|
+
env_vars = fetch(:default_env).map { |k, v| "#{k}=#{v}" }.join(" ")
|
|
65
|
+
nvm_prefix = "source #{fetch(:nuxt_nvm_script)} && nvm use #{fetch(:nuxt_nvm_version)}"
|
|
66
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && env #{env_vars} ./node_modules/.bin/nuxt build')
|
|
67
|
+
else
|
|
68
|
+
execute :npm, "run build"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
desc "Export static files (if needed)"
|
|
76
|
+
task :export do
|
|
77
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
78
|
+
within release_path do
|
|
79
|
+
execute :echo, "'generating|deploy' > #{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
80
|
+
execute :echo, "'Deploy - Render - LOGS :: #{ Time.now.strftime("%d.%m.%Y - %H:%M") } ::' > #{shared_path}/#{fetch(:nuxt_logs_file)}"
|
|
81
|
+
if fetch(:nuxt_use_nvm, false)
|
|
82
|
+
env_vars = fetch(:default_env).map { |k, v| "#{k}=#{v}" }.join(" ")
|
|
83
|
+
nvm_prefix = "source #{fetch(:nuxt_nvm_script)} && nvm use #{fetch(:nuxt_nvm_version)}"
|
|
84
|
+
|
|
85
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && env #{env_vars} ./node_modules/.bin/nuxt generate')
|
|
86
|
+
else
|
|
87
|
+
execute :npm, "run generate 2>&1 | tee -a #{shared_path}/#{fetch(:nuxt_logs_file)}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
desc "Sync the dist folder to the shared folder"
|
|
94
|
+
task :sync_dist do
|
|
95
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
96
|
+
execute :echo, "'syncing|deploy' > #{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
97
|
+
execute :rsync, "-a --delete #{release_path}/dist/ #{shared_path}/www/"
|
|
98
|
+
execute :echo, "'success|deploy' > #{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
99
|
+
execute :touch, "#{shared_path}/#{fetch(:nuxt_done_file)}"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
desc "Fix permissions (just in case)"
|
|
105
|
+
task :fix_permissions do
|
|
106
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
107
|
+
execute :sudo, :chown, "-R #{fetch(:user)}:#{fetch(:user)} #{release_path}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
desc "Setup defaults for Nuxt.js app"
|
|
113
|
+
task :setup_app do
|
|
114
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
115
|
+
ensure_shared_www_path
|
|
116
|
+
ensure_shared_log_path
|
|
117
|
+
execute :touch, "#{shared_path}/#{fetch(:nuxt_stat_file)}"
|
|
118
|
+
execute :touch, "#{shared_path}/#{fetch(:nuxt_logs_file)}"
|
|
119
|
+
execute :touch, "#{shared_path}/#{fetch(:nuxt_done_file)}"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
desc "Regenerate Nuxt.js app"
|
|
125
|
+
task :rebuild_app do
|
|
126
|
+
invoke "nuxt:install_dependencies"
|
|
127
|
+
invoke "nuxt:build"
|
|
128
|
+
invoke "nuxt:export"
|
|
129
|
+
invoke "nuxt:sync_dist"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
desc "Regenerate Nuxt.js app"
|
|
133
|
+
task :regenerate_app do
|
|
134
|
+
invoke "nuxt:export"
|
|
135
|
+
invoke "nuxt:sync_dist"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
desc "Install required node version with nvm"
|
|
139
|
+
task :install_nvm_node do
|
|
140
|
+
on roles(fetch(:nuxt_app_roles)) do
|
|
141
|
+
if fetch(:nuxt_use_nvm, false)
|
|
142
|
+
execute %(bash -lc 'source #{fetch(:nuxt_nvm_script)} && nvm install #{fetch(:nuxt_nvm_version)}')
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
namespace :deploy do
|
|
150
|
+
after 'deploy:published', :rebuild_nuxt_app do
|
|
151
|
+
invoke "nuxt:rebuild_app"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
desc 'Server setup tasks'
|
|
157
|
+
task :setup do
|
|
158
|
+
invoke 'nuxt:setup_app'
|
|
159
|
+
end
|