Вопрос или проблема
У меня есть контейнер Docker с Nginx, который работает как SSL обратный прокси для аутентификации. У меня есть контейнер Apache, обслуживающий Laravel приложение. Я всегда получаю HTML, но без CSS или изображений. В Chrome я получаю:
Ресурс интерпретируется как таблица стилей, но передан с MIME-типом text/html:
Вот мой default.conf в nginx/sites/
upstream app {
server 172.18.0.6;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server ipv6only=on;
server_name rocket.example.com localhost;
root /var/www/public;
index index.php index.html index.htm;
include /etc/nginx/mime.types;
# сообщаем пользователям перейти на версию SSL в этот раз
if ($ssl_protocol = "") {
rewrite ^ https://$server_name$request_uri? permanent;
}
add_header Strict-Transport-Security "max-age=15768000";
ssl_certificate /etc/nginx/rocket.crt;
ssl_certificate_key /etc/nginx/rocket.key;
ssl_dhparam /etc/nginx/rocket_dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK";
error_page 497 https://$host:$server_port$request_uri;
ssl_verify_client on;
ssl_verify_depth 10;
ssl_client_certificate /etc/nginx/allcerts.pem;
location / {
try_files $uri $uri/ /index.php$is_args$args;
include /etc/nginx/mime.types;
}
location ~ \.php$ {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Host $host:$server_port;
proxy_set_header Referer $http_referer;
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 https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header X-Client-Verify $ssl_client_verify;
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_send_timeout 86400;
proxy_read_timeout 86400;
include /etc/nginx/mime.types;
}
location ~ /\.ht {
deny all;
}
}
Ни одно из решений, которые я нашел в Google, не сработало.
Может кто-нибудь увидеть ошибку, которая может это вызывать? Я добавил директивы proxy_ в обе секции, с одинаковым эффектом. Любая помощь будет крайне признательна.
Секция, содержащая proxy_pass, установлена только для проксирования PHP-файлов. Эта строка здесь
location ~ \.php$ {
Первое, что я попробовал бы — переместить этот целый блок в основной блок “location /”.
Ваше перенаправление на https использует оператор if, что не идеально – прочитайте “if – это зло“. Если вы хотите, чтобы клиенты использовали https, лучше всего создать серию серверов для перенаправления, как так
# Перенаправление non-www запросов на www
server {
listen 80;
server_name example.com www.example.com;
access_log /var/log/nginx/hr.access.log main buffer=128k flush=1m if=$log_ua;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
ssl_certificate_key /var/lib/acme/certs//***CERT_DIRECTORY/privkey;
# Установите предпочтительные протоколы и шифры. TLS1.2 требуется для HTTP/2
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
access_log /var/log/nginx/hr.access.log main buffer=128k flush=1m if=$log_ua;
return 301 https://www.example.com$request_uri;
}
Ответ или решение
Для решения проблемы с тем, что Nginx не передает CSS и изображения в вашем приложении, необходимо рассмотреть несколько моментов в вашей конфигурации reverse proxy. Исходя из предоставленного вами конфигурационного файла default.conf
, существует ряд исправлений и рекомендаций, которые помогут устранить проблему.
- Перемещение блока
location ~ \.php$
: Ваша конфигурация обрабатывает только PHP-файлы в отдельном блокеlocation
. Это может привести к тому, что при запросе к статическим ресурсам (CSS, изображения и т.д.) Nginx не сможет корректно их обработать. Рекомендуется объединить обработку всех запросов в блокеlocation /
и использоватьtry_files
для поиска статических файлов, а также направлять запросы к PHP-скриптам. Попробуйте следующую конфигурацию:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass app; # Ваш upstream сервер
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
-
Удаление блока
include /etc/nginx/mime.types
: Этот блок лучше разместить только один раз в секцииhttp
, а не в каждом блокеlocation
. Проверьте, что типы MIME настроены корректно, чтобы Nginx мог корректно определять тип передаваемых ресурсов. -
Использование
rewrite
: Ваше текущее использованиеif
для перенаправления на HTTPS может вызвать проблемы в Nginx. Вместо этого лучше использовать отдельный серверный блок для перенаправления:
server {
listen 80;
server_name rocket.example.com;
return 301 https://$host$request_uri;
}
-
Проверка MIME-типов файлов: Убедитесь, что ваши статические файлы (CSS, изображения) имеют правильные расширения и находятся в ожидаемых директориях. Например, если ваш CSS-файл ожидается по адресу
/css/style.css
, убедитесь, что файл действительно доступен по указанному пути. -
Логирование ошибок: Включите логирование ошибок Nginx для более детального анализа проблемы. Это поможет вам увидеть, какие запросы обрабатываются неправильно:
error_log /var/log/nginx/error.log debug;
-
Проверка конфигурации Docker: Убедитесь, что конфигурация Docker правильно настроена для проксирования трафика и что все контейнеры находятся в одной сети. Проверьте, что контейнеры Nginx и Apache могут общаться друг с другом.
-
Проверка прав доступа: Убедитесь, что права доступа к файлам и директориям, особенно в
/var/www/public
, настроены корректно, чтобы Nginx мог их прочитать.
Приведенные выше шаги должны помочь вам устранить проблему с передачей CSS и изображений. После того, как вы внесете необходимые изменения, не забудьте протестировать конфигурацию Nginx с помощью команды:
nginx -t
Затем перезапустите Nginx:
systemctl restart nginx
Если после этих изменений проблемы сохраняются, проверьте логи Nginx и Apache на наличие сообщений об ошибках, которые могут указать на конкретные причины проблем в конфигурации.