소스 검색

Фикс: README кодировка, curl/wget healthcheck, Caddy healthcheck fix

neyrogovnarik 1 개월 전
부모
커밋
a28f5d4e2e
5개의 변경된 파일134개의 추가작업 그리고 94개의 파일을 삭제
  1. 128 88
      README.md
  2. 1 1
      backend/Dockerfile
  3. 3 3
      deploy/deploy-remote.sh
  4. 1 1
      deploy/docker-compose.prod.yml
  5. 1 1
      docker-compose.yml

+ 128 - 88
README.md

@@ -1,6 +1,6 @@
 # PhotoPlaces
 
-Сервис онлайн-карты с отметками мест для фотосъёмки, аренды фотостудий и найма фотографов.
+Маркетплейс фотолокаций: находите места и студии для фотосъёмок, бронируйте, общайтесь с фотографами.
 
 ## Стек
 
@@ -9,34 +9,29 @@
 | Фронтенд | Next.js 14, React 18, TypeScript, Tailwind CSS |
 | Бэкенд | Go 1.22, Chi router, pgx |
 | База данных | PostgreSQL 16 + PostGIS |
-| Кеш | Redis 7 |
+| Кэш | Redis 7 |
 | Файлы | MinIO (S3-совместимое хранилище) |
-| Аутентификация | JWT (access + refresh токены) |
+| Авторизация | JWT (access + refresh токены) |
 | Инфраструктура | Docker, docker-compose |
 
-## Быстрый старт
+## Быстрый старт (локальная разработка)
 
-### 1. Клонировать и перейти в проект
+### 1. Клонирование и запуск зависимостей
 
 ```bash
 git clone http://192.168.88.96:10880/foxtime/photoplaces.git
 cd photoplaces
-```
-
-### 2. Запустить инфраструктуру (БД, Redis, MinIO)
-
-```bash
 docker compose up -d postgres redis minio
 ```
 
-### 3. Инициализировать переменные окружения
+### 2. Настройка окружения
 
 ```bash
 cp backend/.env.example backend/.env
 cp frontend/.env.local.example frontend/.env.local
 ```
 
-### 4. Запустить бэкенд
+### 3. Запуск бэкенда
 
 ```bash
 cd backend
@@ -45,7 +40,7 @@ go run ./cmd/api
 
 Бэкенд будет доступен на `http://localhost:8080/api/v1`
 
-### 5. Запустить фронтенд (в другом терминале)
+### 4. Запуск фронтенда (в отдельном терминале)
 
 ```bash
 cd frontend
@@ -55,10 +50,53 @@ npm run dev
 
 Фронтенд будет доступен на `http://localhost:3000`
 
-### Либо через Make
+### Через Make
+
+```bash
+make dev    # docker compose + go run + npm run dev одновременно
+```
+
+## Развёртывание на сервере (192.168.88.128)
+
+### Первичная настройка сервера
+
+Заходим на сервер по SSH и запускаем:
+
+```bash
+ssh foxtime@192.168.88.128
+curl -fsSL http://192.168.88.96:10880/foxtime/photoplaces/raw/main/deploy/deploy-remote.sh | bash
+```
+
+Скрипт автоматически:
+1. Проверит/установит Docker, Git, curl, openssl
+2. Склонирует репозиторий
+3. Сгенерирует секреты (пароли БД, JWT, S3)
+4. Запросит Yandex Maps API Key и домен
+5. Запустит docker-compose в production режиме
+
+### Ручной деплой (если автоматический не подошёл)
+
+```bash
+ssh foxtime@192.168.88.128
+cd /home/foxtime/photoplaces
+docker compose --env-file deploy/env.prod -f deploy/docker-compose.prod.yml up -d --build
+```
+
+### Просмотр логов
+
+```bash
+ssh foxtime@192.168.88.128
+cd /home/foxtime/photoplaces
+docker compose -f deploy/docker-compose.prod.yml logs -f
+```
+
+### Обновление после изменений в репозитории
 
 ```bash
-make dev    # docker compose + go run + npm run dev одной командой
+ssh foxtime@192.168.88.128
+cd /home/foxtime/photoplaces
+git pull origin main
+docker compose --env-file deploy/env.prod -f deploy/docker-compose.prod.yml up -d --build --remove-orphans
 ```
 
 ## Структура проекта
@@ -66,107 +104,108 @@ make dev    # docker compose + go run + npm run dev одной командой
 ```
 photoplaces/
 ├── backend/
-│   ├── cmd/api/main.go          # точка входа API
+│   ├── cmd/api/main.go            # Точка входа API
 │   ├── internal/
-│   │   ├── config/              # загрузка конфигурации из env
-│   │   ├── handlers/            # HTTP-обработчики (auth, places, services...)
-│   │   ├── middleware/          # JWT-аутентификация, rate limiter
-│   │   ├── models/              # структуры данных (User, Place, Booking…)
-│   │   ├── repository/          # работа с PostgreSQL
-│   │   └── services/            # бизнес-логика
-│   ├── migrations/              # SQL-миграции (golang-migrate)
-│   └── docs/                    # документация
-│       ├── SPEC.md              # техническое задание
-│       ├── API_CONTRACT.md      # контракт API
-│       ├── DB_SCHEMA.md         # схема базы данных
-│       ├── MAP_PROVIDERS.md     # провайдеры карт
-│       └── PAYMENT_INTEGRATION.md
+│   │   ├── config/                # Загрузка конфига из env
+│   │   ├── handlers/              # HTTP-обработчики (auth, places, services...)
+│   │   ├── middleware/            # JWT-аутентификация, rate limiter
+│   │   ├── models/               # Модели данных (User, Place, Booking...)
+│   │   ├── repository/           # Запросы к PostgreSQL
+│   │   ├── services/             # Бизнес-логика
+│   │   ├── validator/            # Валидация (go-playground/validator)
+│   │   ├── pointer/              # Утилиты для указателей
+│   │   └── log/                  # Структурированное логирование (slog)
+│   ├── migrations/               # SQL-миграции (golang-migrate)
+│   └── docs/                     # Документация
 ├── frontend/
 │   ├── src/
-│   │   ├── app/                 # страницы и layout (Next.js App Router)
-│   │   ├── components/          # React-компоненты
-│   │   ├── hooks/               # кастомные хуки (useAuth)
-│   │   ├── lib/                 # утилиты (api, map)
-│   │   ├── styles/              # глобальные стили
-│   │   └── types/               # TypeScript-типы
+│   │   ├── app/                  # Страницы (Next.js App Router)
+│   │   ├── components/           # React-компоненты
+│   │   ├── hooks/                # Пользовательские хуки (useAuth)
+│   │   ├── lib/                  # Утилиты (api, map)
+│   │   ├── styles/               # Глобальные стили
+│   │   └── types/                # TypeScript-типы
 │   └── public/
-├── deploy/                      # продакшен-окружение
+├── deploy/                       # Инфраструктура продакшена
 │   ├── docker-compose.prod.yml
 │   ├── env.prod
 │   ├── deploy.sh
+│   ├── deploy-remote.sh
 │   └── setup.sh
-├── docker-compose.yml           # локальное окружение
-└── Makefile                     # вспомогательные команды
+├── docker-compose.yml            # Локальная разработка
+└── Makefile                      # Автоматизация команд
 ```
 
-## Доступные команды
+## Команды Make
 
 ```bash
-make dev      # локальная разработка
-make prod     # продакшен-сборка
-make logs     # логи продакшена
-make stop     # остановка контейнеров
-make clean    # остановка + удаление volume
-make ps       # статус контейнеров
+make dev      # Локальная разработка
+make prod     # Продакшен-сборка
+make test     # Запуск всех тестов
+make test-backend   # Тесты бэкенда
+make test-frontend  # Тесты фронтенда
+make logs     # Просмотр логов
+make stop     # Остановка контейнеров
+make migrate  # Запуск миграций
 ```
 
 ## API
 
-Документация: `backend/docs/API_CONTRACT.md`
+Полная спецификация: `backend/docs/API_CONTRACT.md`
 
 Базовый URL: `http://localhost:8080/api/v1`
 
 ### Основные эндпоинты
 
-| Метод | Путь | Аутентификация |
-|-------|------|----------------|
-| POST | /auth/register |  |
-| POST | /auth/login |  |
-| POST | /auth/refresh |  |
+| Метод | Путь | Авторизация |
+|-------|------|-------------|
+| POST | /auth/register | Нет |
+| POST | /auth/login | Нет |
+| POST | /auth/refresh | Нет |
 | POST | /auth/logout | + |
 | GET | /auth/me | + |
-| GET | /places |  |
-| GET | /places/:id |  |
+| GET | /places | Нет |
+| GET | /places/:id | Нет |
 | POST | /places | + |
 | PATCH | /places/:id | + |
 | DELETE | /places/:id | + |
 | POST | /places/:id/moderate | moderator+ |
-| GET | /tags |  |
-| GET | /features |  |
-| GET | /services |  |
+| GET | /tags | Нет |
+| GET | /features | Нет |
+| GET | /services | Нет |
 | POST | /services | + |
 | PATCH | /services/:id | + |
 | DELETE | /services/:id | + |
 | POST | /bookings | + |
 | GET | /bookings/me | + |
 | PATCH | /bookings/:id/cancel | + |
-| GET | /reviews |  |
+| GET | /reviews | Нет |
 | POST | /reviews | + |
-| GET | /users/:id |  |
+| GET | /users/:id | Нет |
 | PATCH | /users/me | + |
 | GET | /admin/users | moderator+ |
 | PATCH | /admin/users/:id | moderator+ |
 | POST | /upload/presigned-url | + |
-| GET | /ws/visitors |  (WebSocket) |
+| GET | /ws/visitors | Нет (WebSocket) |
 
-## Переменные окружения
+## Конфигурация
 
 ### Бэкенд (`backend/.env`)
 
-| Переменная | По умолчанию | Обязательная |
-|-----------|-------------|-------------|
-| APP_ENV | development |  |
-| SERVER_PORT | 8080 |  |
-| DATABASE_URL | postgres://photoplaces:photoplaces_dev@localhost:5432/photoplaces?sslmode=disable | да |
-| REDIS_URL | redis://localhost:6379/0 | да |
-| S3_ENDPOINT | http://localhost:9000 | да |
-| S3_PUBLIC_ENDPOINT | http://localhost:9000 | да |
-| S3_ACCESS_KEY | photoplaces | да |
-| S3_SECRET_KEY | photoplaces_dev | да |
-| S3_BUCKET | photoplaces | да |
-| JWT_SECRET | dev-secret | да |
-| JWT_REFRESH_SECRET | dev-refresh-secret | да |
-| ALLOWED_ORIGINS | http://localhost:3000 |  |
+| Переменная | По умолчанию | Описание |
+|-----------|-------------|---------|
+| APP_ENV | development | Среда |
+| SERVER_PORT | 8080 | Порт |
+| DATABASE_URL | postgres://... | Подключение к БД |
+| REDIS_URL | redis://... | Подключение к Redis |
+| S3_ENDPOINT | http://localhost:9000 | MinIO endpoint |
+| S3_PUBLIC_ENDPOINT | http://localhost:9000 | Публичный S3 endpoint |
+| S3_ACCESS_KEY | photoplaces | S3 Access Key |
+| S3_SECRET_KEY | photoplaces_dev | S3 Secret Key |
+| S3_BUCKET | photoplaces | S3 Bucket |
+| JWT_SECRET | dev-secret | JWT Secret |
+| JWT_REFRESH_SECRET | dev-refresh-secret | JWT Refresh Secret |
+| ALLOWED_ORIGINS | http://localhost:3000 | CORS origins |
 
 ### Фронтенд (`frontend/.env.local`)
 
@@ -174,34 +213,35 @@ make ps       # статус контейнеров
 |-----------|-------------|
 | NEXT_PUBLIC_API_URL | http://localhost:8080/api/v1 |
 | NEXT_PUBLIC_MAP_PROVIDER | yandex |
-| NEXT_PUBLIC_YANDEX_MAPS_API_KEY | (пусто) |
+| NEXT_PUBLIC_YANDEX_MAPS_API_KEY | (задаётся) |
 
 ## Миграции
 
-Миграции накатываются автоматически в продакшене через `migrate/migrate` (см. `deploy/docker-compose.prod.yml`). Локально можно накатить вручную:
+Миграции запускаются автоматически через `docker-entrypoint.sh` при старте бэкенда, либо отдельно:
 
 ```bash
-docker compose run --rm migrations
+docker compose run --rm migrate
 ```
 
 Файлы миграций: `backend/migrations/`
 
 ## Роли пользователей
 
-| Роль | Описание |
-|------|----------|
+| Роль | Права |
+|------|-------|
 | superadmin | Полный доступ |
 | moderator | Модерация мест, управление пользователями |
-| landlord | Добавление и управление своими студиями |
-| executor | Добавление услуг фото/видеосъёмки |
-| customer | Добавление мест для съёмки |
+| landlord | Создание и управление студиями |
+| executor | Создание и управление услугами |
+| customer | Поиск и бронирование |
 
 ## Безопасность
 
 - JWT-аутентификация: access token (15 мин) + refresh token (30 дней)
-- Rate limiting: in-memory, 60 запр/мин на IP
-- CORS: настроен для разрешённых доменов
-- Параметризованные SQL-запросы (pgx)
-- Валидация загружаемых файлов (тип, размер)
-- Мягкое удаление (deleted_at)
-- Проверка владельца ресурса при изменении/удалении
+- Rate limiting: Redis-based, настраивается для каждой группы эндпоинтов
+- CORS: только разрешённые origins
+- Защита от SQL-инъекций: pgx с параметризованными запросами
+- Валидация ввода: go-playground/validator
+- Мягкое удаление (soft delete: deleted_at)
+- Content Security Policy (CSP) через Caddy
+- WebSocket origin check: только разрешённые домены

+ 1 - 1
backend/Dockerfile

@@ -10,7 +10,7 @@ RUN go mod tidy
 RUN CGO_ENABLED=0 GOOS=linux go build -o /photoplaces-api ./cmd/api
 
 FROM alpine:3.19
-RUN apk add --no-cache ca-certificates tzdata postgresql-client
+RUN apk add --no-cache ca-certificates tzdata postgresql-client curl
 RUN wget -qO- https://github.com/golang-migrate/migrate/releases/download/v4.17.1/migrate.linux-amd64.tar.gz | tar xz -C /usr/local/bin migrate
 COPY --from=builder /photoplaces-api /photoplaces-api
 COPY --from=builder /app/migrations /migrations

+ 3 - 3
deploy/deploy-remote.sh

@@ -279,9 +279,9 @@ health_check() {
     while [ $attempt -lt $max_attempts ]; do
         attempt=$((attempt + 1))
 
-        # Проверка Caddy (порт 2019 metrics) — curl есть в alpine
-        if docker compose -f deploy/docker-compose.prod.yml exec -T caddy curl -sf http://localhost:2019/metrics >/dev/null 2>&1; then
-            # Проверка backend через Caddy (HTTP, SSL на Synology)
+        # Проверка Caddy (wget есть в caddy:alpine по умолчанию)
+        if docker compose -f deploy/docker-compose.prod.yml exec -T caddy wget -qO- http://localhost:2019/metrics >/dev/null 2>&1; then
+            # Проверяем backend через Caddy (HTTP, SSL на Synology)
             if curl -sf "http://localhost/api/v1/health" >/dev/null 2>&1; then
                 log_ok "Backend здоров"
                 break

+ 1 - 1
deploy/docker-compose.prod.yml

@@ -34,7 +34,7 @@ services:
       frontend:
         condition: service_healthy
     healthcheck:
-      test: ["CMD", "curl", "-sf", "http://localhost:2019/metrics"]
+      test: ["CMD", "wget", "-qO-", "http://localhost:2019/metrics"]
       interval: 30s
       timeout: 10s
       retries: 3

+ 1 - 1
docker-compose.yml

@@ -87,7 +87,7 @@ services:
       - ./backend:/app
       - backend-modules:/app/node_modules
     healthcheck:
-      test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/api/v1/health"]
+      test: ["CMD", "curl", "-sf", "http://localhost:8080/api/v1/health"]
       interval: 10s
       timeout: 5s
       retries: 5