deploy
This commit is contained in:
@@ -141,6 +141,11 @@ export async function uploadAdminProductImages(files: FileList | readonly File[]
|
||||
})
|
||||
const payload = (await res.json().catch(() => ({}))) as { urls?: string[]; error?: string }
|
||||
if (!res.ok) {
|
||||
if (res.status === 413) {
|
||||
throw new Error(
|
||||
'Сервер отклонил файл как слишком большой (413). На проде часто лимит nginx: добавьте client_max_body_size для /api/ (см. docs/nginx-upload-limit.md). Проверьте также MAX_UPLOAD_BODY_BYTES в .env на сервере.',
|
||||
)
|
||||
}
|
||||
throw new Error(typeof payload.error === 'string' ? payload.error : `Ошибка загрузки (${res.status})`)
|
||||
}
|
||||
if (!Array.isArray(payload.urls)) {
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
- `OTHER_UPLOAD_MAX_FILE_BYTES` — отзывы, чек оплаты и т.п. (по умолчанию 2 МБ).
|
||||
- `MAX_UPLOAD_BODY_BYTES` — весь POST multipart (по умолчанию рассчитывается от лимита фото товара × 10 + запас).
|
||||
|
||||
**413 на проде, локально ок:** чаще всего **nginx** с лимитом по умолчанию 1 МБ. См. **[docs/nginx-upload-limit.md](nginx-upload-limit.md)** — добавьте `client_max_body_size` для `location /api/`.
|
||||
|
||||
Общие для публикации: `JWT_SECRET`, `ADMIN_EMAIL`, `DATABASE_URL`, `CORS_ORIGIN`, при раздельных доменах — `VITE_*` на этапе сборки фронта, `SERVER_PUBLIC_URL` / `CLIENT_PUBLIC_URL` для OAuth.
|
||||
|
||||
После правок `.env` **перезапустите API** (systemd или ваша команда).
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Лимит размера запроса (413) за reverse proxy
|
||||
|
||||
Локально запросы идут напрямую в Node (Vite проксирует на Fastify) — тело до **~201 МБ** (см. `getMaxUploadBodyBytes()` в [`server/src/lib/upload-limits.js`](../server/src/lib/upload-limits.js)).
|
||||
|
||||
На проде перед Node часто стоит **nginx** (или Caddy, Traefik). У **nginx** по умолчанию **`client_max_body_size 1m`** — загрузка картинки больше ~1 МБ даёт **413**, хотя на локалке всё работает.
|
||||
|
||||
## Nginx
|
||||
|
||||
В блоке `http`, `server` или в `location /api/` (где проксируется API) задайте лимит **не меньше** максимального тела одного запроса загрузки:
|
||||
|
||||
- один файл до **20 МБ** — достаточно **`25m`**;
|
||||
- до **10 файлов** за один `POST /api/admin/uploads` — теоретически до **~200 МБ** данных + multipart — разумно **`250m`** или **`300m`**.
|
||||
|
||||
Пример для `location`, который проксирует API:
|
||||
|
||||
```nginx
|
||||
location /api/ {
|
||||
client_max_body_size 250m;
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $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 $scheme;
|
||||
}
|
||||
```
|
||||
|
||||
После правки конфига: `sudo nginx -t && sudo systemctl reload nginx`.
|
||||
|
||||
## Переменные Node (если 413 не от nginx)
|
||||
|
||||
В `server/.env` не задавайте слишком маленькое **`MAX_UPLOAD_BODY_BYTES`** — иначе Fastify отрежет тело раньше прокси. По умолчанию считается как `getProductImageMaxFileBytes() * 10 + 1 МБ`. Если задали вручную — должно быть **≥ суммы ваших файлов** в одном multipart-запросе.
|
||||
|
||||
## Caddy (кратко)
|
||||
|
||||
В соответствующем site-блоке задайте лимит тела запроса по [документации Caddy v2](https://caddyserver.com/docs/caddyfile/directives/request_body) (например, `request_body` с `max_size`).
|
||||
@@ -132,6 +132,7 @@ server {
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
client_max_body_size 250m;
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
|
||||
Reference in New Issue
Block a user