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,415 @@
|
|
|
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
|
+
# === GENERAL NGINX SETTINGS (can be overridden or used by both) ===
|
|
9
|
+
set :nginx_user, -> { 'www-data' } # User Nginx runs as (Debian/Ubuntu)
|
|
10
|
+
set :nginx_group, -> { 'www-data' } # Group Nginx runs as (Debian/Ubuntu)
|
|
11
|
+
|
|
12
|
+
# === PROXY NGINX SETTINGS ===
|
|
13
|
+
set :nginx_proxy_roles, -> { :proxy }
|
|
14
|
+
# Pfad relativ zur Rake-Datei (tasks/nginx.rake -> ../templates/)
|
|
15
|
+
set :nginx_proxy_template, -> { :default }
|
|
16
|
+
set :nginx_proxy_site_name, -> { "#{fetch(:application)}_#{fetch(:stage)}_proxy" }
|
|
17
|
+
|
|
18
|
+
# Domains and SSL settings are primarily for the proxy
|
|
19
|
+
set :nginx_domains, -> { [] }
|
|
20
|
+
set :nginx_major_domain, -> { false }
|
|
21
|
+
set :nginx_remove_www, -> { true }
|
|
22
|
+
set :nginx_use_ssl, -> { false } # Proxy handles SSL termination
|
|
23
|
+
|
|
24
|
+
set :nginx_ssl_cert, -> { "/etc/letsencrypt/live/#{ cert_domain }/fullchain.pem" }
|
|
25
|
+
set :nginx_ssl_key, -> { "/etc/letsencrypt/live/#{ cert_domain }/privkey.pem" }
|
|
26
|
+
set :nginx_ocsp_stapling, -> { false } # let's encrypt does not support stapling since 2025
|
|
27
|
+
# For old domain certs if major_domain is set
|
|
28
|
+
set :nginx_other_ssl_cert, -> { "/etc/letsencrypt/live/#{ cert_domain }/fullchain.pem" }
|
|
29
|
+
set :nginx_other_ssl_key, -> { "/etc/letsencrypt/live/#{ cert_domain }/privkey.pem" }
|
|
30
|
+
|
|
31
|
+
set :nginx_strict_security, -> { fetch(:nginx_use_ssl, false) } # For HSTS header
|
|
32
|
+
set :nginx_ssl_ciphers, -> {
|
|
33
|
+
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" \
|
|
34
|
+
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:" \
|
|
35
|
+
"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:" \
|
|
36
|
+
"ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305"
|
|
37
|
+
}
|
|
38
|
+
set :allow_well_known_proxy, -> { true } # For Certbot on proxy
|
|
39
|
+
set :nginx_proxy_well_known_root, -> { "/var/www/html" } # Standard path for Certbot webroot on proxy
|
|
40
|
+
|
|
41
|
+
set :nginx_proxy_log_folder, -> { "/var/log/nginx" } # Standard Nginx log folder for proxy
|
|
42
|
+
set :nginx_proxy_hooks, -> { true }
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Upstream App Server (where the App-Nginx runs)
|
|
46
|
+
# WICHTIG: Diese in config/deploy/<stage>.rb setzen!
|
|
47
|
+
# z.B. set :nginx_upstream_host, '10.0.0.5'
|
|
48
|
+
# set :nginx_upstream_port, 8080
|
|
49
|
+
# set :nginx_upstream_host, -> { nil }
|
|
50
|
+
# set :nginx_upstream_port, -> { 3500 } # Port App-Nginx is exposed on (e.g. Docker mapped port or direct)
|
|
51
|
+
## new style: Use these variables to define the upstream app server, falling back to old style if not set
|
|
52
|
+
set :nginx_upstream_host, -> { fetch(:nginx_upstream_app_host, nil) }
|
|
53
|
+
set :nginx_upstream_port, -> { fetch(:nginx_upstream_app_port, 3500) } # Port App-Nginx is exposed on (e.g. Docker mapped port or direct)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# === APP NGINX SETTINGS ===
|
|
58
|
+
set :nginx_app_roles, -> { :app }
|
|
59
|
+
set :nginx_app_template, -> { :default }
|
|
60
|
+
set :nginx_app_site_name, -> { "#{fetch(:application)}_#{fetch(:stage)}_app" }
|
|
61
|
+
set :nginx_app_fallback_site, -> { "404.html" } # Fallback: Nuxt.js default "404.html" page .. Vue default is "index.html"
|
|
62
|
+
|
|
63
|
+
# App specific paths (relative to shared_path for linked_dirs)
|
|
64
|
+
set :nginx_root_folder, -> { "#{shared_path}/www" } # JS app static files (Nuxt default: "dist")
|
|
65
|
+
set :nginx_log_folder, -> { "log" } # App Nginx logs
|
|
66
|
+
|
|
67
|
+
# This is from your original setup, relevant for the app server.
|
|
68
|
+
# append :linked_dirs, fetch(:nginx_root_folder), fetch(:nginx_log_folder)
|
|
69
|
+
|
|
70
|
+
set :nginx_app_hooks, -> { true }
|
|
71
|
+
set :allow_well_known_app, -> { false } # Usually handled by proxy
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
namespace :nginx do
|
|
76
|
+
|
|
77
|
+
# --- PROXY NGINX TASKS ---
|
|
78
|
+
namespace :proxy do
|
|
79
|
+
# Helper task to ensure upstream variables are set for the proxy
|
|
80
|
+
task :ensure_upstream_vars_set do
|
|
81
|
+
unless fetch(:nginx_upstream_host)
|
|
82
|
+
error "FEHLER: Bitte `:nginx_upstream_host` in deiner Stage-Konfiguration setzen (z.B. config/deploy/#{fetch(:stage)}.rb)."
|
|
83
|
+
info "Beispiel: set :nginx_upstream_host, 'interne.ip.des.app.servers'"
|
|
84
|
+
info " set :nginx_upstream_port, 8080"
|
|
85
|
+
exit 1
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
namespace :site do
|
|
90
|
+
desc "Upload Proxy Nginx site configuration"
|
|
91
|
+
task :upload do
|
|
92
|
+
invoke "nginx:proxy:ensure_upstream_vars_set"
|
|
93
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
94
|
+
config_file = fetch(:nginx_proxy_template)
|
|
95
|
+
target_config = fetch(:nginx_proxy_site_name)
|
|
96
|
+
|
|
97
|
+
puts "📤 [PROXY] Uploading Nginx config: #{target_config} from #{config_file}"
|
|
98
|
+
if config_file == :default
|
|
99
|
+
puts "📤 [PROXY] Using default template"
|
|
100
|
+
template2go("nginx_proxy_conf", "/tmp/#{target_config}")
|
|
101
|
+
else
|
|
102
|
+
puts "📤 [PROXY] Using custom template #{config_file}"
|
|
103
|
+
template2go(config_file, "/tmp/#{target_config}")
|
|
104
|
+
end
|
|
105
|
+
execute :sudo, :mv, "/tmp/#{target_config}", "/etc/nginx/sites-available/#{target_config}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
desc "Enable Proxy Nginx site"
|
|
110
|
+
task :enable do
|
|
111
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
112
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_proxy_site_name)}"
|
|
113
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_proxy_site_name)}"
|
|
114
|
+
unless test "[ -h #{enabled_path} ]"
|
|
115
|
+
puts "🔗 [PROXY] Enabling Nginx site..."
|
|
116
|
+
execute :sudo, :ln, "-s", available_path, enabled_path
|
|
117
|
+
invoke "nginx:proxy:service:reload"
|
|
118
|
+
else
|
|
119
|
+
puts "✅ [PROXY] Nginx site is already enabled!"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
desc "Disable Proxy Nginx site"
|
|
125
|
+
task :disable do
|
|
126
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
127
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_proxy_site_name)}"
|
|
128
|
+
if test "[ -h #{enabled_path} ]"
|
|
129
|
+
puts "🚫 [PROXY] Disabling Nginx site..."
|
|
130
|
+
execute :sudo, :rm, "-f", enabled_path
|
|
131
|
+
invoke "nginx:proxy:service:reload"
|
|
132
|
+
else
|
|
133
|
+
puts "⚠️ [PROXY] Nginx site is not enabled!"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
desc "Remove Proxy Nginx site configuration"
|
|
139
|
+
task :remove do
|
|
140
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
141
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_proxy_site_name)}"
|
|
142
|
+
if test "[ -f #{available_path} ]"
|
|
143
|
+
puts "🗑 [PROXY] Removing Nginx site configuration..."
|
|
144
|
+
execute :sudo, :rm, "-f", available_path
|
|
145
|
+
else
|
|
146
|
+
puts "⚠️ [PROXY] Nginx site configuration does not exist!"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
task :prepare do
|
|
152
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
153
|
+
puts "⚙️ [PROXY] Ensuring Nginx directories exist..."
|
|
154
|
+
execute :sudo, "mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled"
|
|
155
|
+
if fetch(:allow_well_known_proxy)
|
|
156
|
+
execute :sudo, "mkdir -p #{fetch(:nginx_proxy_well_known_root)}"
|
|
157
|
+
# Optional: set owner for nginx_proxy_well_known_root if certbot runs as different user
|
|
158
|
+
# execute :sudo, "chown #{fetch(:nginx_user)}:#{fetch(:nginx_group)} #{fetch(:nginx_proxy_well_known_root)}"
|
|
159
|
+
end
|
|
160
|
+
invoke "nginx:proxy:site:upload"
|
|
161
|
+
puts "✅ [PROXY] Nginx setup completed! Enable with `cap #{fetch(:stage)} nginx:proxy:site:enable`"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end # end site
|
|
165
|
+
|
|
166
|
+
namespace :service do
|
|
167
|
+
%w[start stop restart reload].each do |command|
|
|
168
|
+
desc "#{command.capitalize} Proxy Nginx service"
|
|
169
|
+
task command do
|
|
170
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
171
|
+
puts "🔄 [PROXY] Running: systemctl #{command} nginx..."
|
|
172
|
+
execute :sudo, "systemctl #{command} nginx"
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
desc "Check Proxy Nginx configuration"
|
|
177
|
+
task :check_config do
|
|
178
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
179
|
+
puts "🧐 [PROXY] Checking nginx configuration..."
|
|
180
|
+
execute :sudo, "nginx -t"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
desc "Check Proxy Nginx status"
|
|
184
|
+
task :check_status do
|
|
185
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
186
|
+
puts "🔍 [PROXY] Checking nginx status..."
|
|
187
|
+
execute :sudo, "systemctl status nginx --no-pager"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end # end service
|
|
191
|
+
|
|
192
|
+
desc "Update Proxy Nginx (Upload, Enable if needed, Reload/Restart)"
|
|
193
|
+
task :update do
|
|
194
|
+
on roles fetch(:nginx_proxy_roles) do
|
|
195
|
+
puts "🔄 [PROXY] Reconfiguring Nginx..."
|
|
196
|
+
invoke "nginx:proxy:site:upload"
|
|
197
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_proxy_site_name)}"
|
|
198
|
+
if test "[ -h #{enabled_path} ]"
|
|
199
|
+
puts "🔗 [PROXY] Site already enabled, reloading."
|
|
200
|
+
else
|
|
201
|
+
invoke "nginx:proxy:site:enable" # This will also reload
|
|
202
|
+
end
|
|
203
|
+
invoke "nginx:proxy:service:restart" # Or :restart if significant changes
|
|
204
|
+
puts "✅ [PROXY] Nginx reconfiguration complete!"
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end # end :proxy namespace
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
211
|
+
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# --- APP NGINX TASKS ---
|
|
215
|
+
namespace :app do
|
|
216
|
+
namespace :site do
|
|
217
|
+
desc "Upload App Nginx site configuration"
|
|
218
|
+
task :upload do
|
|
219
|
+
on roles fetch(:nginx_app_roles) do
|
|
220
|
+
config_file = fetch(:nginx_app_template)
|
|
221
|
+
target_config = fetch(:nginx_app_site_name)
|
|
222
|
+
|
|
223
|
+
puts "📤 [APP] Uploading Nginx config: #{target_config} from #{config_file}"
|
|
224
|
+
if config_file == :default
|
|
225
|
+
template2go("nginx_app_conf", "/tmp/#{target_config}")
|
|
226
|
+
else
|
|
227
|
+
template2go(config_file, "/tmp/#{target_config}")
|
|
228
|
+
end
|
|
229
|
+
execute :sudo, :mv, "/tmp/#{target_config}", "/etc/nginx/sites-available/#{target_config}"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
desc "Enable App Nginx site"
|
|
234
|
+
task :enable do
|
|
235
|
+
on roles fetch(:nginx_app_roles) do
|
|
236
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_app_site_name)}"
|
|
237
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_app_site_name)}"
|
|
238
|
+
unless test "[ -h #{enabled_path} ]"
|
|
239
|
+
puts "🔗 [APP] Enabling Nginx site..."
|
|
240
|
+
execute :sudo, :ln, "-s", available_path, enabled_path
|
|
241
|
+
invoke "nginx:app:service:reload" # Or :restart if it's a container
|
|
242
|
+
else
|
|
243
|
+
puts "✅ [APP] Nginx site is already enabled!"
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
desc "Disable App Nginx site"
|
|
249
|
+
task :disable do
|
|
250
|
+
on roles fetch(:nginx_app_roles) do
|
|
251
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_app_site_name)}"
|
|
252
|
+
if test "[ -h #{enabled_path} ]"
|
|
253
|
+
puts "🚫 [APP] Disabling Nginx site..."
|
|
254
|
+
execute :sudo, :rm, "-f", enabled_path
|
|
255
|
+
invoke "nginx:app:service:reload" # Or :restart
|
|
256
|
+
else
|
|
257
|
+
puts "⚠️ [APP] Nginx site is not enabled!"
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
desc "Remove App Nginx site configuration"
|
|
263
|
+
task :remove do
|
|
264
|
+
on roles fetch(:nginx_app_roles) do
|
|
265
|
+
available_path = "/etc/nginx/sites-available/#{fetch(:nginx_app_site_name)}"
|
|
266
|
+
if test "[ -f #{available_path} ]"
|
|
267
|
+
puts "🗑 [APP] Removing Nginx site configuration..."
|
|
268
|
+
execute :sudo, :rm, "-f", available_path
|
|
269
|
+
else
|
|
270
|
+
puts "⚠️ [APP] Nginx site configuration does not exist!"
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
task :prepare do
|
|
276
|
+
on roles fetch(:nginx_app_roles) do
|
|
277
|
+
puts "⚙️ [APP] Ensuring Nginx directories exist..."
|
|
278
|
+
execute :sudo, "mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled"
|
|
279
|
+
# Ensure shared directories for logs and app root exist and have Nginx access
|
|
280
|
+
# This is usually handled by Capistrano's deploy:check and linked_dirs setup
|
|
281
|
+
invoke "nginx:app:site:upload"
|
|
282
|
+
puts "✅ [APP] Nginx setup completed! Enable with `cap #{fetch(:stage)} nginx:app:site:enable`"
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end # end site
|
|
286
|
+
|
|
287
|
+
namespace :service do
|
|
288
|
+
# Adjust commands if App Nginx is in a Docker container
|
|
289
|
+
# Example: set :nginx_app_cmd_prefix, "sudo docker exec my_nginx_container"
|
|
290
|
+
# execute "#{fetch(:nginx_app_cmd_prefix, 'sudo')} systemctl #{command} nginx"
|
|
291
|
+
%w[start stop restart reload].each do |command|
|
|
292
|
+
desc "#{command.capitalize} App Nginx service"
|
|
293
|
+
task command do
|
|
294
|
+
on roles fetch(:nginx_app_roles) do
|
|
295
|
+
# IF DOCKER: Replace with docker command e.g.
|
|
296
|
+
# execute :sudo, "docker restart #{fetch(:nginx_app_container_name)}" if command == 'restart'
|
|
297
|
+
# execute :sudo, "docker exec #{fetch(:nginx_app_container_name)} nginx -s #{command == 'restart' ? 'reload' : command}" # for reload, stop
|
|
298
|
+
puts "🔄 [APP] Running: systemctl #{command} nginx..."
|
|
299
|
+
execute :sudo, "systemctl #{command} nginx"
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
desc "Check App Nginx configuration"
|
|
304
|
+
task :check_config do
|
|
305
|
+
on roles fetch(:nginx_app_roles) do
|
|
306
|
+
# IF DOCKER: execute :sudo, "docker exec #{fetch(:nginx_app_container_name)} nginx -t"
|
|
307
|
+
puts "🧐 [APP] Checking nginx configuration..."
|
|
308
|
+
execute :sudo, "nginx -t"
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
desc "Check App Nginx status"
|
|
312
|
+
task :check_status do
|
|
313
|
+
on roles fetch(:nginx_app_roles) do
|
|
314
|
+
# IF DOCKER: execute :sudo, "docker ps -f name=#{fetch(:nginx_app_container_name)}"
|
|
315
|
+
puts "🔍 [APP] Checking nginx status..."
|
|
316
|
+
execute :sudo, "systemctl status nginx --no-pager"
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end # end service
|
|
320
|
+
|
|
321
|
+
desc "Update App Nginx (Upload, Enable if needed, Reload/Restart)"
|
|
322
|
+
task :update do
|
|
323
|
+
on roles fetch(:nginx_app_roles) do
|
|
324
|
+
puts "🔄 [APP] Reconfiguring Nginx..."
|
|
325
|
+
invoke "nginx:app:site:upload"
|
|
326
|
+
enabled_path = "/etc/nginx/sites-enabled/#{fetch(:nginx_app_site_name)}"
|
|
327
|
+
if test "[ -h #{enabled_path} ]"
|
|
328
|
+
puts "🔗 [APP] Site already enabled, reloading."
|
|
329
|
+
else
|
|
330
|
+
invoke "nginx:app:site:enable"
|
|
331
|
+
end
|
|
332
|
+
invoke "nginx:app:service:restart" # Or :restart
|
|
333
|
+
puts "✅ [APP] Nginx reconfiguration complete!"
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
desc "Fix App Nginx folder rights (if permission problems occur)"
|
|
338
|
+
task :fix_folder_rights do
|
|
339
|
+
on roles fetch(:nginx_app_roles) do # Only on app servers
|
|
340
|
+
puts "🛡️ [APP] Fixing folder rights..."
|
|
341
|
+
execute :sudo, "chmod o+x /home/#{fetch(:user)}"
|
|
342
|
+
execute :sudo, "chmod o+x #{fetch(:deploy_to)}"
|
|
343
|
+
execute :sudo, "chmod o+x #{current_path}" # current_path might not be fully set if deploy failed
|
|
344
|
+
execute :sudo, "chmod o+x #{shared_path}"
|
|
345
|
+
# Nginx (user www-data) needs read access to app files and write to logs
|
|
346
|
+
# These commands assume nginx_root_folder and nginx_log_folder are under shared_path
|
|
347
|
+
execute :sudo, "chown -R #{fetch(:user)}:#{fetch(:nginx_group)} #{shared_path}/#{fetch(:nginx_root_folder)}"
|
|
348
|
+
execute :sudo, "chown -R #{fetch(:user)}:#{fetch(:nginx_group)} #{shared_path}/#{fetch(:nginx_log_folder)}"
|
|
349
|
+
execute :sudo, "chmod -R g+rX,o-rwx #{shared_path}/#{fetch(:nginx_root_folder)}" # Group read/execute
|
|
350
|
+
execute :sudo, "chmod -R g+rwX,o-rwx #{shared_path}/#{fetch(:nginx_log_folder)}" # Group read/write/execute
|
|
351
|
+
# If Nginx runs as www-data and deploy user is different, you might need to add www-data to deploy user's group or use ACLs.
|
|
352
|
+
# A simpler (but less secure for shared hosts) approach for www-data to read:
|
|
353
|
+
# execute :sudo, "chmod -R o+rX #{shared_path}/#{fetch(:nginx_root_folder)}"
|
|
354
|
+
# execute :sudo, "find #{shared_path}/#{fetch(:nginx_root_folder)} -type d -exec chmod o+x {} \\;" # Ensure directories are executable
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end # end :app namespace
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
# --- COMBINED/UTILITY TASKS ---
|
|
361
|
+
desc "Setup Nginx for both Proxy and App roles defined in current stage"
|
|
362
|
+
task :setup_all do
|
|
363
|
+
if roles(fetch(:nginx_proxy_roles)).any?
|
|
364
|
+
invoke 'nginx:proxy:site:prepare'
|
|
365
|
+
else
|
|
366
|
+
puts "ℹ️ No :proxy roles defined for stage #{fetch(:stage)}, skipping proxy setup."
|
|
367
|
+
end
|
|
368
|
+
if roles(fetch(:nginx_app_roles)).any?
|
|
369
|
+
invoke 'nginx:app:site:prepare'
|
|
370
|
+
else
|
|
371
|
+
puts "ℹ️ No :app roles defined for stage #{fetch(:stage)}, skipping app Nginx setup."
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
desc "Update Nginx configurations for both Proxy and App roles defined in current stage"
|
|
376
|
+
task :update_all do
|
|
377
|
+
if roles(fetch(:nginx_proxy_roles)).any?
|
|
378
|
+
invoke 'nginx:proxy:update'
|
|
379
|
+
else
|
|
380
|
+
puts "ℹ️ No :proxy roles defined for stage #{fetch(:stage)}, skipping proxy update."
|
|
381
|
+
end
|
|
382
|
+
if roles(fetch(:nginx_app_roles)).any?
|
|
383
|
+
invoke 'nginx:app:update'
|
|
384
|
+
else
|
|
385
|
+
puts "ℹ️ No :app roles defined for stage #{fetch(:stage)}, skipping app Nginx update."
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
end # end :nginx namespace
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
# --- DEPLOY HOOKS ---
|
|
393
|
+
# Your original global setup hook. You might want to make it more specific
|
|
394
|
+
# or use the new `nginx:setup_all` task manually or hooked elsewhere.
|
|
395
|
+
# task :setup do
|
|
396
|
+
# # invoke 'nginx:proxy:site:prepare' # If always proxy
|
|
397
|
+
# # invoke 'nginx:app:site:prepare' # If always app
|
|
398
|
+
# invoke 'nginx:setup_all' # This will check roles
|
|
399
|
+
# end
|
|
400
|
+
|
|
401
|
+
namespace :deploy do
|
|
402
|
+
after 'deploy:finishing', :update_nginx_configurations do
|
|
403
|
+
# Update Proxy Nginx if hooks enabled and proxy roles exist for the stage
|
|
404
|
+
if fetch(:nginx_proxy_hooks) && roles(fetch(:nginx_proxy_roles)).any?
|
|
405
|
+
puts "훅: nginx:proxy:update wird aufgerufen"
|
|
406
|
+
invoke "nginx:proxy:update"
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# Update App Nginx if hooks enabled and app roles exist for the stage
|
|
410
|
+
if fetch(:nginx_app_hooks) && roles(fetch(:nginx_app_roles)).any?
|
|
411
|
+
puts "훅: nginx:app:update wird aufgerufen"
|
|
412
|
+
invoke "nginx:app:update"
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'capistrano/nuxt2/base_helpers'
|
|
2
|
+
include Capistrano::Nuxt2::BaseHelpers
|
|
3
|
+
|
|
4
|
+
namespace :load do
|
|
5
|
+
task :defaults do
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
set :vue_use_nvm, -> { false }
|
|
9
|
+
set :vue_install_without_env, -> { false }
|
|
10
|
+
set :vue_nvm_path, -> { "~/.nvm" }
|
|
11
|
+
set :vue_nvm_version, -> { "18.19.0" }
|
|
12
|
+
set :vue_nvm_script, -> { "$HOME/.nvm/nvm.sh" }
|
|
13
|
+
|
|
14
|
+
set :vue_app_roles, -> { :app }
|
|
15
|
+
|
|
16
|
+
## Maybe nonsense .. builds `APP_NAME_STG_DEPLOY_MODE`
|
|
17
|
+
set :vue_stage_env_var, -> { build_deploy_env_var }
|
|
18
|
+
|
|
19
|
+
append :linked_dirs, 'node_modules' # , '.nuxt', 'dist'
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
namespace :vue do
|
|
26
|
+
|
|
27
|
+
desc "output env var and stage"
|
|
28
|
+
task :output_env do
|
|
29
|
+
on roles(fetch(:vue_app_roles)) do
|
|
30
|
+
puts "🔧 Vue.js stage: #{fetch(:stage)}"
|
|
31
|
+
puts "🔧 Vue.js deploy mode: #{fetch(:vue_stage_env_var)}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
desc "Install dependencies"
|
|
36
|
+
task :install_dependencies do
|
|
37
|
+
on roles(fetch(:vue_app_roles)) do
|
|
38
|
+
within release_path do
|
|
39
|
+
if fetch(:vue_use_nvm, false)
|
|
40
|
+
env_vars = fetch(:default_env).map { |k, v| "#{k}=#{v}" }.join(" ")
|
|
41
|
+
nvm_prefix = "source #{fetch(:vue_nvm_script)} && nvm use #{fetch(:vue_nvm_version)}"
|
|
42
|
+
if fetch(:vue_install_without_env, false)
|
|
43
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && npm install --production=false')
|
|
44
|
+
else
|
|
45
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && env #{env_vars} npm install')
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
execute :npm, "install"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
desc "Build Vue.js app"
|
|
56
|
+
task :build do
|
|
57
|
+
on roles(fetch(:vue_app_roles)) do
|
|
58
|
+
within release_path do
|
|
59
|
+
if fetch(:vue_use_nvm, false)
|
|
60
|
+
env_vars = fetch(:default_env).map { |k, v| "#{k}=#{v}" }.join(" ")
|
|
61
|
+
nvm_prefix = "source #{fetch(:vue_nvm_script)} && nvm use #{fetch(:vue_nvm_version)}"
|
|
62
|
+
execute %(bash -lc '#{nvm_prefix} && cd #{release_path} && env #{env_vars} npm run build')
|
|
63
|
+
else
|
|
64
|
+
execute :npm, "run build"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
desc "Sync the dist folder to the shared folder"
|
|
72
|
+
task :sync_dist do
|
|
73
|
+
on roles(fetch(:vue_app_roles)) do
|
|
74
|
+
execute :rsync, "-a --delete #{release_path}/dist/ #{shared_path}/www/"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
desc "Setup defaults for Vue.js app"
|
|
79
|
+
task :setup_app do
|
|
80
|
+
on roles(fetch(:vue_app_roles)) do
|
|
81
|
+
ensure_shared_www_path
|
|
82
|
+
ensure_shared_log_path
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
desc "Fix permissions (just in case)"
|
|
87
|
+
task :fix_permissions do
|
|
88
|
+
on roles(fetch(:vue_app_roles)) do
|
|
89
|
+
execute :sudo, :chown, "-R #{fetch(:user)}:#{fetch(:user)} #{release_path}"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
desc "Regenerate Vue.js app"
|
|
96
|
+
task :rebuild_app do
|
|
97
|
+
invoke "vue:install_dependencies"
|
|
98
|
+
invoke "vue:build"
|
|
99
|
+
invoke "vue:sync_dist"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
desc "Install required node version with nvm"
|
|
104
|
+
task :install_nvm_node do
|
|
105
|
+
on roles(fetch(:vue_app_roles)) do
|
|
106
|
+
if fetch(:vue_use_nvm, false)
|
|
107
|
+
execute %(bash -lc 'source #{fetch(:vue_nvm_script)} && nvm install #{fetch(:vue_nvm_version)}')
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
namespace :deploy do
|
|
115
|
+
after 'deploy:published', :rebuild_nuxt_app do
|
|
116
|
+
invoke "vue:rebuild_app"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
desc 'Server setup tasks'
|
|
122
|
+
task :setup do
|
|
123
|
+
invoke 'vue:setup_app'
|
|
124
|
+
end
|
|
125
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
## Modern TLS Security
|
|
3
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
4
|
+
ssl_ciphers <%= fetch(:nginx_ssl_ciphers) %>;
|
|
5
|
+
ssl_prefer_server_ciphers on;
|
|
6
|
+
ssl_ecdh_curve X25519:secp384r1;
|
|
7
|
+
|
|
8
|
+
ssl_session_cache shared:SSL_50:50m;
|
|
9
|
+
ssl_session_tickets off;
|
|
10
|
+
|
|
11
|
+
<% if fetch(:nginx_ocsp_stapling, false) %>
|
|
12
|
+
## OCSP Stapling for Faster SSL Handshakes
|
|
13
|
+
ssl_stapling on;
|
|
14
|
+
ssl_stapling_verify on;
|
|
15
|
+
# DNS für die OCSP-Abfrage
|
|
16
|
+
resolver 8.8.8.8 1.1.1.1 valid=300s;
|
|
17
|
+
resolver_timeout 5s;
|
|
18
|
+
<% end %>
|
|
19
|
+
|
|
20
|
+
## Security Headers
|
|
21
|
+
add_header X-Frame-Options DENY;
|
|
22
|
+
add_header X-Content-Type-Options nosniff;
|
|
23
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
|
24
|
+
|
|
25
|
+
## Enable HTTP Strict Transport Security (HSTS)
|
|
26
|
+
<% if fetch(:nginx_strict_security) %>
|
|
27
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
|
|
28
|
+
<% end %>
|
|
29
|
+
|