diff --git a/deploy/.dockerignore b/deploy/.dockerignore new file mode 100644 index 00000000..49bd91fe --- /dev/null +++ b/deploy/.dockerignore @@ -0,0 +1,35 @@ +# Git +.git +.gitignore + +# Node +node_modules +npm-debug.log +package-lock.json + +# Development +*.md +!.gitignore + +# Build artifacts (will be copied from host) +# dist/ не включаем - он будет скопирован из хоста + +# Testing +test/ +functional-tests/ + +# Source +src/ +gulp/ +vendors/ +assets/ + +# App (Express.js - не нужен для статической версии) +app/ + +# Config (будет применен при сборке) +config.local.json + +# Misc +.DS_Store +*.log diff --git a/deploy/Dockerfile b/deploy/Dockerfile new file mode 100644 index 00000000..9fc7b074 --- /dev/null +++ b/deploy/Dockerfile @@ -0,0 +1,16 @@ +FROM nginx:alpine + +# Удалить дефолтную конфигурацию nginx +RUN rm /etc/nginx/conf.d/default.conf + +# Копируем кастомную конфигурацию nginx +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Копируем собранные файлы (предполагается, что они уже с примененным конфигом) +COPY dist/ /usr/share/nginx/html/ + +# Открываем порт 80 +EXPOSE 80 + +# Запускаем nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 00000000..8c650e90 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,145 @@ +# Deployment Guide + +Переход на статическую раздачу через nginx. + +## Архитектура + +Проект теперь раздается как статические файлы через nginx без необходимости в Express-сервере. Конфигурация применяется на этапе сборки в CI. + +## Файлы + +- `Dockerfile` — образ на базе nginx:alpine +- `nginx.conf` — конфигурация nginx с gzip и кэшированием +- `apply-config.sh` — скрипт для применения конфигурации к собранным файлам + +## Сборка в CI + +### 1. Собрать проект + +```bash +npm run build +``` + +Это создаст файлы в папке `dist/`: +- `index.html` +- `loader.js` +- `js/script.*.js` +- `css/styles.*.*.css` +- и другие статические файлы + +### 2. Применить конфигурацию + +```bash +# Установка прав на скрипт (если нужно) +chmod +x deploy/apply-config.sh + +# Применение конфига +BASE_URL="//maps.api.2gis.ru/2.0" ./deploy/apply-config.sh dist +``` + +Или через Docker: + +```bash +docker run --rm -v $(pwd):/app -w /app \ + -e BASE_URL="//maps.api.2gis.ru/2.0" \ + bash:alpine ./deploy/apply-config.sh dist +``` + +### 3. Собрать Docker-образ + +```bash +docker build -t 2gis-mapsapi:latest -f deploy/Dockerfile . +``` + +### 4. Запуск + +```bash +docker run -d -p 8080:80 --name mapsapi 2gis-mapsapi:latest +``` + +Сервер будет доступен по адресу `http://localhost:8080` + +## Переменные окружения + +При применении конфигурации можно использовать следующие переменные: + +| Переменная | Описание | Значение по умолчанию | +|------------|----------|----------------------| +| `BASE_URL` | Базовый URL API | `//maps.api.2gis.ru/2.0` | +| `PROTOCOL` | Протокол | `http:` | +| `WEB_API_KEY` | API ключ | - | +| `WEB_API_VERSION` | Версия API | `2.0` | +| `DIST_DIR` | Путь к директории с файлами | `dist` | + +## Пример CI/CD (GitHub Actions) + +```yaml +name: Build and Deploy + +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '14' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Apply config + run: | + chmod +x deploy/apply-config.sh + BASE_URL="${{ secrets.BASE_URL }}" ./deploy/apply-config.sh dist + + - name: Build Docker image + run: docker build -t mapsapi:${{ github.sha }} -f deploy/Dockerfile . + + - name: Push to registry + run: | + # Добавьте шаги для пуша в ваш registry + docker push mapsapi:${{ github.sha }} +``` + +## Разница с предыдущей версией + +### Было (Express.js) +- Сервер на Node.js + Express +- Динамическая подстановка конфига при каждом запросе +- Чтение файлов с диска при старте +- Порты 3000 по умолчанию + +### Стало (nginx) +- Статическая раздача через nginx +- Конфиг применяется один раз при сборке +- Все файлы уже готовы к раздаче +- Порт 80 (стандартный для nginx) +- Лучшая производительность и кэширование +- Меньше ресурсов (nginx vs Node.js) + +## Health Check + +Эндпоинт `/healthcheck` возвращает `200 OK` для проверки работоспособности контейнера. + +```bash +curl http://localhost:8080/healthcheck +``` + +## Миграция + +Если вы используете старый Express-сервер: + +1. Обновите переменные окружения в вашем оркестраторе (Kubernetes, Docker Swarm и т.д.) +2. Измените порт с 3000 на 80 (или настройте прокси) +3. Убедитесь, что конфигурация применена к файлам перед сборкой образа diff --git a/deploy/apply-config.sh b/deploy/apply-config.sh new file mode 100755 index 00000000..d0282703 --- /dev/null +++ b/deploy/apply-config.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Скрипт для применения конфигурации к собранным файлам +# Используется в CI перед сборкой Docker-образа + +set -e + +# Параметры +DIST_DIR="${1:-dist}" +BASE_URL="${BASE_URL:-//maps.api.2gis.ru/2.0}" +PROTOCOL="${PROTOCOL:-http:}" +WEB_API_KEY="${WEB_API_KEY:-}" +WEB_API_VERSION="${WEB_API_VERSION:-2.0}" + +echo "Applying configuration to files in ${DIST_DIR}..." +echo "BASE_URL: ${BASE_URL}" +echo "PROTOCOL: ${PROTOCOL}" + +# Функция для замены плейсхолдеров в файле +apply_replacements() { + local file="$1" + + if [ ! -f "$file" ]; then + echo "File not found: $file" + return 1 + fi + + # Создаем временный файл + local tmp_file="${file}.tmp" + + # Читаем файл и применяем замены + sed \ + -e "s|__BASE_URL__|${BASE_URL}|g" \ + -e "s|__ORIGINAL_BASE_URL__|${BASE_URL}|g" \ + "$file" > "$tmp_file" + + # Заменяем оригинальный файл + mv "$tmp_file" "$file" + + echo "Applied config to: $file" +} + +# Применяем к index.html +if [ -f "${DIST_DIR}/index.html" ]; then + apply_replacements "${DIST_DIR}/index.html" +else + echo "Warning: ${DIST_DIR}/index.html not found" +fi + +# Применяем к loader.js (если он есть в dist) +if [ -f "${DIST_DIR}/loader.js" ]; then + apply_replacements "${DIST_DIR}/loader.js" +else + echo "Warning: ${DIST_DIR}/loader.js not found" +fi + +echo "Configuration applied successfully!" diff --git a/deploy/nginx.conf b/deploy/nginx.conf new file mode 100644 index 00000000..1ae48a62 --- /dev/null +++ b/deploy/nginx.conf @@ -0,0 +1,37 @@ +server { + listen 80; + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + # Gzip сжатие + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + gzip_min_length 1000; + + # Кэширование статических файлов + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Кэширование HTML + location ~* \.html$ { + expires -1; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + } + + # Основная локация + location / { + try_files $uri $uri/ /index.html; + } + + # Health check endpoint + location /healthcheck { + access_log off; + return 200 "OK"; + add_header Content-Type text/plain; + } +}