Ristruttura il deploy: immagine autosufficiente per Dokploy
Il Dockerfile compilava l'applicazione in /app-src mentre il runtime girava da /var/www/html, popolato solo dal bind mount del sorgente: l'immagine costruita non veniva mai usata. L'entrypoint rieseguiva composer install e npm run build a ogni avvio, dentro il container. Su Dokploy, senza sorgente sull'host, questo significava build a runtime a ogni deploy. Ora vendor/ e public/build sono compilati in stage separati e copiati nell'immagine finale. I container di produzione non montano il sorgente e non eseguono build all'avvio: un redeploy e' build, migrazioni, online. - Dockerfile multi-stage (composer, node, runtime) - nginx e php-fpm nello stesso container via supervisor: con container separati nginx avrebbe bisogno di una copia di public/ e del volume storage solo per servire file statici - clear_env = no in www.conf, senza cui php-fpm nasconde a Laravel tutte le variabili d'ambiente - configurazione da ambiente di processo invece di .env riscritto con sed; il compose fissa solo i valori dettati dalla topologia - fail-fast su APP_URL, DB_PASSWORD, DB_ROOT_PASSWORD, REDIS_PASSWORD - servizio scheduler dedicato: schedule:work non veniva mai eseguito, quindi la pulizia dell'audit log non e' mai partita - solo il container app esegue le migrazioni, per evitare che due container in gara lascino uno schema applicato a meta' - healthcheck separati per worker e scheduler, che non espongono HTTP - docker-compose.dev.yml per lo sviluppo locale - documentazione unificata in README.md e HANDOFF.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
FROM nginx:1.25-alpine
|
||||
COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||
@@ -1,11 +1,21 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
root /var/www/html/public;
|
||||
index index.php index.html;
|
||||
index index.php;
|
||||
|
||||
charset utf-8;
|
||||
client_max_body_size 64M;
|
||||
|
||||
# Territory PDF/ZIP imports are the largest uploads; keep this in step with
|
||||
# upload_max_filesize / post_max_size in docker/php/php.ini.
|
||||
client_max_body_size 256M;
|
||||
|
||||
# Behind Dokploy's Traefik, the real client IP arrives in X-Forwarded-For.
|
||||
real_ip_header X-Forwarded-For;
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_recursive on;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
@@ -14,34 +24,70 @@ server {
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
# Vite emits content-hashed filenames, so these are safe to cache hard.
|
||||
location /build/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Uploaded territory PDFs and thumbnails (public/storage -> storage/app/public).
|
||||
# Served directly by nginx rather than round-tripping through PHP.
|
||||
location /storage/ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
|
||||
# Forward proxy headers so Laravel can validate signed URLs behind reverse proxy
|
||||
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||
fastcgi_param HTTP_X_FORWARDED_HOST $http_host;
|
||||
fastcgi_param HTTP_X_FORWARDED_PORT $http_x_forwarded_port;
|
||||
# PDF generation and ZIP imports can outrun the default 60s.
|
||||
fastcgi_read_timeout 300;
|
||||
fastcgi_buffers 16 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
|
||||
# Trust external proxy proto, or default to https for signed URL validation
|
||||
set $fwd_proto $http_x_forwarded_proto;
|
||||
if ($fwd_proto = "") {
|
||||
set $fwd_proto "https";
|
||||
}
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO $fwd_proto;
|
||||
# Set server-side, NOT taken from the client's header: honouring a
|
||||
# client-supplied X-Forwarded-Proto would let an attacker declare the
|
||||
# connection plaintext and skew signed-URL validation and secure-cookie
|
||||
# decisions. The value is written by the entrypoint from APP_URL's
|
||||
# scheme (see /etc/nginx/conf.d/forwarded-proto.conf) — https in
|
||||
# production behind Traefik, http for local plain-HTTP development.
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO $app_forwarded_proto;
|
||||
# X-Forwarded-Port is deliberately NOT set here. nginx already passes
|
||||
# the incoming header through as HTTP_X_FORWARDED_PORT, and Traefik
|
||||
# sends the real public port; overriding it with $server_port (always
|
||||
# 80 inside the container) would corrupt generated URLs.
|
||||
|
||||
internal;
|
||||
}
|
||||
|
||||
# Any other .php file is not a valid entrypoint — Laravel routes everything
|
||||
# through index.php. This blocks execution of uploaded/stray scripts.
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css application/json application/javascript
|
||||
text/xml application/xml image/svg+xml;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user