LINUX.ORG.RU
решено ФорумAdmin

Nginx не отдаёт картинки. Как пофиксить?

 


0

1

Конфиг для сайта: https://pastebin.com/gmqbjfbE

При запросе картинки: http://xxx.xxx.xxx.xxx/...f7a523705381.png

Вижу ошибку «504 Gateway Time-out». Без конца крутится прелоадер в браузере. Подскажите как фиксить.

В логах это выглядит так:

2022/05/15 18:00:55 [error] 5386#5386: *48 upstream timed out (110: Connection timed out) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: xxx.xxx.xxx.xxx, request: "GET /api/static/image/2022/5126a2f6-5542-461d-b3bb>

Бэк на Node.js

P.S. если что, то я не шарю настраивать Nginx от слова совсем. Первый опыт.

★★★★★

Последнее исправление: CryNet (всего исправлений: 6)

Он же тебе написал в логе и в ошибке: «бек» зависает и nginx не может дождаться ответа от него. Он конечно не должен зависать (ни от каких запросов, даже от некорректных) и это тебе следует исправить (в nodejs где-то, а лучше выкинуть эту гадость и делать сайт хотя бы на php). Но мне кажется что у тебя ещё и неправильный урл, скорее всего должен был быть «/static/image/2022/5126a2f6-5542-461d-b3bb» (без /api в начале).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от Oldboy

Нет. Автор может и правда не осилит ничего сложнее php, но php осилят все. И он однозначно лучше чем nodejs. Если осилит си - прекрасно, но думаю тогда он бы не создал эту тему.

firkax ★★★★★
()
Ответ на: комментарий от vel

вот и смотри логи ноды

М-м-м а они по ходу не пишутся или я хз где их искать. У меня есть только это:

  • access_log /var/log/nginx/crynet.tech.access.log;
  • error_log /var/log/nginx/crynet.tech.error.log;
CryNet ★★★★★
() автор топика
Последнее исправление: CryNet (всего исправлений: 1)
Ответ на: комментарий от zolden

@zolden

А что за картинки такие, что их REST API сервер отдаёт?

Та вроде нормальная практика:

https://qna.habr.com/q/456980

Даже есть специальная либа для Node. Но там ничего такого в плане логики. Просто тыкаешься на URL, а Node отдаёт картинку и все.

В моём мире всё это должна решать Node, а Nginx тут чисто как прокси. Вроде так все делают. Но это мой первый опыт с Нодой и вообще бэком и Nginx, так что могу многого не знать.

Хотя может и переделать это. Видимо так делают, чтобы прогер не заморачивался с конфигами сервака, а на проектах для прода Nginx-ом занимается девопс.

CryNet ★★★★★
() автор топика
Последнее исправление: CryNet (всего исправлений: 3)
Ответ на: комментарий от firkax

скорее всего должен был быть «/static/image/2022/5126a2f6-5542-461d-b3bb» (без /api в начале

URL правильный. Просто у любого обращения к бэку в URL-е есть /api/. Я знаю, что это это выглядит ужасно. Всё никак не дойдут руки это пофиксить, хоть это и дело двух минут.

CryNet ★★★★★
() автор топика
Ответ на: комментарий от CryNet

Ну давай рассуждать логически.

nodejs жуткое говно в части простых операций типа отдать файл с диска.

Он хорош незаменим в первую очередь как сервер с поддержкой websocket. Также он хорош как сервер с динамическим программируемым содержимым.

nginx наоборот, хорош как реверс-прокси для защиты стоящего позади него тела жирного в утесах и раздатчик статики.

Так что в правильных проектах нжинксу отдают статику, элементарно определив префикс в url типа /media или /static и отдавая все, что начинается с этих префиксов напрямую. Это и быстро и ненпаряжно для сервера и надежно.

Естественно, бывают исключения. Например, нет сил/ресурсов использовать сервер nginx. Программист хорошо знает свой сервер приложений и не хочет ставить/сопровождать еще и реверс-прокси. Ну ок, понятно. Но это явно не твой случай. Во первых, nginx ты уже поставил, а во вторых ты с nodejs явно на ВЫ, раз не сообразил что проблема в nodejs, просто обратившись по внутреннему url мимо nginx.

Еще вариант, реверс-прокси находится на другом узле и доступа к статике с него нет или он неудобен. Тоже вариант.

Возможно, статика тоже должна отдаваться с тонкой проверкой прав, ролей и т.д. и эта логика не может быть без серьезных усилий передана на nginx (хотя это крайне полезно, но муторно и не всем хочется заморачиваться).

Возможно, один из этих вариантов твой, поэтому я и спросил.

AVL2 ★★★★★
()
Ответ на: комментарий от AVL2

раз не сообразил что проблема в nodejs, просто обратившись по внутреннему url мимо nginx

Типа убить nginx, запустить nodejs и спосмотреть что он отдаст если запросить картинку?

Бо вот это: /api/static/image/2022/5126a2f6-5542-461d-b3bb.png и есть обращение к картинке напрямую. По моей логике Nodejs чекнет есть ли тут картинка, и отдаст её из static/image/2022/5126a2f6-5542-461d-b3bb-f7a523705381.png.

элементарно определив префикс в url типа /media или /static и отдавая все, что начинается с этих префиксов напрямую

А раскрытие путей возможно, нужно дополнительно конфигурировать Nginx или он сам это решает?

CryNet ★★★★★
() автор топика
Ответ на: комментарий от AVL2

Кстати. Если загуглить деплой подобный стеков, как у меня. То как правило везде устанавливают Nginx. Хотя как бы можно и без него. Пока не знаю с чем это связанно.

CryNet ★★★★★
() автор топика
Ответ на: комментарий от CryNet

Это связано не в последнюю очередь с тем что отдавать статику нодой/апачем/пхп - это быть ссзб, поскольку сильно возрастает загрузка сервера (они не умеют делать это хорошо). Поэтому ставят прокси вроде nginx (lighttp и иже с ними).

AndreyKl ★★★★★
()
Ответ на: комментарий от leave

По моей логике Nodejs чекнет есть ли тут картинка

а зачем?

Ну я в такой способ защитился от раскрытия путёй, чтобы static/image/../../../2022/index.ts не сработало. Локально у меня нет Nginx-а и я разработку вёл без него. Я и не думал, что мне придёться его настраивать, для меня это вообще шок xD

CryNet ★★★★★
() автор топика
Ответ на: комментарий от CryNet

Я уже плохо помню детали, но в целом идея (эффеткивной) настройки такая:

- у тебя есть nginx
- за ним стоит нода
- на nginx приходит запрос на картинку, например, /api/image/22.png
- этот запрос nginx должен передать ноде
- нода _не_ _должна_ отдавать картинку. должна проверить права на файл и передать nginx-у ответ в виде хидера с редиректом (модуль internal кажется). Если права доступа есть - то редирект на то метсо где лежит файл, а иначе на страничку с сообщением об ошибке.
- nginx принимает редирект от ноды, понимает его и отдаёт браузеру нужную информацию. при этом урл в браузере клиента остаётся /api/image/22.png (т.е. не меняется всю дорогу).

вот тут нашёл инструкцию, вроде то что нужно
https://shortcut.com/developer-how-to/how-to-use-internal-redirects-in-nginx

(да, хидер должен быть не обычный редирект, а X-Accel-Redirect, тогда nginx не передаёт его браузеру а обрабатывает сам. вроде так, но я уже наверное лет 7 не брался за это, поэтому за точность не ручаюсь).

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AVL2

nodejs жуткое говно в части простых операций типа отдать файл с диска.

Он хорош незаменим в первую очередь как сервер с поддержкой websocket. Также он хорош как сервер с динамическим программируемым содержимым.

Из всего этого надо оставить первые три слова, остальное - лишнее.

firkax ★★★★★
()
Ответ на: комментарий от CryNet

Ну я в такой способ защитился от раскрытия путёй, чтобы static/image/../../../2022/index.ts не сработало.

Он и так не сработает, если его будет отдавать nginx.

Я и не думал, что мне придёться его настраивать, для меня это вообще шок xD

Настройка nginx-а в 100 раз проще чем любое программирование. И nginx - важная часть любого веб-сервера, пытаться разрабатывать на обрезке без него это какая-то странная затея.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от CryNet

А почему оно должно сработать?

Ты делаешь отдельный локейшен

location /static/ {
    root /path/to/static/;
    try_files $uri $uri/ =404;
}

и отдельный главный

location / {
    proxy_pass http://node_ip:node_port;
}

https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms

leave ★★★★★
()
Ответ на: комментарий от AndreyKl

этот запрос nginx должен передать ноде

Мне например не нужна проверка прав, я могу скипнуть этот пункт? Nginx может обработать запрос и в ответ отдать картинку без Node?

CryNet ★★★★★
() автор топика
Ответ на: комментарий от CryNet

если урл типа /static/images/22.png, а картинки хранятся в /var/www/html/imgs, то это будет что то вроде

location /static/images {
  root /var/www/html/imgs;
}

вроде так.
Если будут ошибки пути, посмотри логи nginx, там вроде обычно понятно почему он не находит файл.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

location /static/images {
root /var/www/html/imgs;
}

Во-первых, надо «location ^~» а не «location». Во-вторых, с таким конфигом урл /static/images/22.png, будет браться из /var/www/html/imgs/static/images/22.png. Если надо чтобы он брался из /var/www/html/imgs/22.png то так:

 location ^~ /static/images {
   alias /var/www/html/imgs;
 }

firkax ★★★★★
()
Ответ на: комментарий от leave

Тем, кто не имеет чёткого понимания о том, зачем ему location без «^~» в этом месте. Иначе когда-то потом, после добавления доп. правил для не-статики, могут появиться неожиданные эффекты, и хорошо если не приводящие к уязвимостям. Если он сознательно поймёт что ^~ там лишнее - уберёт, а по дефолту оно должно быть.

firkax ★★★★★
()