Files
vizitka-site/deploy/nginx-site.conf
T
aibrashandClaude Sonnet 5.5 6ddece7017
deploy / deploy (push) Successful in 4s
Кнопка «Помахать» с общим счётчиком, домен, шапка
- Главная: тихая кнопка «Помахать» (web/js/wave.js), общий счётчик для всех посетителей
- server/server.mjs: мини-API (/api/waves, /api/wave), счётчик хранится вне репозитория
  (/var/lib/vizitka-site/waves.json), лимит раз в секунду с IP, проверка Origin
- deploy: systemd-сервис vizitka-api, проксирование /api в nginx, setup-server.sh ставит nodejs
- CI: после git pull перезапускает API
- Домен https://me.ibrash.duckdns.org вместо заглушки, исправлен пробел в шапке
- README и заметки обновлены

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 16:55:30 +05:00

68 lines
3.2 KiB
Plaintext

# nginx: статический сайт-визитка. Репозиторий клонирован в /opt/vizitka-site, раздаём его папку web/
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /opt/vizitka-site/web;
index index.html;
# реальный IP посетителя из X-Forwarded-For, если запрос пришёл от прокси из локальной сети (для лимита в API)
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;
set_real_ip_from 127.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# сжатие
gzip on;
gzip_vary on;
gzip_min_length 512;
gzip_types text/css application/javascript application/json image/svg+xml text/plain application/xml;
# заголовки безопасности (строгий CSP: на сайте нет inline-скриптов и стилей, внешних ресурсов нет)
server_tokens off;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
# API кнопки «Помахать» (Node, systemd-сервис vizitka-api), счётчик хранится вне репозитория
location /api/ {
proxy_pass http://127.0.0.1:8787;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Client-IP $remote_addr;
proxy_read_timeout 10s;
client_max_body_size 1k;
}
location / {
try_files $uri $uri/ =404;
}
# кэш: картинки и шрифты надолго, стили и скрипты на час, данные без кэша
location ~* \.(woff2|webp|png|jpe?g|svg|ico)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000" always;
# add_header в location сбрасывает наследуемые, поэтому дублируем безопасные заголовки
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
add_header X-Content-Type-Options "nosniff" always;
}
location ~* \.(css|js)$ {
add_header Cache-Control "public, max-age=3600" always;
add_header X-Content-Type-Options "nosniff" always;
}
location = /config.json {
add_header Cache-Control "no-cache" always;
add_header X-Content-Type-Options "nosniff" always;
}
# скрытые файлы наружу не отдаём
location ~ /\. { deny all; }
error_page 404 /404.html;
location = /404.html { internal; }
}