ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 48s
ci / api (push) Successful in 51s
ci / recommender (push) Canceled after 2s
ci / ts (packages + web) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (apps/web/Dockerfile, web, ) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, api, api) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, storage-agent, storage-agent) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/recommender/Dockerfile, recommender, ) (push) Canceled after 0s
ci / mobile (Metro-бандл Android) (push) Canceled after 0s
Security and robustness: - storage-agent rejects an empty INTERNAL_TOKEN (config notEmpty + middleware) - api takes the client IP only from X-Real-IP (chi RealIP trusted True-Client-IP) - /readyz reports ok/fail and logs the cause; checks run in parallel with a timeout - storage-agent shuts down gracefully; shared httpx.NewServer/Serve with IdleTimeout - goose migrations take a Postgres advisory lock - recommender readyz: per-check timeout, redis socket timeouts Clients: - Android release allows cleartext HTTP for LAN servers (expo-build-properties) - checkServer times out after 10s; connect button is disabled while checking Deploy and CI: - install.sh hands cache/uploads/updates/models to the non-root service users - update.sh refuses downgrades unless PIPU_ALLOW_DOWNGRADE=1 - recommender/analyzer get only the env they need; required secrets fail fast - nginx security headers and CSP; strip True-Client-IP - dev compose binds ports to 127.0.0.1; postgres/redis images pinned - version.mjs fails on a malformed explicit tag instead of releasing 0.0.0-dev - contract check catches untracked generated files - final releases fail without a release keystore; changelog skips rc tags Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.6 KiB
Plaintext
68 lines
2.6 KiB
Plaintext
# Шаблон обрабатывается envsubst при старте контейнера nginx (переменные: API_UPSTREAM).
|
|
# HTTPS терминирует внешний прокси: Caddy из compose.tls.yaml или ваш собственный — см. docs/install-guide.md.
|
|
|
|
# За внешним прокси (Caddy, Traefik, ...) сохраняем исходную схему и IP клиента.
|
|
map $http_x_forwarded_proto $pipu_scheme {
|
|
default $http_x_forwarded_proto;
|
|
'' $scheme;
|
|
}
|
|
|
|
upstream pipu_api {
|
|
server ${API_UPSTREAM};
|
|
keepalive 16;
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
|
|
# Доверяем X-Forwarded-For только от частных сетей (docker, LAN), где стоит прокси.
|
|
set_real_ip_from 10.0.0.0/8;
|
|
set_real_ip_from 172.16.0.0/12;
|
|
set_real_ip_from 192.168.0.0/16;
|
|
real_ip_header X-Forwarded-For;
|
|
real_ip_recursive on;
|
|
|
|
root /usr/share/nginx/html;
|
|
client_max_body_size 16m;
|
|
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
|
|
gzip on;
|
|
gzip_types text/css application/javascript application/json image/svg+xml;
|
|
|
|
location /api/ {
|
|
proxy_pass http://pipu_api;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Connection "";
|
|
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 $pipu_scheme;
|
|
# api берёт IP клиента только из X-Real-IP; остальные заголовки клиент может подделать
|
|
proxy_set_header True-Client-IP "";
|
|
}
|
|
|
|
location = /healthz { proxy_pass http://pipu_api; }
|
|
location = /readyz { proxy_pass http://pipu_api; }
|
|
|
|
# Аудио и обложки отдаёт nginx по заголовку X-Accel-Redirect от api (docs/playback.md).
|
|
location /_internal/library/ { internal; alias /library/; sendfile on; aio threads; }
|
|
location /_internal/cache/ { internal; alias /cache/transcode/; sendfile on; }
|
|
location /_internal/covers/ { internal; alias /cache/covers/; expires 30d; }
|
|
location /_internal/uploads/ { internal; alias /uploads/; sendfile on; }
|
|
|
|
location /assets/ {
|
|
expires 1y;
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
add_header Cache-Control "public, immutable";
|
|
try_files $uri =404;
|
|
}
|
|
|
|
location / {
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
add_header Cache-Control "no-cache";
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
}
|