From 60813cf019098bc0d71a7df105662f4a14c018df Mon Sep 17 00:00:00 2001 From: erjemin Date: Sat, 28 Mar 2026 17:49:22 +0300 Subject: [PATCH] =?UTF-8?q?mod:=20=D0=B2=D1=81=D0=B5=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20deployment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEPLOYMENT.md | 152 ++++++++++++++++++ Dockerfile | 9 +- README.md | 61 +++++-- .../nginx/cadpoint1998--external-nginx.conf | 84 ++++++++++ docker-compose.prod.yml | 91 +++++++++++ docker-compose.yml | 1 + 6 files changed, 383 insertions(+), 15 deletions(-) create mode 100644 DEPLOYMENT.md create mode 100644 config/nginx/cadpoint1998--external-nginx.conf create mode 100644 docker-compose.prod.yml diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..77c27fe --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,152 @@ +# Развёртывание cadpoint1998 на продакшене + +## 📋 Архитектура + +```txt +┌─────────────────────────────────────────────────────────┐ +│ Хост (продакшен) │ +├─────────────────────────────────────────────────────────┤ +│ │ +│ Внешний nginx (на хосте или в контейнере) │ +│ ├─ Прослушивает: 0.0.0.0:80 (public) │ +│ ├─ Обслуживает: tmp.cadpoint.ru │ +│ └─ Проксирует → 127.0.0.1:8030 │ +│ ↓ │ +│ Docker контейнер cadpoint1998 │ +│ ├─ Прослушивает: 0.0.0.0:8030 (internal) │ +│ ├─ Служит: статический HTML (KOI8-R) │ +│ └─ Watchtower следит за обновлениями │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +## 🚀 Шаги развёртывания + +### 1. Подготовка на локальной машине + +```bash +# Убедись, что коммиты в `main` +git add . +git commit -m "Add external nginx config and deployment script" +git push origin main + +# Создаёшь тег для деплоя +git tag v1.0.0 +git push origin v1.0.0 + +# Gitea Workflow запустится автоматически и соберёт образ +``` + +### 2. Подготовка сервера (вход по SSH) + +А. Создать папку для проекта (замените `<папка-прилолжений>` и `<прилолжение>` на свои значения): +```bash +# На продакшене (как e-serg или sudo) +mkdir -p ~/<папка-прилолжений>/<прилолжение> +cd ~/<папка-прилолжений>/<прилолжение> +``` + +Б. Создайте в ней каталог для конфигурационных файлов nginx: +```bash +mkdir -p config/nginx +``` + +В. Создать файл `docker-compose.yml`, поместите в нее содержимое из `docker-compose.prod.yml` (копи-паст из репозитрия). + +Г. Создайте файл для переменных окружения проекта `.env` и заполните его (см. образец файла `.env.example` в репозитории). + + +### 3. Запуск контейнера на сервере + +Запусти контейнер (конфиги nginx скопируются автоматически) +``` +sudo docker compose up -d +``` + +# Контейнер выведет при запуске: +# 📋 Копирование внешнего nginx конфига на хост... +# ✅ Пример nginx-конфика создан в ./config/nginx/cadpoint1998--external-nginx.conf.sample +# ✅ Боевой nginx-конфиг создан в ./config/nginx/cadpoint1998--external-nginx.conf + +### 4. Настройка внешнего nginx на хосте + +Сделай символическую ссылку на конфиг в папке nginx (или скопируй его): +```bash +sudo ln -s ~/<папка-прилолжений>/<прилолжение>/config/nginx/cadpoint1998--external-nginx.conf /etc/nginx/sites-enabled +``` + +Проверь, что конфиг корректный и nginx может его загрузить: +```bash +sudo nginx -t +``` + +Если ошибок нет и все `ok` перезапусти сервис nginx: +```bash +sudo systemctl reload nginx +``` + +Проверь, что сайт отвечает по адресу `http://tmp.cadpoint.ru` (не забудь настроить DNS): +```bash +curl -v http://tmp.cadpoint.ru/index.htm +``` + +### 5. Настройка сертификата SSL (если нужен) + +``` +sudo certbot --nginx -d tmp.cadpoint.ru +``` + +## 🔄 Обновление сайта + +Когда ты создашь и запушишь новый тег в репозиторий: + +```bash +git tag v1.0.1 +git push origin v1.0.1 +``` + +**Автоматически происходит:** +1. Gitea запускает workflow (docker-publish.yaml) +2. Собирается новый образ и пушится в реестр как `v1.0.1` и `latest` +3. На сервере Watchtower каждые 30 минут проверяет реестр +4. Находит новый образ и автоматически: + - Pulls новый образ + - Стопит старый контейнер + - Запускает новый контейнер + - Копирует конфиги (если это первый запуск) + +**Ручной pull (если не хочешь ждать Watchtower):** +```bash +cd ~/<папка-прилолжений>/<прилолжение> +sudo docker compose pull +sudo docker compose up -d +``` + +## ⚠️ Важно про конфиги + +При каждом запуске контейнера он копирует конфиги из образа на хост: + +1. **Первый запуск**: оба конфига копируются + - `.sample` (свежий из контейнера, для справки) + - основной (для использования в nginx) + +2. **Последующие запуски**: только `.sample` обновляется + - Основной конфиг НЕ перезаписывается + - Это защищает ручные правки (например, после certbot) + +## 📊 Мониторинг + +```bash +# Логи контейнера +sudo docker compose logs -f cadpoint1998-site | tail -100 + +# Логи Watchtower +sudo docker compose logs -f cadpoint1998-watchtower | tail -50 + +# Проверка доступности (с хоста) +curl -v http://127.0.0.1:8030/index.htm + +# Проверка через внешний nginx +curl -v -H 'Host: tmp.cadpoint.ru' http://localhost +``` + diff --git a/Dockerfile b/Dockerfile index 3801f0f..79d804d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ FROM nginx:alpine # Удаляем стандартный nginx конфиг (по умолчанию) RUN rm /etc/nginx/conf.d/default.conf -# Копируем custom конфиг cadpoint1998 как default +# Копируем custom конфиг cadpoint1998 как default (для внутреннего nginx) # Это обеспечивает правильную кодировку KOI8-R и маршрутизацию COPY config/nginx/cadpoint1998--internal-nginx.conf /etc/nginx/conf.d/default.conf @@ -15,10 +15,9 @@ COPY config/nginx/cadpoint1998--internal-nginx.conf /etc/nginx/conf.d/default.co # Архив содержит исторический контент (не обновляется), поэтому полностью в образ COPY html/ /usr/share/nginx/html/ -# Health check: проверяем доступность сайта через nginx -# Используется Docker для определения статуса контейнера и orchestration-системами -HEALTHCHECK --interval=120s --timeout=3s --start-period=5s --retries=3 \ - CMD wget --quiet --tries=1 --spider http://localhost/index.htm || exit 1 +# Копируем внешний nginx конфиг для экспорта на хост (через volume) +# Это нужно для настройки reverse-proxy на хосте +COPY config/nginx/cadpoint1998--external-nginx.conf /tmp/cadpoint1998--external-nginx.conf.source # Экспозируем порт 80 (внутренний, проксируется внешним nginx на хосте) EXPOSE 80 diff --git a/README.md b/README.md index 9f9cdfb..b5a0711 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## ВСЕ о САПР (CAD/CAM/CAE Archive) -Архивная версия исторического русскоязычного сайта о системах автоматизированного проектирования (САПР), созданного в 1998–1999 годах. Развернуто, для обозрения по адресу: [1998.cadpoint.ru/](https://1998.cadpoint.ru/). +Это архивная версия исторического русскоязычного сайта о системах автоматизированного проектирования (САПР), созданного в 1998–1999 годах для "Русской Промышленной Компании" (РПК). Развернуто по адресу: [1998.cadpoint.ru](https://1998.cadpoint.ru/). **Осторожно:** - фреймы (frameset) и meta-refresh; @@ -63,12 +63,17 @@ Content-Type: text/html; charset=koi8-r │ ├── images/ # Баннеры и логотипы │ ├── robots.txt # Инструкции для поисковых роботов │ └── favicon.* # Иконки браузера -├── configs/ # Конфигурация nginx -│ ├── cadpoin-ru_1998.conf -│ └── cadpoin-ru_1998_w_ssl.conf +├── config/ +│ └── nginx/ +│ ├── cadpoint1998--internal-nginx.conf # Конфиг внутреннего nginx (в контейнере) +│ └── cadpoint1998--external-nginx.conf # Конфиг внешнего nginx (на хосте, для reverse-proxy) +├── Dockerfile # Контейнеризация архива (nginx + HTML + конфиги) +├── docker-compose.yml # Dev-конфиг (локальное тестирование) +├── docker-compose.prod.yml # Prod-конфиг (продакшен с Watchtower) ├── .gitignore # Исключение из репозитория ├── .gitattributes # Правила кодировки и обработки файлов ├── .editorconfig # Рекомендации для редакторов +├── .env.example # Пример переменных окружения └── README.md # Этот файл ``` @@ -115,17 +120,53 @@ Content-Type: text/html; charset=koi8-r Проект может быть расширен в отдельных ветках: -- **`legacy-1998`** — архивная версия в оригинальном виде (текущая ветка) -- **`main`** — версия с миграцией: - - Развертывание в Docker - - Возможно что-то еще (пока не знаю) +- **`legacy-1998`** — архивная версия в оригинальном виде (ветка сохранения истории) +- **`main`** — современная версия с контейнеризацией (текущая ветка): + - ✅ Docker контейнеризация (nginx:alpine) + - ✅ docker-compose для dev и prod + - ✅ Watchtower для автоматических обновлений образа + - ✅ Gitea CI/CD пайплайн (автосборка при тегировании) + - ✅ Support для SSL/TLS (через certbot) + - ✅ Reverse-proxy через внешний nginx + +## Контейнеризация (2026) + +Архив полностью перемещён в Docker контейнер с современной инфраструктурой: + +### Что включено + +- **Образ**: `git.cube2.ru/erjemin/1998-cad-cadpoint:latest` (nginx:alpine) +- **Содержимое образа**: + - nginx (web-сервер) + - Конфиг для внутреннего nginx (с поддержкой KOI8-R) + - Весь архив HTML сайта (KOI8-R) + - Конфиг для внешнего nginx (для reverse-proxy на хосте) + +### Как запустить + +**Development (локально):** +```bash +docker-compose up --build +# Сайт доступен на http://127.0.0.1:8030 +``` + +**Production (на сервере):** +```bash +docker-compose -f docker-compose.prod.yml up -d +# Watchtower автоматически следит за обновлениями образа +# Сайт проксируется через внешний nginx на хосте +``` + +### Детальная документация + +См. [DEPLOYMENT.md](DEPLOYMENT.md) для полной инструкции по развёртыванию на продакшене. ## Контакты и лицензия Автор: *Sergei Erjemin* (это я) Контакт: `erjemin@gmail.com` -Архив сохранён и перенесён в современную инфраструктуру в 2026 году. +Архив сохранён и перенесён в современную инфраструктуру (Docker) в 2026 году. --- -**Последнее обновление:** March 27, 2026 +**Последнее обновление:** March 28, 2026 (добавлена контейнеризация) diff --git a/config/nginx/cadpoint1998--external-nginx.conf b/config/nginx/cadpoint1998--external-nginx.conf new file mode 100644 index 0000000..d66431e --- /dev/null +++ b/config/nginx/cadpoint1998--external-nginx.conf @@ -0,0 +1,84 @@ +# Внешний nginx конфиг для проксирования к контейнеру cadpoint1998 +# Это конфиг для ХОСТА (не внутри контейнера) +# +# Используется переменная /home/e-serg/docker-app/cadpoint1998-site из .env +# Генерируется из этого файла через: sed "s|\/home/e-serg/docker-app/cadpoint1998-site|$HOST_PROJECT_PATH|g" \ +# config/nginx/cadpoint1998--external-nginx.example > config/nginx/cadpoint1998--external-nginx.conf + +upstream cadpoint1998_backend { + # Контейнер слушает на localhost:8030 (из docker-compose.prod.yml) + server 127.0.0.1:8030; + keepalive 32; +} + +server { + listen 80; + listen [::]:80; + server_name tmp.cadpoint.ru; + + # Редирект HTTP → HTTPS (cerbot добавит SSL позже) + # Пока оставляем HTTP для тестирования + # Раскомментируй после добавления SSL: + # return 301 https://$server_name$request_uri; + + # Логи для этого виртуального хоста + # --- ЛОГИ --- + access_log /var/log/nginx/cadpoint1998.access.log; + error_log /var/log/nginx/cadpoint1998.error.log warn; + + # Основной блок проксирования + location / { + # Проксируем все запросы в контейнер + proxy_pass http://cadpoint1998_backend; + + # Сохраняем оригинальный хост в заголовке (важно для правильной работы контейнера) + 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; + + # Keepalive для улучшения производительности + proxy_http_version 1.1; + proxy_set_header Connection ""; + + # Timeouts для длительных запросов + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # Буферизация (для архивного сайта можно отключить если мало памяти) + # proxy_buffering off; + proxy_buffering on; + proxy_buffer_size 4k; + proxy_buffers 8 4k; + } + + # Кэширование статических файлов (HTML, GIF, CSS, JS, иконки) + location ~* \.(htm|html|gif|png|jpe?g|svg|ico|css|js|woff|woff2|ttf|eot)$ { + proxy_pass http://cadpoint1998_backend; + proxy_set_header Host $host; + + # Кэш в браузере на 7 дней для статики (архив не меняется) + expires 7d; + add_header Cache-Control "public, max-age=604800, immutable"; + + # Логирование отключаем для статики (шум в логах) + access_log off; + } + + # Health check для мониторинга (внутренний эндпоинт) + location = /health { + access_log off; + default_type text/plain; + return 200 "OK\n"; + } + + # Запретить доступ к скрытым файлам + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } +} + + diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..68de5f6 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,91 @@ +# Файл для продакшена (использует только собранный образ, без локальных volume) +# Для разработки используй docker-compose.yml + +services: + cadpoint1998: + # В продакшене используем заранее собранный образ (не build) + image: git.cube2.ru/erjemin/1998-cad-cadpoint:latest + + # Имя контейнера для идентификации + container_name: cadpoint1998-site + + # Политика перезагрузки: всегда перезагружаемся при сбое + restart: always + + # Метки для Watchtower (авто-обновление) + labels: + - "com.centurylinklabs.watchtower.scope=cadpoint1998-scope" + + # Переменные окружения + env_file: + - .env + + # Volume для экспорта конфигов из контейнера на хост + # Контейнер копирует nginx конфиг при запуске для настройки reverse-proxy на хосте + volumes: + - ./config/nginx:/tmp/nginx_configs:rw # контейнер пишет сюда конфиги + + # Command: скрипт для копирования конфигов из контейнера на хост при запуске + # Встроенный entrypoint nginx:alpine (/docker-entrypoint.sh) запустит это как команду + command: > + sh -c " + echo '📋 Копирование внешнего nginx конфига на хост...' && + cp /tmp/cadpoint1998--external-nginx.conf.source /tmp/nginx_configs/cadpoint1998--external-nginx.conf.sample && + echo '✅ Пример nginx-конфига создан в ./config/nginx/cadpoint1998--external-nginx.conf.sample (свежий из контейнера)' && + if [ ! -f /tmp/nginx_configs/cadpoint1998--external-nginx.conf ]; then + cp /tmp/cadpoint1998--external-nginx.conf.source /tmp/nginx_configs/cadpoint1998--external-nginx.conf && + echo '✅ Боевой nginx-конфиг создан в ./config/nginx/cadpoint1998--external-nginx.conf (свежий из контейнера)' + else + echo '⏭️ Боевой nginx-конфиг оставлен без изменений.' + fi + " + + # В продакшене слушаем на внутреннем адресе (проксируется через внешний nginx) + ports: + - "127.0.0.1:8030:80" + + # Логирование в JSON-файлы (для сбора логов через docker logs) + logging: + driver: "json-file" + options: + max-size: "10m" # больше лимит в продакшене для логирования + max-file: "1" # храним 1 файл лога + labels: "service=cadpoint1998" + + # Сеть для взаимодействия с другими контейнерами + networks: + - cadpoint1998-network + + + # WATCHTOWER ДЛЯ АВТОМАТИЧЕСКОГО ОБНОВЛЕНИЯ ОБРАЗОВ ИЗ РЕЕСТРА + watchtower: + image: containrrr/watchtower + container_name: cadpoint1998-watchtower + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # Переменные окружения + env_file: + - .env + environment: + - DOCKER_API_VERSION=1.44 + # Берем учетные данные из .env файла + - REPO_USER=${REPO_USER} + - REPO_PASS=${REPO_PASS} + # Ограничиваем область видимости только этим проектом + - WATCHTOWER_SCOPE=cadpoint1998-scope + # Если нужно указать реестр явно (обычно watchtower сам понимает из имени образа) + # - WATCHTOWER_REGISTRY_URL=git.cube2.ru + command: --interval 1800 --cleanup # Проверять каждые 30 минут + logging: + driver: "json-file" + options: + max-size: "1m" + max-file: "1" + networks: + - cadpoint1998-network + +# Bridge-сеть для координации сервисов +networks: + cadpoint1998-network: + driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index eaafa93..002bff6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,6 +35,7 @@ services: networks: - cadpoint1998-network + # Определяем пользовательскую bridge-сеть для контейнеров networks: cadpoint1998-network: