From cc26d7e75326166d51ce0f801e23291c7c70bfe6 Mon Sep 17 00:00:00 2001 From: "s.zotov" Date: Sun, 12 Apr 2026 20:46:45 +0000 Subject: [PATCH] Add "Docker" --- Docker.md | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 Docker.md diff --git a/Docker.md b/Docker.md new file mode 100644 index 0000000..5944308 --- /dev/null +++ b/Docker.md @@ -0,0 +1,176 @@ +# Docker и деплой + +## Контейнеры + +| Контейнер | Образ | Порт | Описание | +|-----------|-------|------|----------| +| `va-builder` (prod) / `vaaspekter-builder-1` (dev) | `vaaspekter-builder` | 6001→5173 | Vite dev server + backend API | +| `va-email-gen-api` (prod) / `vaaspekter-email-gen-api-1` (dev) | `vaaspekter-email-gen-api` | 8787 | Рендер Pug→HTML | +| `gitea` | `gitea/gitea:latest` | 3000 | Git-сервер (prod only) | + +## DEV окружение (docker-compose.yml) + +```yaml +services: + builder: + build: + context: . + dockerfile: z51-pug-builder/Dockerfile + ports: + - "6001:5173" + volumes: + - ./z51-pug-builder/data:/app/data # данные (persist) + - ./z51-pug-builder/src:/app/src # HMR — изменения мгновенно + - ./z51-pug-builder/vite.config.js:/app/vite.config.js # нужен restart + - ./email-gen:/email-gen # rw + environment: + - EMAIL_GEN_API_URL=http://email-gen-api:8787 + + email-gen-api: + build: + context: ./deploy/email-gen-api + volumes: + - ./email-gen:/workspace/email-gen # rw + - email-gen-node-modules:/workspace/email-gen/node_modules +``` + +### Что менялось → что делать (DEV) + +| Файл | Действие | +|------|----------| +| `src/*.svelte`, `src/*.css`, `lib/*.js` | **Ничего** — HMR подхватит мгновенно | +| `vite.config.js` | `docker compose restart builder` | +| `email-gen/` (pug, миксины) | `docker compose build && docker compose up -d` | +| `package.json` (зависимости) | `docker compose build && docker compose up -d` | +| `Dockerfile` | `docker compose build && docker compose up -d` | +| `data/` (JSON данные) | Автоматически (volume) | + +## PROD окружение (docker-compose.prod.yml) + +```yaml +services: + builder: + image: vaaspekter-builder # предсобранный образ! + container_name: va-builder + environment: + - EMAIL_GEN_API_URL=http://email-gen-api:8787 + - NODE_OPTIONS=--max-old-space-size=3072 + ports: + - "127.0.0.1:6001:5173" + volumes: + - ./data:/app/data # только данные + - ./email-gen:/email-gen # только шаблоны + restart: unless-stopped + + email-gen-api: + image: vaaspekter-email-gen-api + container_name: va-email-gen-api + volumes: + - ./email-gen:/workspace/email-gen + restart: unless-stopped +``` + +### Ключевое отличие PROD от DEV + +На проде **НЕТ монтирования** `src/`, `vite.config.js`, `package.json` — всё **запечено в Docker-образ**. + +**Для ЛЮБОГО изменения кода нужна пересборка образа.** + +## Процедура деплоя + +### ⚠️ ВАЖНО: платформа + +Mac — Apple Silicon (ARM), сервер — x86_64. **Всегда** собирать с `--platform linux/amd64`! + +Без этого флага → `exec format error` при запуске контейнера. + +### Пошагово + +```bash +# 1. Собрать образ для x86 +docker build --platform linux/amd64 -f z51-pug-builder/Dockerfile -t vaaspekter-builder . + +# 2. Экспортировать в tar.gz (~217 МБ) +docker save vaaspekter-builder | gzip > /tmp/va-builder.tar.gz + +# 3. Загрузить на сервер +scp /tmp/va-builder.tar.gz root@45.144.221.96:/opt/va/ + +# 4. На сервере: загрузить и перезапустить +ssh root@45.144.221.96 +cd /opt/va +docker load < va-builder.tar.gz +docker compose -f docker-compose.prod.yml up -d builder +``` + +### Деплой email-gen-api (аналогично) + +```bash +docker build --platform linux/amd64 -f deploy/email-gen-api/Dockerfile deploy/email-gen-api/ -t vaaspekter-email-gen-api +docker save vaaspekter-email-gen-api | gzip > /tmp/va-email-gen-api.tar.gz +scp /tmp/va-email-gen-api.tar.gz root@45.144.221.96:/opt/va/ +# на сервере: +docker load < va-email-gen-api.tar.gz +docker compose -f docker-compose.prod.yml up -d email-gen-api +``` + +## Пути на сервере + +| Путь | Описание | +|------|----------| +| `/opt/va/docker-compose.prod.yml` | Prod compose файл | +| `/opt/va/data/` | Пользовательские данные (volume) | +| `/opt/va/email-gen/` | Pug-шаблоны (volume) | +| `/opt/va/va-builder.tar.gz` | Последний образ builder | +| `/opt/va/va-email-gen-api.tar.gz` | Последний образ email-gen-api | +| `/etc/nginx/sites-enabled/aspekter` | Nginx конфиг | +| `/opt/va/landing/` | Лендинг aspekter.ru | +| `/opt/gitea/` | Gitea data | + +## Nginx + +Файл: `/etc/nginx/sites-enabled/aspekter` + +### va.aspekter.ru → builder +```nginx +server { + listen 443 ssl; + server_name va.aspekter.ru; + # SSL Let's Encrypt + + location ~* (\.env|\.git|\.php|\.sql|passwd|wp-admin|...) { + return 444; # блокировка сканеров + } + + location / { + proxy_pass http://127.0.0.1:6001; + # WebSocket support для HMR + } +} +``` + +### aspekter.ru → лендинг (для будущего проекта) +### git.aspekter.ru → Gitea + +## Очистка Docker + +После нескольких деплоев накапливаются старые образы (до 25 ГБ!): + +```bash +docker image prune -a -f +``` + +## Dockerfile (z51-pug-builder) + +```dockerfile +FROM node:20-alpine +WORKDIR /app +COPY z51-pug-builder/package*.json ./ +RUN npm install +COPY z51-pug-builder/ ./ +COPY email-gen/ /email-gen/ +EXPOSE 5173 +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "5173"] +``` + +Важно: `email-gen/` копируется в образ, но на проде перекрывается volume mount. Копия в образе — fallback.