feat: CI/CD, per-domain HTTPS, backup, config generator
- sites.yml — единый источник истины для всех сайтов - generate-configs.sh — генератор nginx конфигов, certbot domains.txt, .env - nginx: per-domain HTTPS (вместо all-or-nothing switch-config) - certbot: единый renew-all.sh, динамический init (без 5 дублирующих скриптов) - backup: контейнер с pg_dump + rclone (Яндекс.Диск), ежедневно в 3AM - Gitea + Gitea Runner в docker-compose (self-hosted Git + CI/CD) - .gitea/workflows/deploy.yml — CI/CD pipeline: push → авто-деплой - Makefile: generate-configs, reconfig, deploy, backup, restore, gitea, help
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
name: Deploy
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'main_dc/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
run: |
|
||||||
|
cd /home/gaziz/artefacts/tp/main_dc
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Если изменился sites.yml — генерируем конфиги
|
||||||
|
if git diff --name-only HEAD~1 HEAD | grep -q 'main_dc/sites.yml'; then
|
||||||
|
echo "→ sites.yml changed, generating configs..."
|
||||||
|
bash generate-configs.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Авто-детект и пересборка изменённых сервисов
|
||||||
|
echo "→ Detecting changed services..."
|
||||||
|
CHANGED=$(git diff --name-only HEAD~1 HEAD | grep -oP 'main_dc/\K[^/]+' | sort -u)
|
||||||
|
for svc in $CHANGED; do
|
||||||
|
svc_name="$svc"
|
||||||
|
# маппинг директорий на имена compose-сервисов
|
||||||
|
case "$svc" in
|
||||||
|
BB) svc_name="api_bb" ;;
|
||||||
|
valitovgaziz) svc_name="valitovgaziz" ;;
|
||||||
|
nginx|certbot|backup|gitea) svc_name="$svc" ;;
|
||||||
|
api_bb|api_yal|analytics|db) svc_name="$svc" ;;
|
||||||
|
yalarba) svc_name="yalarba" ;;
|
||||||
|
*) svc_name="" ;;
|
||||||
|
esac
|
||||||
|
if [ -n "$svc_name" ] && grep -q "^ $svc_name:" docker-compose.yml; then
|
||||||
|
echo " → Rebuilding $svc_name..."
|
||||||
|
make stop_$svc_name build_$svc_name start_$svc_name || \
|
||||||
|
make stop_$svc build_$svc start_$svc 2>/dev/null || \
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Nginx всегда перезапускаем если изменились конфиги
|
||||||
|
if echo "$CHANGED" | grep -q 'nginx\|sites.yml'; then
|
||||||
|
echo " → Reloading nginx..."
|
||||||
|
docker compose exec -T nginx nginx -s reload 2>/dev/null || \
|
||||||
|
docker compose restart nginx
|
||||||
|
fi
|
||||||
+6
-7
@@ -1,12 +1,11 @@
|
|||||||
#CERTBOT NGINX VARIABLES
|
|
||||||
|
|
||||||
EMAIL=valitovgaziz@yandex.ru
|
EMAIL=valitovgaziz@yandex.ru
|
||||||
DOMAINS_yalarba=yalarba.ru,www.yalarba.ru
|
#CERTBOT NGINX VARIABLES — авто-сгенерировано, не редактировать вручную
|
||||||
DOMAINS_valitovgaziz=valitovgaziz.ru,www.valitovgaziz.ru
|
|
||||||
DOMAINS_easysite102=easysite102.ru,www.easysite102.ru
|
|
||||||
DOMAINS_begushiybashkir=xn--80abahjtcfl5d0a8di.xn--p1ai,www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
|
||||||
DOMAINS_begushiybashkir_latin=begushiybashkir.ru,www.begushiybashkir.ru
|
|
||||||
ALL_DOMAINS=yalarba.ru,www.yalarba.ru,valitovgaziz.ru,www.valitovgaziz.ru,easysite102.ru,www.easysite102.ru,begushiybashkir.ru,www.begushiybashkir.ru,xn--80abahjtcfl5d0a8di.xn--p1ai,www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
ALL_DOMAINS=yalarba.ru,www.yalarba.ru,valitovgaziz.ru,www.valitovgaziz.ru,easysite102.ru,www.easysite102.ru,begushiybashkir.ru,www.begushiybashkir.ru,xn--80abahjtcfl5d0a8di.xn--p1ai,www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
DOMAINS_begushiybashkir=begushiybashkir.ru,www.begushiybashkir.ru
|
||||||
|
DOMAINS_begushiybashkir_idn=xn--80abahjtcfl5d0a8di.xn--p1ai,www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
DOMAINS_easysite102=easysite102.ru,www.easysite102.ru
|
||||||
|
DOMAINS_valitovgaziz=valitovgaziz.ru,www.valitovgaziz.ru
|
||||||
|
DOMAINS_yalarba=yalarba.ru,www.yalarba.ru
|
||||||
|
|
||||||
# keycloak
|
# keycloak
|
||||||
KEYCLOAK_ADMIN_PASSWORD=your_secure_password
|
KEYCLOAK_ADMIN_PASSWORD=your_secure_password
|
||||||
|
|||||||
+118
-1
@@ -237,4 +237,121 @@ start_yalarba:
|
|||||||
docker compose up yalarba -d
|
docker compose up yalarba -d
|
||||||
|
|
||||||
# Полный цикл обновления yalarba-nuxt
|
# Полный цикл обновления yalarba-nuxt
|
||||||
yalarba: stop_yalarba git build_yalarba start_yalarba wn
|
yalarba: stop_yalarba git build_yalarba start_yalarba wn
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════
|
||||||
|
# НОВЫЕ ЦЕЛИ: generate-configs, deploy, backup
|
||||||
|
# ═══════════════════════════════════════════════
|
||||||
|
|
||||||
|
# Генерация конфигов из sites.yml
|
||||||
|
generate-configs:
|
||||||
|
bash generate-configs.sh
|
||||||
|
|
||||||
|
# Генерация + рестарт nginx
|
||||||
|
reconfig: generate-configs
|
||||||
|
docker compose restart nginx
|
||||||
|
$(MAKE) wn
|
||||||
|
|
||||||
|
# Авто-детект изменённых сервисов и деплой только их
|
||||||
|
deploy: git
|
||||||
|
@echo "=== Detecting changes ==="
|
||||||
|
@CHANGED=$$(git diff --name-only HEAD~1 HEAD | grep -oP 'main_dc/\K[^/]+' | sort -u); \
|
||||||
|
for svc in $$CHANGED; do \
|
||||||
|
case "$$svc" in \
|
||||||
|
BB) name="api_bb" ;; \
|
||||||
|
certbot) name="certbot" ;; \
|
||||||
|
backup) name="backup" ;; \
|
||||||
|
gitea) name="gitea" ;; \
|
||||||
|
*) name="$$svc" ;; \
|
||||||
|
esac; \
|
||||||
|
if grep -q "^ $$name:" docker-compose.yml 2>/dev/null; then \
|
||||||
|
echo " → Rebuilding $$name..."; \
|
||||||
|
$(MAKE) stop_$$name build_$$name start_$$name 2>/dev/null || \
|
||||||
|
$(MAKE) stop_$$svc build_$$svc start_$$svc 2>/dev/null || true; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
if echo "$$CHANGED" | grep -q 'sites.yml\|nginx'; then \
|
||||||
|
echo " → Regenerating configs..."; \
|
||||||
|
bash generate-configs.sh; \
|
||||||
|
docker compose restart nginx; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ручной запуск бэкапа
|
||||||
|
backup:
|
||||||
|
docker compose exec backup /opt/backup.sh
|
||||||
|
|
||||||
|
# Ручной запуск бэкапа (разовый контейнер)
|
||||||
|
backup-run:
|
||||||
|
docker compose run --rm backup /opt/backup.sh
|
||||||
|
|
||||||
|
# Восстановление из бэкапа: make restore [DATE=2026-06-11]
|
||||||
|
restore:
|
||||||
|
docker compose run --rm backup /opt/restore.sh $(DATE)
|
||||||
|
|
||||||
|
# Gitea — полный цикл обновления
|
||||||
|
gitea: stop_gitea git build_gitea start_gitea wn
|
||||||
|
|
||||||
|
stop_gitea:
|
||||||
|
docker compose down gitea
|
||||||
|
|
||||||
|
build_gitea:
|
||||||
|
docker compose build gitea --no-cache
|
||||||
|
|
||||||
|
start_gitea:
|
||||||
|
docker compose up gitea -d
|
||||||
|
|
||||||
|
# Gitea Runner — полный цикл
|
||||||
|
gitea-runner: stop_gitea-runner git build_gitea-runner start_gitea-runner wn
|
||||||
|
|
||||||
|
stop_gitea-runner:
|
||||||
|
docker compose down gitea-runner
|
||||||
|
|
||||||
|
build_gitea-runner:
|
||||||
|
docker compose build gitea-runner --no-cache
|
||||||
|
|
||||||
|
start_gitea-runner:
|
||||||
|
docker compose up gitea-runner -d
|
||||||
|
|
||||||
|
# Gitea first-time setup helper
|
||||||
|
gitea-setup:
|
||||||
|
@echo "=== Gitea Setup ==="
|
||||||
|
@echo "1. Open http://94.41.23.97:3001 in browser"
|
||||||
|
@echo "2. Complete initial setup (DB: SQLite3 is fine)"
|
||||||
|
@echo "3. Create admin user"
|
||||||
|
@echo "4. Create new repository 'tp' and push:"
|
||||||
|
@echo " git remote add gitea http://94.41.23.97:3001/USER/tp.git"
|
||||||
|
@echo " git push -u gitea main"
|
||||||
|
@echo "5. Register runner:"
|
||||||
|
@echo " Settings → Actions → Runners → Create Token"
|
||||||
|
@echo " Update GITEA_RUNNER_REGISTRATION_TOKEN in docker-compose.yml"
|
||||||
|
@echo " Then: docker compose up -d gitea-runner"
|
||||||
|
@echo "6. Add secrets in repo Settings → Actions → Secrets:"
|
||||||
|
@echo " (none needed — runner runs locally)"
|
||||||
|
|
||||||
|
# Показать все доступные цели
|
||||||
|
help:
|
||||||
|
@echo "=== Make targets ==="
|
||||||
|
@echo ""
|
||||||
|
@echo "Site management:"
|
||||||
|
@echo " generate-configs — generate nginx configs from sites.yml"
|
||||||
|
@echo " reconfig — generate configs + restart nginx"
|
||||||
|
@echo ""
|
||||||
|
@echo "Deploy:"
|
||||||
|
@echo " all — full cycle all services"
|
||||||
|
@echo " deploy — auto-detect changes, rebuild only changed"
|
||||||
|
@echo " <service> — full cycle for one service"
|
||||||
|
@echo ""
|
||||||
|
@echo "Backup:"
|
||||||
|
@echo " backup — run backup via running container"
|
||||||
|
@echo " backup-run — run backup in one-shot container"
|
||||||
|
@echo " restore DATE=... — restore from backup"
|
||||||
|
@echo ""
|
||||||
|
@echo "Gitea:"
|
||||||
|
@echo " gitea — full cycle Gitea"
|
||||||
|
@echo " gitea-runner — full cycle Runner"
|
||||||
|
@echo " gitea-setup — first-time setup instructions"
|
||||||
|
@echo ""
|
||||||
|
@echo "Monitoring:"
|
||||||
|
@echo " wn — watch docker ps"
|
||||||
|
@echo " logs_<service> — logs for a service"
|
||||||
|
@echo " bb_db — psql into bb_db"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
RUN apk add --no-cache postgresql-client rclone bash curl
|
||||||
|
|
||||||
|
COPY scripts/ /opt/
|
||||||
|
RUN chmod +x /opt/*.sh
|
||||||
|
|
||||||
|
# crontab для расписания бэкапов
|
||||||
|
RUN echo "$BACKUP_TIME /opt/backup.sh > /proc/1/fd/1 2>&1" > /etc/crontabs/root
|
||||||
|
|
||||||
|
CMD ["crond", "-f", "-l", "2"]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Пример конфига rclone для Яндекс.Диска
|
||||||
|
# Скопируй в backup/rclone.conf и заполни токен
|
||||||
|
# Инструкция: https://rclone.org/yandex/
|
||||||
|
[yadisk]
|
||||||
|
type = yandex
|
||||||
|
client_id =
|
||||||
|
client_secret =
|
||||||
|
token = {"access_token":"...","token_type":"...","expiry":"..."}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# backup.sh — ежедневный бэкап: pg_dump + файлы → локально + Яндекс.Диск
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BACKUP_DIR="/backups/$(date +%Y-%m-%d)"
|
||||||
|
RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
|
||||||
|
DB_NAMES="${DB_NAMES:-mydb}"
|
||||||
|
TIMESTAMP=$(date +%H%M%S)
|
||||||
|
|
||||||
|
mkdir -p "$BACKUP_DIR/db" "$BACKUP_DIR/files"
|
||||||
|
|
||||||
|
echo "=== Backup $TIMESTAMP ==="
|
||||||
|
|
||||||
|
# 1. Дампы всех БД
|
||||||
|
IFS=',' read -ra databases <<< "$DB_NAMES"
|
||||||
|
for db in "${databases[@]}"; do
|
||||||
|
db=$(echo "$db" | xargs) # trim
|
||||||
|
echo "→ Dumping database: $db"
|
||||||
|
PGPASSWORD="$DB_PASSWORD" pg_dump -h "$DB_HOST" -p "${DB_PORT:-5432}" \
|
||||||
|
-U "$DB_USER" -d "$db" --format=custom \
|
||||||
|
-f "$BACKUP_DIR/db/${db}-${TIMESTAMP}.dump"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 2. Архив файлов
|
||||||
|
echo "→ Archiving files..."
|
||||||
|
tar -czf "$BACKUP_DIR/files/certbot-${TIMESTAMP}.tar.gz" -C /data/certbot . 2>/dev/null || true
|
||||||
|
tar -czf "$BACKUP_DIR/files/uploads-${TIMESTAMP}.tar.gz" -C /data/uploads . 2>/dev/null || true
|
||||||
|
tar -czf "$BACKUP_DIR/files/analytics-${TIMESTAMP}.tar.gz" -C /data/analytics . 2>/dev/null || true
|
||||||
|
|
||||||
|
# 3. Создаём symlink latest
|
||||||
|
rm -f /backups/latest
|
||||||
|
ln -sf "$BACKUP_DIR" /backups/latest
|
||||||
|
|
||||||
|
# 4. Ротация — удаляем старше RETENTION_DAYS
|
||||||
|
find /backups -maxdepth 1 -type d -name '2*' -mtime "+$RETENTION_DAYS" -exec rm -rf {} \; 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "✓ Local backup saved to $BACKUP_DIR"
|
||||||
|
|
||||||
|
# 5. Синхронизация с Яндекс.Диск
|
||||||
|
if command -v rclone > /dev/null 2>&1 && [ -n "${RCLONE_REMOTE:-}" ]; then
|
||||||
|
echo "→ Syncing to cloud: $RCLONE_REMOTE"
|
||||||
|
rclone sync /backups "$RCLONE_REMOTE" --progress 2>&1 || \
|
||||||
|
echo " ⚠ Cloud sync failed (check rclone config)"
|
||||||
|
echo "✓ Cloud sync complete"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Backup finished ==="
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# restore.sh — восстановление из бэкапа
|
||||||
|
# Использование: docker compose run --rm backup /opt/restore.sh [дата]
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BACKUP_DATE="${1:-latest}"
|
||||||
|
BACKUP_DIR="/backups/$BACKUP_DATE"
|
||||||
|
|
||||||
|
if [ ! -d "$BACKUP_DIR" ]; then
|
||||||
|
echo "Ошибка: бэкап $BACKUP_DIR не найден"
|
||||||
|
echo "Доступные бэкапы:"
|
||||||
|
ls -d /backups/2* 2>/dev/null || echo " (нет бэкапов)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Restore from $BACKUP_DIR ==="
|
||||||
|
|
||||||
|
# Восстановить БД
|
||||||
|
if [ -d "$BACKUP_DIR/db" ]; then
|
||||||
|
for dump in "$BACKUP_DIR/db"/*.dump; do
|
||||||
|
[ -f "$dump" ] || continue
|
||||||
|
db=$(basename "$dump" | sed 's/-.*//')
|
||||||
|
echo "→ Restoring database: $db"
|
||||||
|
PGPASSWORD="$DB_PASSWORD" pg_restore -h "$DB_HOST" -p "${DB_PORT:-5432}" \
|
||||||
|
-U "$DB_USER" -d "$db" --clean --if-exists "$dump" || \
|
||||||
|
echo " ⚠ Restore of $db had warnings (non-fatal)"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Распаковать файлы
|
||||||
|
if [ -d "$BACKUP_DIR/files" ]; then
|
||||||
|
for archive in "$BACKUP_DIR/files"/*.tar.gz; do
|
||||||
|
[ -f "$archive" ] || continue
|
||||||
|
name=$(basename "$archive" | sed 's/-.*//')
|
||||||
|
target="/data/$name"
|
||||||
|
echo "→ Extracting $name to $target"
|
||||||
|
mkdir -p "$target"
|
||||||
|
tar -xzf "$archive" -C "$target" || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Restore completed ==="
|
||||||
|
echo "При необходимости перезапусти сервисы: docker compose restart"
|
||||||
@@ -1,20 +1,10 @@
|
|||||||
FROM certbot/certbot
|
FROM certbot/certbot
|
||||||
|
|
||||||
# Проверяем наличие crond (используем command -v вместо which)
|
RUN apk add --no-cache cronie docker-cli
|
||||||
RUN if ! command -v crond > /dev/null 2>&1; then \
|
|
||||||
echo "Cron not found. Installing cronie..."; \
|
|
||||||
apk add --no-cache cronie; \
|
|
||||||
else \
|
|
||||||
echo "Cron is already installed."; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Создаем директории для конфигов
|
|
||||||
RUN mkdir -p /etc/letsencrypt/config
|
RUN mkdir -p /etc/letsencrypt/config
|
||||||
|
|
||||||
# Копируем конфигурационные файлы
|
|
||||||
COPY scripts/ /opt/
|
COPY scripts/ /opt/
|
||||||
|
RUN chmod +x /opt/*.sh
|
||||||
|
|
||||||
# Устанавливаем права
|
ENTRYPOINT ["/opt/init-certbot.sh"]
|
||||||
RUN chmod +x /opt/*
|
|
||||||
|
|
||||||
ENTRYPOINT ["/opt/init-certbot.sh"]
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
yalarba.ru
|
||||||
|
www.yalarba.ru
|
||||||
|
valitovgaziz.ru
|
||||||
|
www.valitovgaziz.ru
|
||||||
|
easysite102.ru
|
||||||
|
www.easysite102.ru
|
||||||
|
begushiybashkir.ru
|
||||||
|
www.begushiybashkir.ru
|
||||||
|
xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
@@ -1 +1 @@
|
|||||||
0 0 * * * root /opt/checkRenewCerts.sh > /proc/1/fd/1 2>&1
|
0 0 * * * /opt/renew-all.sh > /proc/1/fd/1 2>&1
|
||||||
|
|||||||
@@ -1,69 +1,32 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# init-certbot.sh — точка входа certbot контейнера
|
||||||
|
set -e
|
||||||
|
|
||||||
# Проверяем наличие сертификатов для yalarba.ru
|
echo "=== Certbot init ==="
|
||||||
if [ ! -d "/etc/letsencrypt/live/yalarba.ru" ]; then
|
|
||||||
echo "Получаем новые сертификаты yalarba.ru ..."
|
|
||||||
certbot certonly --webroot \
|
|
||||||
--config /etc/letsencrypt/config/certbot.ini \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d ${DOMAINS_yalarba}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "сertificates for ${DOMAINS_yalarba} is ready"
|
# Получаем сертификаты для всех доменов из DOMAINS_* env
|
||||||
|
env | grep '^DOMAINS_' | grep -v '^ALL_DOMAINS' | sort | while IFS='=' read -r var_name domains; do
|
||||||
|
primary_domain=$(echo "$domains" | cut -d, -f1)
|
||||||
|
|
||||||
# Проверяем наличие сертификатов для valitovgaziz.ru
|
if [ ! -d "/etc/letsencrypt/live/$primary_domain" ]; then
|
||||||
if [ ! -d "/etc/letsencrypt/live/valitovgaziz.ru" ]; then
|
echo "→ Получаем сертификат для $primary_domain"
|
||||||
echo "Получаем новые сертификаты valitovgaziz ..."
|
certbot certonly --webroot \
|
||||||
certbot certonly --webroot \
|
--config /etc/letsencrypt/config/certbot.ini \
|
||||||
--config /etc/letsencrypt/config/certbot.ini \
|
-w /var/www/certbot \
|
||||||
-w /var/www/certbot \
|
-d "$domains"
|
||||||
-d ${DOMAINS_valitovgaziz}
|
echo "✓ Сертификат для $primary_domain получен"
|
||||||
fi
|
else
|
||||||
|
echo "✓ Сертификат для $primary_domain уже существует"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo "сertificates for ${DOMAINS_valitovgaziz} is ready"
|
# Настраиваем cron для ежедневного обновления
|
||||||
|
|
||||||
# Проверяем наличие сертификатов для easysite102.ru
|
|
||||||
if [ ! -d "/etc/letsencrypt/live/easysite102.ru" ]; then
|
|
||||||
echo "Получаем новые сертификаты easysite102.ru ..."
|
|
||||||
certbot certonly --webroot \
|
|
||||||
--config /etc/letsencrypt/config/certbot.ini \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d ${DOMAINS_easysite102}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "сertificates for ${DOMAINS_easysite102} is ready"
|
|
||||||
|
|
||||||
# Проверяем наличие сертификатов для бегущийбашкир.рф
|
|
||||||
if [ ! -d "/etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai" ]; then
|
|
||||||
echo "Получаем новые сертификаты xn--80abahjtcfl5d0a8di.xn--p1ai(бегущийбашкир.рф) ..."
|
|
||||||
certbot certonly --webroot \
|
|
||||||
--config /etc/letsencrypt/config/certbot.ini \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d ${DOMAINS_begushiybashkir}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "сertificates for ${DOMAINS_begushiybashkir} is ready"
|
|
||||||
|
|
||||||
# Проверяем наличие сертификатов для begushiybashkir.ru
|
|
||||||
if [ ! -d "/etc/letsencrypt/live/begushiybashkir.ru" ]; then
|
|
||||||
echo "Получаем новые сертификаты begushiybashkir.ru ..."
|
|
||||||
certbot certonly --webroot \
|
|
||||||
--config /etc/letsencrypt/config/certbot.ini \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d ${DOMAINS_begushiybashkir_latin}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "сertificates for ${DOMAINS_begushiybashkir_latin} is ready"
|
|
||||||
|
|
||||||
set -e # Завершаем работу, если любая команда вернёт ошибку
|
|
||||||
|
|
||||||
# Активируем сервис cron
|
|
||||||
/usr/sbin/crond -f &
|
|
||||||
crond -f &
|
|
||||||
|
|
||||||
# Копируем нашу собственную crontab таблицу
|
|
||||||
cp /opt/crontab.txt /etc/crontabs/root
|
cp /opt/crontab.txt /etc/crontabs/root
|
||||||
|
|
||||||
# Оставляем контейнер открытым
|
# Запускаем crond в фоне
|
||||||
tail -f /dev/null
|
crond -b
|
||||||
|
|
||||||
|
echo "=== Init завершён, контейнер работает ==="
|
||||||
|
|
||||||
|
# Держим контейнер живым
|
||||||
|
tail -f /dev/null
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# renew-all.sh — единый скрипт обновления всех сертификатов
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=== Certbot renewal ==="
|
||||||
|
|
||||||
|
# Обновляем все сертификаты
|
||||||
|
certbot renew --webroot -w /var/www/certbot
|
||||||
|
|
||||||
|
# Перезагружаем nginx чтобы он подхватил новые сертификаты
|
||||||
|
if command -v docker > /dev/null 2>&1; then
|
||||||
|
echo "→ Перезагружаем nginx..."
|
||||||
|
docker exec nginx nginx -s reload 2>/dev/null || \
|
||||||
|
echo " (nginx reload не удался, возможно контейнер не запущен)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Renewal завершён ==="
|
||||||
@@ -10,19 +10,15 @@ services:
|
|||||||
- ./certbot/config:/etc/letsencrypt/config
|
- ./certbot/config:/etc/letsencrypt/config
|
||||||
- certbot_data:/etc/letsencrypt
|
- certbot_data:/etc/letsencrypt
|
||||||
- certbot_www:/var/www/certbot
|
- certbot_www:/var/www/certbot
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
- EMAIL=${EMAIL}
|
- EMAIL=${EMAIL}
|
||||||
- DOMAINS=${ALL_DOMAINS}
|
|
||||||
- STAGING=0
|
- STAGING=0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test: ["CMD-SHELL", "ls /etc/letsencrypt/live/*/fullchain.pem 2>/dev/null | head -1 | xargs test -f || exit 1"]
|
||||||
[
|
|
||||||
"CMD-SHELL",
|
|
||||||
"test -f /etc/letsencrypt/live/$$(echo $${DOMAINS} | cut -d',' -f1)/fullchain.pem || exit 1",
|
|
||||||
]
|
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -45,6 +41,7 @@ services:
|
|||||||
- ./stubSite:/usr/share/nginx/stub/html
|
- ./stubSite:/usr/share/nginx/stub/html
|
||||||
- ./BB/bbvue/dist:/usr/share/nginx/begushiybashkir/html
|
- ./BB/bbvue/dist:/usr/share/nginx/begushiybashkir/html
|
||||||
- analytics_logs:/var/log/analytics:ro
|
- analytics_logs:/var/log/analytics:ro
|
||||||
|
- ./nginx/conf.available:/etc/nginx/conf.available:ro
|
||||||
networks:
|
networks:
|
||||||
- web-network
|
- web-network
|
||||||
- internal
|
- internal
|
||||||
@@ -52,8 +49,6 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
easysite:
|
easysite:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
certbot:
|
|
||||||
condition: service_healthy
|
|
||||||
api_bb:
|
api_bb:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
analytics:
|
analytics:
|
||||||
@@ -254,6 +249,81 @@ services:
|
|||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# Gitea — self-hosted Git сервер + CI/CD
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3001:3000"
|
||||||
|
- "2222:22"
|
||||||
|
volumes:
|
||||||
|
- gitea_data:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- GITEA__server__DOMAIN=git.yalarba.ru
|
||||||
|
- GITEA__server__SSH_DOMAIN=94.41.23.97
|
||||||
|
- GITEA__server__ROOT_URL=https://git.yalarba.ru
|
||||||
|
networks:
|
||||||
|
- web-network
|
||||||
|
- internal
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--spider", "http://localhost:3000"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
gitea-runner:
|
||||||
|
image: gitea/act_runner:latest
|
||||||
|
container_name: gitea-runner
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /home/gaziz/artefacts/tp:/home/gaziz/artefacts/tp
|
||||||
|
- gitea_runner:/data
|
||||||
|
environment:
|
||||||
|
- GITEA_INSTANCE_URL=http://gitea:3000
|
||||||
|
- GITEA_RUNNER_REGISTRATION_TOKEN=
|
||||||
|
depends_on:
|
||||||
|
gitea:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# Backup — ежедневные бэкапы БД + файлов → локально + Яндекс.Диск
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
backup:
|
||||||
|
build:
|
||||||
|
context: ./backup
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: backup
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /var/backups/tp:/backups
|
||||||
|
- certbot_data:/data/certbot:ro
|
||||||
|
- api_bb_uploads:/data/uploads:ro
|
||||||
|
- analytics_data:/data/analytics:ro
|
||||||
|
environment:
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_USER: postgres
|
||||||
|
DB_PASSWORD: postgres
|
||||||
|
DB_NAMES: mydb,bb_db
|
||||||
|
RCLONE_REMOTE: "yadisk:tp-backups"
|
||||||
|
BACKUP_RETENTION_DAYS: 7
|
||||||
|
BACKUP_TIME: "0 3 * * *"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
certbot_data: # volume для данных Certbot
|
certbot_data: # volume для данных Certbot
|
||||||
certbot_www: # volume для данных Certbot
|
certbot_www: # volume для данных Certbot
|
||||||
@@ -261,6 +331,8 @@ volumes:
|
|||||||
api_bb_uploads: # Volume для загружаемых файлов бегущий башкир
|
api_bb_uploads: # Volume для загружаемых файлов бегущий башкир
|
||||||
analytics_logs: # Volume для логов аналитики
|
analytics_logs: # Volume для логов аналитики
|
||||||
analytics_data: # Volume для данных аналитики
|
analytics_data: # Volume для данных аналитики
|
||||||
|
gitea_data: # Volume для Gitea
|
||||||
|
gitea_runner: # Volume для Gitea Runner
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
web-network:
|
web-network:
|
||||||
|
|||||||
Executable
+474
@@ -0,0 +1,474 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# generate-configs.sh — генератор конфигов из sites.yml
|
||||||
|
# Генерирует: nginx-http.conf, nginx-ssl.conf, certbot/domains.txt, обновляет .env
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
SITES_YML="$DIR/sites.yml"
|
||||||
|
NGINX_DIR="$DIR/nginx"
|
||||||
|
ENV_FILE="$DIR/.env"
|
||||||
|
|
||||||
|
if [ ! -f "$SITES_YML" ]; then
|
||||||
|
echo "Ошибка: $SITES_YML не найден"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Генерация конфигов из sites.yml ==="
|
||||||
|
|
||||||
|
# Используем python3 с quoted heredoc — предотвращает интерпретацию $ переменных bash
|
||||||
|
python3 - "$DIR" "$NGINX_DIR" "$ENV_FILE" << 'PYEOF'
|
||||||
|
import yaml, os, sys
|
||||||
|
|
||||||
|
BASE_DIR = sys.argv[1]
|
||||||
|
NGINX_DIR = sys.argv[2]
|
||||||
|
ENV_FILE = sys.argv[3]
|
||||||
|
SITES_YML = os.path.join(BASE_DIR, "sites.yml")
|
||||||
|
|
||||||
|
with open(SITES_YML) as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
|
||||||
|
sites = data.get("sites", {})
|
||||||
|
if not sites:
|
||||||
|
print("Ошибка: в sites.yml нет сайтов")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# собираем данные
|
||||||
|
all_domains = []
|
||||||
|
env_domains = {}
|
||||||
|
site_list = []
|
||||||
|
|
||||||
|
for name, cfg in sites.items():
|
||||||
|
domain = cfg["domain"]
|
||||||
|
aliases = cfg.get("aliases", [])
|
||||||
|
|
||||||
|
all_domains.append(domain)
|
||||||
|
all_domains.extend(aliases)
|
||||||
|
|
||||||
|
env_key = f"DOMAINS_{name}"
|
||||||
|
env_val = ",".join([domain] + aliases)
|
||||||
|
env_domains[env_key] = env_val
|
||||||
|
|
||||||
|
site_list.append({
|
||||||
|
"name": name,
|
||||||
|
"domain": domain,
|
||||||
|
"aliases": aliases,
|
||||||
|
"type": cfg.get("type", "upstream"),
|
||||||
|
"upstream": cfg.get("upstream", ""),
|
||||||
|
"root": cfg.get("root", ""),
|
||||||
|
"api": cfg.get("api", {}),
|
||||||
|
})
|
||||||
|
|
||||||
|
env_domains["ALL_DOMAINS"] = ",".join(all_domains)
|
||||||
|
|
||||||
|
def all_server_names():
|
||||||
|
"""Возвращает строку со всеми доменами и алиасами через пробел"""
|
||||||
|
parts = []
|
||||||
|
for s in site_list:
|
||||||
|
parts.append(s["domain"])
|
||||||
|
parts.extend(s["aliases"])
|
||||||
|
return " ".join(parts)
|
||||||
|
|
||||||
|
def all_server_names_multiline():
|
||||||
|
"""Возвращает строку с переносами для nginx server_name"""
|
||||||
|
lines = []
|
||||||
|
for s in site_list:
|
||||||
|
lines.append(s["domain"])
|
||||||
|
for a in s["aliases"]:
|
||||||
|
lines.append(a)
|
||||||
|
return " \\\n ".join(lines)
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# 2. Генерация nginx-http.conf
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
http_conf = f"""# Автоматически сгенерировано generate-configs.sh — не редактировать вручную
|
||||||
|
# HTTP-only конфигурация (работает когда нет сертификатов)
|
||||||
|
|
||||||
|
server {{
|
||||||
|
listen 80;
|
||||||
|
server_name {all_server_names_multiline()};
|
||||||
|
|
||||||
|
location / {{
|
||||||
|
root /usr/share/nginx/stub/html;
|
||||||
|
index index.html;
|
||||||
|
}}
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {{
|
||||||
|
root /var/www/certbot;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
# Блок для HTTPS → HTTP редиректа (порт 443)
|
||||||
|
server {{
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name {all_server_names_multiline()};
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/dummy.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/dummy.key;
|
||||||
|
|
||||||
|
return 301 http://$host$request_uri;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
|
||||||
|
http_conf_path = os.path.join(NGINX_DIR, "nginx-http.conf")
|
||||||
|
with open(http_conf_path, "w") as f:
|
||||||
|
f.write(http_conf.lstrip())
|
||||||
|
print(f" ✓ {http_conf_path}")
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# 3. Генерация nginx-ssl.conf
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
ssl_server_blocks = []
|
||||||
|
|
||||||
|
for s in site_list:
|
||||||
|
server_names = " ".join([s["domain"]] + s["aliases"])
|
||||||
|
|
||||||
|
block = f"""
|
||||||
|
server {{
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name {server_names};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{s["domain"]}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{s["domain"]}/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
"""
|
||||||
|
if s["type"] == "upstream":
|
||||||
|
block += f"""
|
||||||
|
location / {{
|
||||||
|
proxy_pass {s["upstream"]};
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
elif s["type"] == "static":
|
||||||
|
block += f"""
|
||||||
|
location / {{
|
||||||
|
root {s["root"]};
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
# API routes
|
||||||
|
for path, target in s["api"].items():
|
||||||
|
cors_block = ""
|
||||||
|
if "/api/" in path:
|
||||||
|
cors_block = """
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
block += f"""
|
||||||
|
location {path} {{
|
||||||
|
proxy_pass {target};
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
{cors_block}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
if s["type"] == "static":
|
||||||
|
block += f"""
|
||||||
|
location /uploads/ {{
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
block += "}"
|
||||||
|
ssl_server_blocks.append(block)
|
||||||
|
|
||||||
|
ssl_conf = f"""# Автоматически сгенерировано generate-configs.sh — не редактировать вручную
|
||||||
|
# Полная HTTPS конфигурация
|
||||||
|
|
||||||
|
# --- HTTP → HTTPS редирект ---
|
||||||
|
server {{
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name {all_server_names()};
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {{
|
||||||
|
root /var/www/certbot;
|
||||||
|
}}
|
||||||
|
|
||||||
|
location /uploads/ {{
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}}
|
||||||
|
|
||||||
|
location / {{
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
# --- HTTPS серверные блоки ---
|
||||||
|
{''.join(ssl_server_blocks)}
|
||||||
|
"""
|
||||||
|
|
||||||
|
ssl_conf_path = os.path.join(NGINX_DIR, "nginx-ssl.conf")
|
||||||
|
with open(ssl_conf_path, "w") as f:
|
||||||
|
f.write(ssl_conf.lstrip())
|
||||||
|
print(f" ✓ {ssl_conf_path}")
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# 4. Генерация per-domain конфигов (conf.available/)
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
CONF_AVAILABLE = os.path.join(NGINX_DIR, "conf.available")
|
||||||
|
os.makedirs(CONF_AVAILABLE, exist_ok=True)
|
||||||
|
|
||||||
|
# 00-http.conf — базовый HTTP catch-all (всегда активен)
|
||||||
|
base_http = f"""# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {{
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {{
|
||||||
|
root /usr/share/nginx/stub/html;
|
||||||
|
index index.html;
|
||||||
|
}}
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {{
|
||||||
|
root /var/www/certbot;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
path = os.path.join(CONF_AVAILABLE, "00-http.conf")
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.write(base_http.lstrip())
|
||||||
|
print(f" ✓ conf.available/00-http.conf")
|
||||||
|
|
||||||
|
# per-domain: SSL + HTTP fallback
|
||||||
|
ORDER = ["10", "20", "30", "40", "50", "60", "70", "80", "90"]
|
||||||
|
for idx, s in enumerate(site_list):
|
||||||
|
prefix = ORDER[idx] if idx < len(ORDER) else f"{90 + idx}"
|
||||||
|
safe_name = s["name"]
|
||||||
|
server_names = " ".join([s["domain"]] + s["aliases"])
|
||||||
|
|
||||||
|
# --- SSL variant ---
|
||||||
|
ssl_block = f"""# CERT_DOMAIN={s["domain"]}
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {{
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name {server_names};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{s["domain"]}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{s["domain"]}/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
"""
|
||||||
|
if s["type"] == "upstream":
|
||||||
|
ssl_block += f"""
|
||||||
|
location / {{
|
||||||
|
proxy_pass {s["upstream"]};
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
elif s["type"] == "static":
|
||||||
|
ssl_block += f"""
|
||||||
|
location / {{
|
||||||
|
root {s["root"]};
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
for path, target in s["api"].items():
|
||||||
|
cors = ""
|
||||||
|
if "/api/" in path:
|
||||||
|
cors = """
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
ssl_block += f"""
|
||||||
|
location {path} {{
|
||||||
|
proxy_pass {target};
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
{cors}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
if s["type"] == "static":
|
||||||
|
ssl_block += f"""
|
||||||
|
location /uploads/ {{
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
ssl_block += "}"
|
||||||
|
|
||||||
|
ssl_path = os.path.join(CONF_AVAILABLE, f"{prefix}-{safe_name}.ssl.conf")
|
||||||
|
with open(ssl_path, "w") as f:
|
||||||
|
f.write(ssl_block.lstrip())
|
||||||
|
|
||||||
|
# --- HTTP fallback variant ---
|
||||||
|
http_block = f"""# HTTP fallback for {s["domain"]} (no SSL cert)
|
||||||
|
server {{
|
||||||
|
listen 80;
|
||||||
|
server_name {server_names};
|
||||||
|
"""
|
||||||
|
if s["type"] == "upstream":
|
||||||
|
http_block += f"""
|
||||||
|
location / {{
|
||||||
|
proxy_pass {s["upstream"]};
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
elif s["type"] == "static":
|
||||||
|
http_block += f"""
|
||||||
|
location / {{
|
||||||
|
root {s["root"]};
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
for path, target in s["api"].items():
|
||||||
|
cors = ""
|
||||||
|
if "/api/" in path:
|
||||||
|
cors = """
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
http_block += f"""
|
||||||
|
location {path} {{
|
||||||
|
proxy_pass {target};
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
{cors}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
if s["type"] == "static":
|
||||||
|
http_block += f"""
|
||||||
|
location /uploads/ {{
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
http_block += "}"
|
||||||
|
|
||||||
|
http_path = os.path.join(CONF_AVAILABLE, f"{prefix}-{safe_name}.http.conf")
|
||||||
|
with open(http_path, "w") as f:
|
||||||
|
f.write(http_block.lstrip())
|
||||||
|
|
||||||
|
print(f" ✓ conf.available/{prefix}-{safe_name}.ssl.conf + .http.conf")
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# 5. Генерация certbot/domains.txt
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
domains_txt_path = os.path.join(BASE_DIR, "certbot", "domains.txt")
|
||||||
|
with open(domains_txt_path, "w") as f:
|
||||||
|
for d in all_domains:
|
||||||
|
f.write(d + "\n")
|
||||||
|
print(f" ✓ {domains_txt_path}")
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# 6. Обновление .env
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
if os.path.exists(ENV_FILE):
|
||||||
|
with open(ENV_FILE) as f:
|
||||||
|
env_lines = f.readlines()
|
||||||
|
else:
|
||||||
|
env_lines = []
|
||||||
|
|
||||||
|
new_env = []
|
||||||
|
for line in env_lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
if stripped.startswith("DOMAINS_") or stripped.startswith("ALL_DOMAINS") or "CERTBOT NGINX VARIABLES" in stripped:
|
||||||
|
continue
|
||||||
|
new_env.append(line)
|
||||||
|
|
||||||
|
# удаляем пустые строки в начале
|
||||||
|
while new_env and not new_env[0].strip():
|
||||||
|
new_env.pop(0)
|
||||||
|
|
||||||
|
domain_keys = {k: v for k, v in env_domains.items()}
|
||||||
|
|
||||||
|
insert_idx = None
|
||||||
|
for i, line in enumerate(new_env):
|
||||||
|
if line.strip().startswith("EMAIL="):
|
||||||
|
insert_idx = i + 1
|
||||||
|
break
|
||||||
|
|
||||||
|
env_header = "#CERTBOT NGINX VARIABLES — авто-сгенерировано, не редактировать вручную\n"
|
||||||
|
domain_lines = [f"{k}={v}\n" for k, v in sorted(domain_keys.items())]
|
||||||
|
|
||||||
|
if insert_idx is not None:
|
||||||
|
new_env.insert(insert_idx, env_header)
|
||||||
|
for dl in reversed(domain_lines):
|
||||||
|
new_env.insert(insert_idx + 1, dl)
|
||||||
|
else:
|
||||||
|
new_env = [env_header] + domain_lines + new_env
|
||||||
|
|
||||||
|
with open(ENV_FILE, "w") as f:
|
||||||
|
f.writelines(new_env)
|
||||||
|
print(f" ✓ {ENV_FILE} (обновлён)")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=== Генерация завершена ===")
|
||||||
|
print(f"Сгенерировано {len(site_list)} сайтов:")
|
||||||
|
for s in site_list:
|
||||||
|
print(f" • {s['domain']} ({s['type']})")
|
||||||
|
print()
|
||||||
|
print("Не забудь перезапустить nginx: docker compose restart nginx")
|
||||||
|
PYEOF
|
||||||
+10
-21
@@ -1,28 +1,17 @@
|
|||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
|
||||||
# Установка зависимостей
|
|
||||||
RUN apk add --no-cache bash openssl
|
RUN apk add --no-cache bash openssl
|
||||||
|
|
||||||
# Создание директории для сертификатов
|
# dummy сертификаты для nginx (нужны чтобы nginx стартовал с любым конфигом)
|
||||||
RUN mkdir -p /etc/nginx/ssl
|
RUN mkdir -p /etc/nginx/ssl && \
|
||||||
|
openssl req -x509 -nodes -days 365 \
|
||||||
|
-newkey rsa:2048 \
|
||||||
|
-keyout /etc/nginx/ssl/dummy.key \
|
||||||
|
-out /etc/nginx/ssl/dummy.crt \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
||||||
|
|
||||||
# Генерация самоподписанных сертификатов (действительны 365 дней)
|
RUN mkdir -p /var/www/certbot /etc/nginx/conf.d /etc/nginx/conf.available
|
||||||
RUN openssl req -x509 -nodes -days 365 \
|
|
||||||
-newkey rsa:2048 \
|
|
||||||
-keyout /etc/nginx/ssl/dummy.key \
|
|
||||||
-out /etc/nginx/ssl/dummy.crt \
|
|
||||||
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
|
||||||
|
|
||||||
# Копируем обе конфигурации
|
# per-domain entrypoint для проверки сертификатов
|
||||||
COPY nginx-http.conf /etc/nginx/nginx-http.conf
|
COPY entrypoint.sh /docker-entrypoint.d/switch-config.sh
|
||||||
COPY nginx-ssl.conf /etc/nginx/nginx-ssl.conf
|
|
||||||
|
|
||||||
# Создаем симлинк по умолчанию на HTTP конфиг
|
|
||||||
RUN ln -sf /etc/nginx/nginx-http.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
# Скрипт для проверки сертификатов и переключения конфига
|
|
||||||
COPY switch-config.sh /docker-entrypoint.d/switch-config.sh
|
|
||||||
RUN chmod +x /docker-entrypoint.d/switch-config.sh
|
RUN chmod +x /docker-entrypoint.d/switch-config.sh
|
||||||
|
|
||||||
# Создаем необходимые директории
|
|
||||||
RUN mkdir -p /var/www/certbot
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/stub/html;
|
||||||
|
index index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# HTTP fallback for yalarba.ru (no SSL cert)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name yalarba.ru www.yalarba.ru;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://yalarba:3000;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/ {
|
||||||
|
proxy_pass http://api_yal:8787;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# CERT_DOMAIN=yalarba.ru
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name yalarba.ru www.yalarba.ru;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/yalarba.ru/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/yalarba.ru/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://yalarba:3000;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/ {
|
||||||
|
proxy_pass http://api_yal:8787;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# HTTP fallback for valitovgaziz.ru (no SSL cert)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name valitovgaziz.ru www.valitovgaziz.ru;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://valitovgaziz/;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://analytics:3000/;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# CERT_DOMAIN=valitovgaziz.ru
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name valitovgaziz.ru www.valitovgaziz.ru;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/valitovgaziz.ru/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/valitovgaziz.ru/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://valitovgaziz/;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://analytics:3000/;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# HTTP fallback for easysite102.ru (no SSL cert)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name easysite102.ru www.easysite102.ru;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://easysite:3000;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/ {
|
||||||
|
proxy_pass http://api_yal:8787;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# CERT_DOMAIN=easysite102.ru
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name easysite102.ru www.easysite102.ru;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/easysite102.ru/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/easysite102.ru/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://easysite:3000;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/ {
|
||||||
|
proxy_pass http://api_yal:8787;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# HTTP fallback for begushiybashkir.ru (no SSL cert)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name begushiybashkir.ru www.begushiybashkir.ru;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api_bb:8080/;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /uploads/ {
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# CERT_DOMAIN=begushiybashkir.ru
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name begushiybashkir.ru www.begushiybashkir.ru;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/begushiybashkir.ru/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/begushiybashkir.ru/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api_bb:8080/;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /uploads/ {
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# HTTP fallback for xn--80abahjtcfl5d0a8di.xn--p1ai (no SSL cert)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name xn--80abahjtcfl5d0a8di.xn--p1ai www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api_bb:8080/;
|
||||||
|
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;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /uploads/ {
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# CERT_DOMAIN=xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
# Автоматически сгенерировано generate-configs.sh
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name xn--80abahjtcfl5d0a8di.xn--p1ai www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api_bb:8080/;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /uploads/ {
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+37
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# entrypoint.sh — per-domain HTTPS переключение
|
||||||
|
# Для каждого домена проверяет сертификат и активирует SSL или HTTP конфиг
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONF_AVAILABLE="/etc/nginx/conf.available"
|
||||||
|
CONF_D="/etc/nginx/conf.d"
|
||||||
|
CERT_DIR="/etc/letsencrypt/live"
|
||||||
|
|
||||||
|
rm -f "$CONF_D"/*.conf
|
||||||
|
|
||||||
|
# базовый HTTP (ACME challenge, catch-all redirect)
|
||||||
|
if [ -f "$CONF_AVAILABLE/00-http.conf" ]; then
|
||||||
|
ln -sf "$CONF_AVAILABLE/00-http.conf" "$CONF_D/00-http.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# per-domain конфиги
|
||||||
|
shopt -s nullglob
|
||||||
|
for ssl_conf in "$CONF_AVAILABLE"/*.ssl.conf; do
|
||||||
|
base="$(basename "$ssl_conf" .ssl.conf)"
|
||||||
|
http_conf="$CONF_AVAILABLE/$base.http.conf"
|
||||||
|
|
||||||
|
# CERT_DOMAIN в первой строке: # CERT_DOMAIN=example.ru
|
||||||
|
cert_domain="$(head -1 "$ssl_conf" | grep -oP '(?<=# CERT_DOMAIN=).+')" || true
|
||||||
|
|
||||||
|
if [ -n "$cert_domain" ] && [ -f "$CERT_DIR/$cert_domain/fullchain.pem" ]; then
|
||||||
|
ln -sf "$ssl_conf" "$CONF_D/$base.ssl.conf"
|
||||||
|
echo " ✓ $base → HTTPS ($cert_domain)"
|
||||||
|
elif [ -f "$http_conf" ]; then
|
||||||
|
ln -sf "$http_conf" "$CONF_D/$base.http.conf"
|
||||||
|
echo " ✓ $base → HTTP (no cert for $cert_domain)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "---"
|
||||||
|
ls -la "$CONF_D/" | grep -v '^total'
|
||||||
|
nginx -t
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
|
# Автоматически сгенерировано generate-configs.sh — не редактировать вручную
|
||||||
|
# HTTP-only конфигурация (работает когда нет сертификатов)
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name yalarba.ru \
|
server_name yalarba.ru \
|
||||||
www.yalarba.ru \
|
www.yalarba.ru \
|
||||||
easysite102.ru \
|
|
||||||
www.easysite102.ru \
|
|
||||||
valitovgaziz.ru \
|
valitovgaziz.ru \
|
||||||
www.valitovgaziz.ru \
|
www.valitovgaziz.ru \
|
||||||
xn--80abahjtcfl5d0a8di.xn--p1ai \
|
easysite102.ru \
|
||||||
www.xn--80abahjtcfl5d0a8di.xn--p1ai \
|
www.easysite102.ru \
|
||||||
begushiybashkir.ru \
|
begushiybashkir.ru \
|
||||||
www.begushiybashkir.ru \
|
www.begushiybashkir.ru \
|
||||||
auth.yalarba.ru;
|
xn--80abahjtcfl5d0a8di.xn--p1ai \
|
||||||
|
www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /usr/share/nginx/stub/html;
|
root /usr/share/nginx/stub/html;
|
||||||
@@ -25,12 +27,19 @@ server {
|
|||||||
# Блок для HTTPS → HTTP редиректа (порт 443)
|
# Блок для HTTPS → HTTP редиректа (порт 443)
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name yalarba.ru www.yalarba.ru easysite102.ru www.easysite102.ru valitovgaziz.ru www.valitovgaziz.ru xn--80abahjtcfl5d0a8di.xn--p1ai www.xn--80abahjtcfl5d0a8di.xn--p1ai begushiybashkir.ru www.begushiybashkir.ru;
|
server_name yalarba.ru \
|
||||||
|
www.yalarba.ru \
|
||||||
|
valitovgaziz.ru \
|
||||||
|
www.valitovgaziz.ru \
|
||||||
|
easysite102.ru \
|
||||||
|
www.easysite102.ru \
|
||||||
|
begushiybashkir.ru \
|
||||||
|
www.begushiybashkir.ru \
|
||||||
|
xn--80abahjtcfl5d0a8di.xn--p1ai \
|
||||||
|
www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
|
|
||||||
# Указание пустых сертификатов (обязательно для запуска Nginx)
|
|
||||||
ssl_certificate /etc/nginx/ssl/dummy.crt;
|
ssl_certificate /etc/nginx/ssl/dummy.crt;
|
||||||
ssl_certificate_key /etc/nginx/ssl/dummy.key;
|
ssl_certificate_key /etc/nginx/ssl/dummy.key;
|
||||||
|
|
||||||
# Редирект всех HTTPS-запросов на HTTP
|
|
||||||
return 301 http://$host$request_uri;
|
return 301 http://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-222
@@ -1,130 +1,52 @@
|
|||||||
# ================================================
|
# Автоматически сгенерировано generate-configs.sh — не редактировать вручную
|
||||||
# КОНФИГУРАЦИЯ NGINX С ПОДДЕРЖКОЙ SSL
|
# Полная HTTPS конфигурация
|
||||||
# Основные задачи:
|
|
||||||
# 1. Перенаправление HTTP → HTTPS
|
|
||||||
# 2. Обслуживание статических файлов
|
|
||||||
# 3. Проксирование к backend сервисам
|
|
||||||
# 4. Поддержка нескольких доменов
|
|
||||||
# ================================================
|
|
||||||
|
|
||||||
# ================================================
|
# --- HTTP → HTTPS редирект ---
|
||||||
# БЛОК 1: HTTP СЕРВЕР (ПОРТ 80)
|
|
||||||
# ================================================
|
|
||||||
server {
|
server {
|
||||||
# Прослушивание порта 80 для всех входящих HTTP соединений
|
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
# Список доменов, которые обслуживает этот сервер
|
|
||||||
# Все запросы к этим доменам по HTTP будут обработаны здесь
|
|
||||||
server_name yalarba.ru www.yalarba.ru
|
|
||||||
valitovgaziz.ru www.valitovgaziz.ru
|
|
||||||
easysite102.ru www.easysite102.ru
|
|
||||||
begushiybashkir.ru
|
|
||||||
xn--80abahjtcfl5d0a8di.xn--p1ai; # Punycode для IDN домена
|
|
||||||
|
|
||||||
# ============================================
|
server_name yalarba.ru www.yalarba.ru valitovgaziz.ru www.valitovgaziz.ru easysite102.ru www.easysite102.ru begushiybashkir.ru www.begushiybashkir.ru xn--80abahjtcfl5d0a8di.xn--p1ai www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
# ЛОКАЦИЯ: Проверочные файлы для Certbot
|
|
||||||
# ============================================
|
|
||||||
# Этот блок КРИТИЧЕСКИ ВАЖЕН для получения SSL сертификатов
|
|
||||||
# Certbot (Let's Encrypt) размещает здесь временные файлы
|
|
||||||
# для подтверждения владения доменом
|
|
||||||
location /.well-known/acme-challenge/ {
|
location /.well-known/acme-challenge/ {
|
||||||
# Директория, где Certbot хранит проверочные файлы
|
|
||||||
root /var/www/certbot;
|
root /var/www/certbot;
|
||||||
|
|
||||||
# Дополнительные настройки не нужны - nginx просто отдает файлы
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Основное перенаправление
|
|
||||||
# ============================================
|
|
||||||
# Все HTTP запросы перенаправляются на HTTPS
|
|
||||||
# Это обеспечивает безопасность и правильную SEO-практику
|
|
||||||
location / {
|
|
||||||
# 301 - постоянный редирект (лучше для SEO, кэшируется браузерами)
|
|
||||||
# https://$host$request_uri - сохраняет домен и полный путь запроса
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
|
|
||||||
# Пример:
|
|
||||||
# HTTP: http://example.com/page?param=1
|
|
||||||
# ↓ перенаправление ↓
|
|
||||||
# HTTPS: https://example.com/page?param=1
|
|
||||||
}
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Загруженные файлы
|
|
||||||
# ============================================
|
|
||||||
# Обслуживание статических файлов (загрузок) по HTTP
|
|
||||||
# Может быть полезно для прямых ссылок или кэширования
|
|
||||||
location /uploads/ {
|
location /uploads/ {
|
||||||
# Псевдоним пути - запросы к /uploads/ обслуживаются из /uploads/ на диске
|
|
||||||
alias /uploads/;
|
alias /uploads/;
|
||||||
|
|
||||||
# Кэширование в браузере на 1 год
|
|
||||||
expires 1y;
|
expires 1y;
|
||||||
|
|
||||||
# Заголовки кэширования:
|
|
||||||
# "public" - может кэшироваться прокси-серверами
|
|
||||||
# "immutable" - файлы никогда не меняются, браузер не проверяет обновления
|
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
# Если файл не найден - вернуть 404 ошибку
|
|
||||||
try_files $uri =404;
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ================================================
|
# --- HTTPS серверные блоки ---
|
||||||
# БЛОК 2: HTTPS СЕРВЕР ДЛЯ YALARBA.RU
|
|
||||||
# ================================================
|
|
||||||
server {
|
server {
|
||||||
# Прослушивание порта 443 с SSL/TLS шифрованием
|
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
|
|
||||||
# Домены для этого сервера
|
|
||||||
server_name yalarba.ru www.yalarba.ru;
|
server_name yalarba.ru www.yalarba.ru;
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# НАСТРОЙКИ SSL СЕРТИФИКАТОВ
|
|
||||||
# ============================================
|
|
||||||
# Пути к SSL сертификатам, сгенерированным Certbot
|
|
||||||
ssl_certificate /etc/letsencrypt/live/yalarba.ru/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/yalarba.ru/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/yalarba.ru/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/yalarba.ru/privkey.pem;
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# НАСТРОЙКИ БЕЗОПАСНОСТИ SSL
|
|
||||||
# ============================================
|
|
||||||
# Разрешенные протоколы - только современные безопасные версии
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
|
||||||
# Сервер выбирает шифры (не клиент)
|
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
# Список безопасных шифров
|
|
||||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Nuxt 4 SSR приложение
|
|
||||||
# ============================================
|
|
||||||
location / {
|
location / {
|
||||||
# Проксирование к Nuxt.js SSR серверу
|
|
||||||
proxy_pass http://yalarba:3000;
|
proxy_pass http://yalarba:3000;
|
||||||
|
|
||||||
# Полный набор заголовков для корректной работы приложения
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
# Длинные таймауты
|
|
||||||
proxy_connect_timeout 600;
|
proxy_connect_timeout 600;
|
||||||
proxy_send_timeout 600;
|
proxy_send_timeout 600;
|
||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: REST API (api_yal)
|
|
||||||
# ============================================
|
|
||||||
location /api/v1/ {
|
location /api/v1/ {
|
||||||
proxy_pass http://api_yal:8787;
|
proxy_pass http://api_yal:8787;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -135,28 +57,30 @@ server {
|
|||||||
proxy_connect_timeout 600;
|
proxy_connect_timeout 600;
|
||||||
proxy_send_timeout 600;
|
proxy_send_timeout 600;
|
||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ================================================
|
|
||||||
# БЛОК 3: HTTPS СЕРВЕР ДЛЯ VALITOVGAZIZ.RU
|
|
||||||
# ================================================
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name valitovgaziz.ru www.valitovgaziz.ru;
|
server_name valitovgaziz.ru www.valitovgaziz.ru;
|
||||||
|
|
||||||
# Свой SSL сертификат для этого домена
|
|
||||||
ssl_certificate /etc/letsencrypt/live/valitovgaziz.ru/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/valitovgaziz.ru/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/valitovgaziz.ru/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/valitovgaziz.ru/privkey.pem;
|
||||||
|
|
||||||
# Те же настройки безопасности SSL
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Проксирование к Vue SPA контейнеру
|
|
||||||
# ============================================
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://valitovgaziz/;
|
proxy_pass http://valitovgaziz/;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -169,79 +93,59 @@ server {
|
|||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: API для аналитики
|
|
||||||
# ============================================
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://analytics:3000/;
|
proxy_pass http://analytics:3000/;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
add_header Access-Control-Allow-Origin "*" always;
|
proxy_connect_timeout 600;
|
||||||
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS" always;
|
proxy_send_timeout 600;
|
||||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
proxy_read_timeout 600;
|
||||||
add_header Access-Control-Allow-Credentials "true" always;
|
|
||||||
|
|
||||||
if ($request_method = OPTIONS) {
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
return 204;
|
return 204;
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy_connect_timeout 30s;
|
|
||||||
proxy_send_timeout 30s;
|
|
||||||
proxy_read_timeout 30s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ================================================
|
|
||||||
# БЛОК 4: HTTPS СЕРВЕР ДЛЯ EASYSITE102.RU
|
|
||||||
# ================================================
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name easysite102.ru www.easysite102.ru;
|
server_name easysite102.ru www.easysite102.ru;
|
||||||
|
|
||||||
# Свой SSL сертификат
|
|
||||||
ssl_certificate /etc/letsencrypt/live/easysite102.ru/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/easysite102.ru/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/easysite102.ru/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/easysite102.ru/privkey.pem;
|
||||||
|
|
||||||
# Безопасные настройки SSL
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Проксирование к Nuxt.js приложению
|
|
||||||
# ============================================
|
|
||||||
location / {
|
location / {
|
||||||
# ВСЕ запросы проксируются к Nuxt.js серверу
|
|
||||||
proxy_pass http://easysite:3000;
|
proxy_pass http://easysite:3000;
|
||||||
|
|
||||||
# Полный набор заголовков для корректной работы приложения
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
# Длинные таймауты для работы приложения
|
|
||||||
proxy_connect_timeout 600;
|
proxy_connect_timeout 600;
|
||||||
proxy_send_timeout 600;
|
proxy_send_timeout 600;
|
||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: API Backend для Easysite (api_yal)
|
|
||||||
# ============================================
|
|
||||||
location /api/v1/ {
|
location /api/v1/ {
|
||||||
proxy_pass http://api_yal:8787;
|
proxy_pass http://api_yal:8787;
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
proxy_connect_timeout 600;
|
proxy_connect_timeout 600;
|
||||||
proxy_send_timeout 600;
|
proxy_send_timeout 600;
|
||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
@@ -255,111 +159,26 @@ server {
|
|||||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
return 204;
|
return 204;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ================================================
|
|
||||||
# БЛОК 5: HTTPS СЕРВЕР ДЛЯ IDN ДОМЕНА
|
|
||||||
# (Punycode для "бегущийбашкир.рф")
|
|
||||||
# ================================================
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
|
|
||||||
# Punycode представление кириллического домена
|
|
||||||
server_name xn--80abahjtcfl5d0a8di.xn--p1ai
|
|
||||||
www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
|
||||||
|
|
||||||
# Отдельный сертификат для IDN домена
|
|
||||||
ssl_certificate /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/privkey.pem;
|
|
||||||
|
|
||||||
# Стандартные SSL настройки
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: SPA приложение (такое же как begushiybashkir.ru)
|
|
||||||
# ============================================
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/begushiybashkir/html;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: API для "Бегущий Башкир"
|
|
||||||
# ============================================
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://api_bb:8080/;
|
|
||||||
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;
|
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
|
||||||
proxy_connect_timeout 600;
|
|
||||||
proxy_send_timeout 600;
|
|
||||||
proxy_read_timeout 600;
|
|
||||||
|
|
||||||
# Те же CORS настройки что и у Easysite
|
|
||||||
if ($request_method = OPTIONS ) {
|
|
||||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
|
||||||
add_header 'Content-Length' 0;
|
|
||||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Загруженные файлы (статическое обслуживание)
|
|
||||||
# ============================================
|
|
||||||
location /uploads/ {
|
|
||||||
# Обслуживание файлов загрузок напрямую из файловой системы
|
|
||||||
alias /uploads/;
|
|
||||||
|
|
||||||
# Долгое кэширование - файлы загрузок редко меняются
|
|
||||||
expires 1y;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
|
|
||||||
# try_files не нужен - nginx сам проверит существование файла
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ================================================
|
|
||||||
# БЛОК 6: HTTPS СЕРВЕР ДЛЯ BEGUSHIYBASHKIR.RU
|
|
||||||
# (ДУБЛИРУЕТ БЛОК 5 С ДРУГИМ ДОМЕНОМ)
|
|
||||||
# ================================================
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name begushiybashkir.ru www.begushiybashkir.ru;
|
server_name begushiybashkir.ru www.begushiybashkir.ru;
|
||||||
|
|
||||||
# Свой SSL сертификат для этого домена
|
|
||||||
ssl_certificate /etc/letsencrypt/live/begushiybashkir.ru/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/begushiybashkir.ru/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/begushiybashkir.ru/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/begushiybashkir.ru/privkey.pem;
|
||||||
|
|
||||||
# Стандартные SSL настройки
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
# ВНИМАНИЕ: Весь контент ниже ДОСЛОВНО ДУБЛИРУЕТ
|
|
||||||
# предыдущий серверный блок для IDN домена
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: SPA приложение
|
|
||||||
# ============================================
|
|
||||||
location / {
|
location / {
|
||||||
root /usr/share/nginx/begushiybashkir/html;
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: API для "Бегущий Башкир"
|
|
||||||
# ============================================
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://api_bb:8080/;
|
proxy_pass http://api_bb:8080/;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -371,8 +190,7 @@ server {
|
|||||||
proxy_send_timeout 600;
|
proxy_send_timeout 600;
|
||||||
proxy_read_timeout 600;
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
# Копия CORS настроек
|
if ($request_method = OPTIONS) {
|
||||||
if ($request_method = OPTIONS ) {
|
|
||||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
@@ -381,17 +199,58 @@ server {
|
|||||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
return 204;
|
return 204;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /uploads/ {
|
||||||
|
alias /uploads/;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name xn--80abahjtcfl5d0a8di.xn--p1ai www.xn--80abahjtcfl5d0a8di.xn--p1ai;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/xn--80abahjtcfl5d0a8di.xn--p1ai/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/begushiybashkir/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api_bb:8080/;
|
||||||
|
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;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_connect_timeout 600;
|
||||||
|
proxy_send_timeout 600;
|
||||||
|
proxy_read_timeout 600;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||||
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
|
add_header 'Content-Length' 0;
|
||||||
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# ЛОКАЦИЯ: Загруженные файлы
|
|
||||||
# ============================================
|
|
||||||
location /uploads/ {
|
location /uploads/ {
|
||||||
alias /uploads/;
|
alias /uploads/;
|
||||||
expires 1y;
|
expires 1y;
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# ================================================
|
|
||||||
# КОНЕЦ КОНФИГУРАЦИИ
|
|
||||||
# ================================================
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# Единый источник истины для всех сайтов проекта
|
||||||
|
# Добавление нового сайта = одна секция в этом файле
|
||||||
|
# После изменений запусти: bash generate-configs.sh
|
||||||
|
|
||||||
|
sites:
|
||||||
|
yalarba:
|
||||||
|
domain: yalarba.ru
|
||||||
|
aliases:
|
||||||
|
- www.yalarba.ru
|
||||||
|
type: upstream
|
||||||
|
upstream: http://yalarba:3000
|
||||||
|
api:
|
||||||
|
/api/v1/: http://api_yal:8787
|
||||||
|
|
||||||
|
valitovgaziz:
|
||||||
|
domain: valitovgaziz.ru
|
||||||
|
aliases:
|
||||||
|
- www.valitovgaziz.ru
|
||||||
|
type: upstream
|
||||||
|
upstream: http://valitovgaziz/
|
||||||
|
api:
|
||||||
|
/api/: http://analytics:3000/
|
||||||
|
|
||||||
|
easysite102:
|
||||||
|
domain: easysite102.ru
|
||||||
|
aliases:
|
||||||
|
- www.easysite102.ru
|
||||||
|
type: upstream
|
||||||
|
upstream: http://easysite:3000
|
||||||
|
api:
|
||||||
|
/api/v1/: http://api_yal:8787
|
||||||
|
|
||||||
|
begushiybashkir:
|
||||||
|
domain: begushiybashkir.ru
|
||||||
|
aliases:
|
||||||
|
- www.begushiybashkir.ru
|
||||||
|
type: static
|
||||||
|
root: /usr/share/nginx/begushiybashkir/html
|
||||||
|
api:
|
||||||
|
/api/: http://api_bb:8080/
|
||||||
|
|
||||||
|
begushiybashkir_idn:
|
||||||
|
domain: xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
aliases:
|
||||||
|
- www.xn--80abahjtcfl5d0a8di.xn--p1ai
|
||||||
|
type: static
|
||||||
|
root: /usr/share/nginx/begushiybashkir/html
|
||||||
|
api:
|
||||||
|
/api/: http://api_bb:8080/
|
||||||
Reference in New Issue
Block a user