Gestisco un sito web dove gli appassionati di fotografia condividono frequentemente le loro opere, e vorrei disabilitare tutta la compressione delle immagini abilitando contemporaneamente la rimozione dei metadati. Ho apportato le seguenti modifiche:
Ho impostato la dimensione massima dell’immagine a 40 MB, ho impostato i megapixel massimi dell’immagine sul valore massimo consentito di 150 MP e ho disabilitato l’ottimizzazione delle immagini dei media del compositore.
Ho anche modificato le impostazioni di Nginx nel contenitore.
In sintesi, ho aggiunto
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 30s;
proxy_read_timeout 1m;
proxy_send_timeout 1m;
e modificato
# dimensione massima del caricamento file (mantenere aggiornata quando si modifica l'impostazione corrispondente del sito)
client_max_body_size 200m ;
In server{} in /etc/nginx/nginx.conf.
Ho aggiunto
client_max_body_size 200m;
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 60s;
proxy_read_timeout 1m;
proxy_send_timeout 1m;
in http{} in /etc/nginx/nginx.conf
Ecco le configurazioni per /etc/nginx/nginx.conf e /etc/nginx/conf.d/discourse.conf:
root@iZj6cgi365ov99veqodfgnZ-app:/var/www/discourse# cat /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
daemon off;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 4000 ;
# multi_accept on;
}
http {
client_max_body_size 200m;
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 60s;
proxy_read_timeout 1m;
proxy_send_timeout 1m;
##
# Impostazioni di base
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Impostazioni SSL
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Rimozione SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Impostazioni di registrazione
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Impostazioni Gzip
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Configurazioni Virtual Host
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # Vedi script di autenticazione di esempio a:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
root@iZj6cgi365ov99veqodfgnZ-app:/var/www/discourse# cat /etc/nginx/conf.d/discourse.conf
# Altri tipi MIME che desideri che nginx gestisca vanno qui
types {
text/csv csv;
application/wasm wasm;
}
upstream discourse { server 127.0.0.1:3000; }
# inactive significa che manteniamo i dati per 1440m minuti indipendentemente dall'ultimo accesso (1 settimana)
# levels significa che è una gerarchia profonda di 2 livelli perché possiamo avere molti file
# max_size limita la dimensione della cache
proxy_cache_path /var/nginx/cache inactive=1440m levels=1:2 keys_zone=one:10m max_size=600m;
# Aumentato dal valore predefinito per accommodare grandi cookie durante i flussi oAuth2
# come in https://meta.discourse.org/t/x/74060 e grandi intestazioni CSP e Link (preload)
proxy_buffer_size 32k;
proxy_buffers 4 32k;
# Aumentato dal valore predefinito per permettere un grande volume di cookie nelle intestazioni di richiesta
# Discourse stesso cerca di minimizzare la dimensione dei cookie, ma non possiamo controllare altri cookie impostati da altri strumenti sullo stesso dominio.
large_client_header_buffers 4 32k;
# Se userai Puma, usa queste:
#
# upstream discourse {
# server unix:/var/www/discourse/tmp/sockets/puma.sock;
# }
# tentativo di preservare il protocollo, deve essere nel contesto http
map $http_x_forwarded_proto $thescheme {
default $scheme;
"~https$" https;
}
log_format log_discourse '[$time_local] "$http_host" $remote_addr "$request" "$http_user_agent" "$sent_http_x_discourse_route" $status $bytes_sent "$http_referer" $upstream_response_time $request_time "$upstream_http_x_discourse_username" "$upstream_http_x_discourse_trackview" "$upstream_http_x_queue_time" "$upstream_http_x_redis_calls" "$upstream_http_x_redis_time" "$upstream_http_x_sql_calls" "$upstream_http_x_sql_time"';
# Consentire l'aggiramento della cache da localhost
geo $bypass_cache {
default 0;
127.0.0.1 1;
::1 1;
}
limit_req_zone $binary_remote_addr zone=flood:10m rate=12r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=200r/m;
limit_req_status 429;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;
server {
listen 80;
return 301 https://kongjiang.org$request_uri;
}
server {
access_log /var/log/nginx/access.log log_discourse;
listen 443 ssl http2;
listen [::]:443 ssl http2;
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 30s;
proxy_read_timeout 1m;
proxy_send_timeout 1m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_certificate /shared/ssl/kongjiang.org.cer;
ssl_certificate /shared/ssl/kongjiang.org_ecc.cer;
ssl_certificate_key /shared/ssl/kongjiang.org.key;
ssl_certificate_key /shared/ssl/kongjiang.org_ecc.key;
ssl_session_tickets off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:1m;
gzip on;
add_header Strict-Transport-Security 'max-age=63072000';
if ($http_host != kongjiang.org) {
rewrite (.*) https://kongjiang.org$1 permanent;
}
gzip_vary on;
gzip_min_length 1000;
gzip_comp_level 5;
gzip_types application/json text/css text/javascript application/x-javascript application/javascript image/svg+xml application/wasm;
gzip_proxied any;
# Scommenta e configura questa sezione per il supporto HTTPS
# NOTA: Inserisci il tuo certificato SSL nella directory principale di configurazione di nginx (/etc/nginx)
#
# rewrite ^/(.*) https://enter.your.web.hostname.here/$1 permanent;
#
# listen 443 ssl;
# ssl_certificate your-hostname-cert.pem;
# ssl_certificate_key your-hostname-cert.key;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers HIGH:!aNULL:!MD5;
#
server_name _ ;
server_tokens off;
sendfile on;
keepalive_timeout 65;
# dimensione massima del caricamento file (mantenere aggiornata quando si modifica l'impostazione corrispondente del sito)
client_max_body_size 200m ;
# percorso alla directory pubblica di discourse
set $public /var/www/discourse/public;
# senza etag deboli non otteniamo alcun beneficio dagli etag sui contenuti compressi dinamicamente
# inoltre gli etag si basano sul file in nginx non sull'hash sha dei dati
# usa le date, risolve il problema bene anche tra server diversi
etag off;
# prevenire il download diretto dei backup
location ^~ /backups/ {
internal;
}
# aggirare lo stack rails con un economico 204 per le richieste favicon.ico
location /favicon.ico {
return 204;
access_log off;
log_not_found off;
}
location / {
root $public;
add_header ETag "";
# auth_basic on;
# auth_basic_user_file /etc/nginx/htpasswd;
location ~ ^/uploads/short-url/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
location ~ ^/(secure-media-uploads/|secure-uploads)/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
location ~* (fonts|assets|plugins|uploads)/.*\.(eot|ttf|woff|woff2|ico|otf)$ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location = /srv/status {
access_log off;
log_not_found off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
# una minima cache qui così non continuiamo a chiedere
# a lungo termine dovremmo probabilmente aumentare a 1y
location ~ ^/javascripts/ {
expires 1d;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location ~ ^/assets/(?<asset_path>.+)$ {
expires 1y;
# la pipeline delle risorse abilita questo
brotli_static on;
gzip_static on;
add_header Cache-Control public,immutable;
# HOOK nella posizione delle risorse (usata per l'estendibilità)
# TODO non penso che questo break sia necessario, interrompe solo il rewrite
break;
}
location ~ ^/plugins/ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
# cache emoji
location ~ /images/emoji/ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location ~ ^/uploads/ {
# NOTA: è davvero fastidioso che non possiamo definire le intestazioni
# al livello superiore ed ereditare.
#
# proxy_set_header NON eredita, per design, dobbiamo ripeterlo,
# altrimenti le intestazioni non sono impostate correttamente
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping $public/=/downloads/;
expires 1y;
add_header Cache-Control public,immutable;
## regole opzionali anti-hotlinking per i caricamenti
#valid_referers none blocked mysite.com *.mysite.com;
#if ($invalid_referer) { return 403; }
# CSS personalizzato
location ~ /stylesheet-cache/ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
# questo ci permette di aggirare rails
location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff|ico||avif)$ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
# SVG necessita di un'intestazione extra allegata
location ~* \.(svg)$ {
}
# miniature e immagini ottimizzate
location ~ /_?optimized/ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
proxy_pass http://discourse;
break;
}
location ~ ^/admin/backups/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping $public/=/downloads/;
proxy_pass http://discourse;
break;
}
# Questo grande blocco è necessario per abilitare selettivamente
# l'accelerazione per backup, avatar, sprite e così via.
# vedi nota sulla ripetizione sopra
location ~ ^/(svg-sprite/|letter_avatar/|letter_avatar_proxy/|user_avatar|highlight-js|stylesheets|theme-javascripts|favicon/proxied|service-worker) {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
# se Set-Cookie è nella risposta nulla viene messo in cache
# questo è doppiamente negativo perché non stiamo passando last modified
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_hide_header "X-Discourse-Username";
proxy_hide_header "X-Runtime";
# nota x-accel-redirect non può essere usato con proxy_cache
proxy_cache one;
proxy_cache_key "$scheme,$host,$request_uri";
proxy_cache_valid 200 301 302 7d;
proxy_cache_bypass $bypass_cache;
proxy_pass http://discourse;
break;
}
# dobbiamo disabilitare il buffering per message bus
location /message-bus/ {
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_pass http://discourse;
break;
}
# questo significa che ogni file in public viene provato per primo
try_files $uri @discourse;
}
location /downloads/ {
internal;
alias $public/;
}
location @discourse {
add_header Strict-Transport-Security 'max-age=31536000'; # ricordare il certificato per un anno e connettersi automaticamente a HTTPS per questo dominio limit_conn connperip 20;
limit_req zone=flood burst=12 nodelay;
limit_req zone=bot burst=100 nodelay;
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
}
}
Nonostante queste modifiche, ricevo ancora un errore „file troppo grande“ quando carico immagini superiori a 15 MB, e con l’ottimizzazione delle immagini dei media del compositore disabilitata, le immagini non riescono a essere caricate.
Qualcuno potrebbe guidarmi su quali altre impostazioni dovrei modificare o se c’è un problema con la mia configurazione Nginx?
Sono nuovo di Nginx e mi sono affidato interamente a Google e ChatGPT per queste modifiche.