neyrogovnarik 4fdc008203 Production readiness: sentinel errors, WebSocket CORS, Docker secrets, тесты, ErrorBoundary, Obsidian Zettelkasten, CSP, DI hace 1 mes
..
Caddyfile 4fdc008203 Production readiness: sentinel errors, WebSocket CORS, Docker secrets, тесты, ErrorBoundary, Obsidian Zettelkasten, CSP, DI hace 1 mes
README.md 8ac67d5043 P0: Security & production readiness hace 1 mes
deploy-remote.sh c271bf0057 Исправления сборки и деплоя hace 1 mes
deploy.sh da3f091189 Финальные исправления перед деплоем hace 1 mes
docker-compose.prod.yml 8dd3857c2c Критичные исправления для деплоя hace 1 mes
env.prod 4fdc008203 Production readiness: sentinel errors, WebSocket CORS, Docker secrets, тесты, ErrorBoundary, Obsidian Zettelkasten, CSP, DI hace 1 mes
env.prod.example 16345a295e MinIO S3 API через path-based routing (api.photoplaces.ru/s3/) hace 1 mes
setup.sh 375ea1940b Initial commit: PhotoPlaces MVP hace 2 meses

README.md

Deploy — Secrets Management

Быстрый старт (local / single server)

# 1. Скопируйте шаблон
cp deploy/env.prod.example deploy/env.prod

# 2. Отредактируйте (или запустите deploy.sh — он предложит сгенерировать секреты)
vim deploy/env.prod

# 3. Деплой
bash deploy/deploy.sh

deploy/env.prod не коммитится в git.gitignore).


Production: External Secrets Sources

Поддерживаются 4 способа загрузки секретов (в порядке приоритета):

1. 1Password CLI (op)

export OP_VAULT="Production"
export OP_ITEM="PhotoPlaces Secrets"
bash deploy/deploy.sh

Требует: op CLI, авторизованный (op signin).

2. HashiCorp Vault

export VAULT_ADDR="https://vault.example.com"
export VAULT_TOKEN="hvs.xxxxx"
export VAULT_PATH="secret/photoplaces"
bash deploy/deploy.sh

Требует: vault CLI, jq.

3. AWS Secrets Manager

export AWS_SECRETS_NAME="prod/photoplaces"
bash deploy/deploy.sh

Требует: aws CLI, jq, IAM права на secretsmanager:GetSecretValue.

4. Local file (fallback)

Если ни один из выше не настроен — используется deploy/env.prod.


Docker Swarm Mode (Secrets в Swarm)

Если кластер в Swarm mode (docker info | grep Swarm), deploy.sh автоматически создаёт Docker secrets:

# Секреты создаются из переменных окружения (загруженных из любого источника выше)
docker secret create db_password -
docker secret create redis_password -
docker secret create jwt_secret -
docker secret create jwt_refresh_secret -
docker secret create s3_secret_key -

В docker-compose.prod.yml сервисы читают секреты из /run/secrets/<name>.

Backend config (internal/config/config.go) поддерживает _FILE суффикс:

// JWT_SECRET_FILE=/run/secrets/jwt_secret → читает из файла
// JWT_SECRET=fallback → если файл не найден

Required Secrets

Переменная Описание Где используется
DB_PASSWORD Пароль PostgreSQL postgres, backend
REDIS_PASSWORD Пароль Redis redis, backend
JWT_SECRET Подпись access токенов backend
JWT_REFRESH_SECRET Подпись refresh токенов backend
S3_SECRET_KEY Пароль MinIO minio, backend
S3_PUBLIC_ENDPOINT Публичный URL MinIO (для прямых загрузок) frontend, backend
NEXT_PUBLIC_API_URL Публичный URL API frontend
ALLOWED_ORIGINS CORS origins (через запятую) backend

Генерация секретов вручную

# 32 байта = 64 hex chars
openssl rand -hex 32

# Для паролей БД/Redis можно короче
openssl rand -base64 24

Безопасность

  • deploy/env.prod в .gitignore
  • ✅ Docker secrets в Swarm (не в env vars, не в логах)
  • ✅ Поддержка внешних vaults (1Password, Vault, AWS)
  • ✅ Fallback на local файл для разработки
  • ✅ Валидация обязательных переменных перед деплоем

Пример для CI/CD (GitHub Actions)

- name: Deploy to production
  env:
    OP_VAULT: ${{ secrets.OP_VAULT }}
    OP_ITEM: ${{ secrets.OP_ITEM }}
    OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
  run: |
    op signin --account ${{ secrets.OP_ACCOUNT }} --token $OP_SERVICE_ACCOUNT_TOKEN
    bash deploy/deploy.sh