#ubuntu #nginx
Вопрос:
Я установил nginx на свой VPS, который работает под управлением Ubuntu 18.04. После настройки записей DNS для домена, указывающих на мой VPS (просто запись A, указывающая на IP-адрес VPS), я все равно получаю ошибку «404 Не найден», хотя я считаю, что конфигурация моего серверного блока правильная. Я оставлю саму конфигурацию ниже, так как есть добрые люди, у которых гораздо больше опыта, чем у меня 🙂
P.S. Я также включил изменения, внесенные Certbot, поскольку сайт использует https, и URL-адрес сайта в конфигурации.
server {
root /root/web/hudson/main;
index index.html index.htm index.nginx-debian.html;
server_name huds0n.xyz;
location / {
try_files $uri $uri/ =404;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/huds0n.xyz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/huds0n.xyz/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = huds0n.xyz) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name huds0n.xyz;
listen 80;
return 404; # managed by Certbot
}
Ответ №1:
Позвольте мне объяснить, что вы сделали с этой конфигурацией.
Вы определили два виртуальных сервера. Мы пока оставим первое, давайте объясним второе :
Первые три строки этого сервера следующие :
if ($host = huds0n.xyz) {
return 301 https://$host$request_uri;
} # managed by Certbot
В первой строке мы проверяем, является ли переменная $host, заданная nginx huds0n.xyz
. Он извлекается из заголовка Host
запроса из HTTP-запроса.
Если это этот хост, мы возвращаем код состояния HTTP 301 (перемещен навсегда) с новым местоположением https://
$host
(Полное доменное имя) $request_uri
(Что в нашем случае после .xyz).
Затем мы определяем имя сервера, которое отличает этот сервер от других. Комбинация Порт Имя сервера позволяет nginx знать, какую конфигурацию сервера использовать при обработке запроса.
В этом случае мы находимся на незашифрованном порту HTTP, как видно в следующей строке с хостом huds0n.xyz.
Даже с этим именем сервера, присвоенным nginx, если у вас нет default_server
указания в параметре listen
директивы, nginx может использовать этот сервер для обработки запроса.
Затем мы возвращаем ошибку 404 «Не найдено». Наконец, для этого виртуального сервера мы получаем 404, только если мы не используем хост huds0n.xyz. (Попробуйте, например, если у вас нет ничего другого, что мешает ему использовать IP-адрес сервера в вашем браузере, чтобы узнать, перенаправлены ли вы).
Теперь у нас есть первый серверный блок, который определяет часть сервера SSL/TLS.
Я вижу две проблемы с этой конфигурацией, но сначала я объясню, что на данный момент делает ваша конфигурация.
Вы определяете корневое расположение в папке /root/web/hudson/main. Это должна быть папка.
Поэтому , если вы напишете в своем браузере https://huds0n.xyz/i-like-bananas.html
, он будет извлечен i-like-bananas.html
в основной папке.
Следующая строка-это директива индекса. Давайте представим, что в вашей основной папке у вас есть папка с именем strawberry
и еще одна с именем raspberry
. В strawberry
вашем файле есть файл с именем index.html содержит красивую картинку с изображением клубники. В raspberry
, к сожалению, веб-мастер забыл поместить такой файл.
С помощью директивы index вы указываете nginx искать файлы (в порядке слева направо), указанные в директиве. Nginx будет, когда вы напишете URL-адрес папки, искать index.html тогда, если не найдется index.htm и так далее.
Следующий блок-это блок расположения в корне веб-сайта ( /
). Каждый запрос, сделанный на этом сервере, связан с этим блоком.
Директива try_files аналогична директиве index, но она запускается каждым URL-адресом, а не только URL-адресом, связанным с папкой.
Он попытается ввести URI (правую часть URL-адреса после хоста), затем URI в виде папки или вернет ошибку 404 (Не найден).
Следующий блок расположения касается каждого файла, соответствующего регулярному выражению (это значение тильды), и это значение регулярного выражения-каждое имя файла, которое заканчивается .php
.
Для этих файлов мы включаем некоторую конфигурацию php fastcgi, которая предоставит PHP необходимые переменные для обработки запроса, и мы передаем запрос и переменные в сокет unix, расположенный внутри /run/php/php7.2-fpm.sock
.
После этого у нас есть директива, которая заставляет nginx прослушивать порт HTTPS, и конфигурация SSL/TLS. Я пропущу эту часть.
Две проблемы, о которых я упоминал ранее, заключаются в следующем :
- Вы хотите использовать PHP, но ваша директива индекса указывает на HTML-файлы. Если вы хотите index.php чтобы использовать для вашей корневой веб-страницы, измените ее на
index index.php
- В
/
блоке определения местоположения вы пробуете $uri, $uri плюс косая черта, затем возвращаете 404. Многие CMS/фреймворки (я думаю, например, о laravel) делают возможным своего рода переписывание URL-адреса. У вас есть один PHP файл (index.php например), который обрабатывает каждый запрос. Как это работает ? Мы просто даем PHP информацию о путиfilename path
в виде переменной FastCGI. Вы можете изменить свой блок, чтобы выполнить эту миссию, поместив это вместо вашейtry_files
директивы :try_files $uri $uri/ /index.php?$query_string;
Основной причиной этого 404 также может быть тот факт, что ваш сервер nginx не может получить доступ к папке или что ваша папка отсутствует/пуста.
Как и было изначально задумано, ваш веб-контент ДОЛЖЕН находиться в /var/www/<subfolder>
папке и принадлежать www-data
.
Вы не должны помещать свои файлы в корневую папку/.
Я надеюсь, что это ответит на ваш вопрос и поможет вам найти причину вашей проблемы.
Комментарии:
1. Блестящий ответ! У меня есть еще один вопрос. Можно ли использовать оба файла с ‘.html’ и ‘.php’ в одном каталоге?
2. Да, конечно, но вам нужно запросить их с помощью URL-адреса. Вы также можете использовать его в качестве индексных файлов. Написание
index index.php index.html
заставит nginx искать файл PHP, а затем файл HTML.