chore: delete dead templates, remove duplicate MinIO task, update CLAUDE.md
Some checks failed
CI/CD / deploy (push) Failing after 10m23s
CI/CD / syntax-check (push) Successful in 1m9s

- Delete grafana provisioning templates (grafana/loki removed)
- Delete env.outline.j2 (Outline replaced by Docmost)
- Remove duplicate MinIO bucket creation Ansible task (plane-createbuckets
  compose service handles this more reliably)
- Update CLAUDE.md: single server, correct domains, remove tools references
This commit is contained in:
jack 2026-03-27 19:24:14 +07:00
parent 5f44441bd1
commit ccd7c44293
6 changed files with 24 additions and 132 deletions

View file

@ -18,9 +18,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1. **Только через CI/CD** — никогда не фикси что-либо вручную на сервере. Внеси изменение, закоммить, запуши → CI/CD сам задеплоит. Потом проверь результат.
2. **Syncthing удалён навсегда** — не упоминать, не предлагать вернуть.
3. **Секреты** — все в `inventory/group_vars/all/vault.yml` с префиксом `vault_`. В `main.yml` только алиасы `"{{ vault_* }}"`. Никаких plaintext секретов.
4. **Синтаксис-чек перед коммитом**`ansible-playbook playbooks/deploy.yml --syntax-check`.
5. **Обновляй доки** — после каждого изменения обновляй `docs/STATUS.md`, `docs/BACKLOG.md` или `docs/DECISIONS.md`.
3. **Vaultwarden удалён навсегда** — не упоминать, не предлагать вернуть.
4. **Tools-сервер удалён навсегда** — один сервер `main`. Мониторинг через UptimeRobot (внешний).
5. **Секреты** — все в `inventory/group_vars/all/vault.yml` с префиксом `vault_`. В `main.yml` только алиасы `"{{ vault_* }}"`. Никаких plaintext секретов.
6. **Синтаксис-чек перед коммитом**`ansible-playbook playbooks/deploy.yml --syntax-check`.
7. **Обновляй доки** — после каждого изменения обновляй `docs/STATUS.md`, `docs/BACKLOG.md` или `docs/DECISIONS.md`.
---
@ -34,21 +36,14 @@ echo "yourpassword" > ~/.vault-password-file && chmod 600 ~/.vault-password-file
# Первичная настройка сервера (от root)
ansible-playbook playbooks/bootstrap.yml -u root
# Деплой основного сервера
# Деплой
ansible-playbook playbooks/deploy.yml
# Деплой tools-сервера
ansible-playbook playbooks/tools.yml
# Деплой всего сразу
ansible-playbook playbooks/site.yml
# Редактировать секреты
ansible-vault edit inventory/group_vars/all/vault.yml
# Проверка синтаксиса (без подключения к серверу)
ansible-playbook playbooks/deploy.yml --syntax-check
ansible-playbook playbooks/tools.yml --syntax-check
# Dry run
ansible-playbook playbooks/deploy.yml --check
@ -65,8 +60,7 @@ ansible-playbook playbooks/deploy.yml --tags backup
## Архитектура
**Серверы:**
- `main` (87.249.49.32) — Traefik, Forgejo, Plane, Vaultwarden, Мониторинг, CI/CD runner
- `tools` (85.193.83.9) — Outline wiki, n8n, docker-mailserver, SnappyMail
- `main` (87.249.49.32) — единственный сервер: Traefik, Forgejo, Plane, Docmost, n8n, CI/CD runner
**Трафик:** Internet → Cloudflare proxy → Traefik (80/443) → сервисы.
Порты 80/443 открыты только для IP-адресов Cloudflare (UFW whitelist).
@ -74,14 +68,13 @@ ansible-playbook playbooks/deploy.yml --tags backup
**Секреты:** `inventory/group_vars/all/vault.yml` (Ansible Vault AES-256).
Пароль vault: `~/.vault-password-file``.gitignore`, никогда не коммитить).
**TLS:** Wildcard сертификат `*.csrx.ru` через Cloudflare DNS-01 (Traefik certresolver).
**TLS:** Wildcard сертификат `*.walava.io` через Cloudflare DNS-01 (Traefik certresolver).
**Роли:**
- `base` — UFW, fail2ban, sshd, deploy user
- `docker` — Docker CE + Compose plugin
- `services` — основной стек (templates → `/opt/services/`, docker compose up)
- `tools` — tools-стек (templates → `/opt/tools/`, docker compose up)
- `backup` — backup каждые 6 часов → S3 (`visual-backup/data/`), только для main-сервера
- `backup` — backup каждые 6 часов → S3 (`walava-backup/`), только для main-сервера
**Шаблоны → файлы на сервере:**
- `roles/services/templates/docker-compose.yml.j2``/opt/services/docker-compose.yml`
@ -89,16 +82,11 @@ ansible-playbook playbooks/deploy.yml --tags backup
- `roles/services/templates/traefik/traefik.yml.j2``/opt/services/traefik/traefik.yml`
- `roles/services/templates/traefik/dynamic/routes.yml.j2``/opt/services/traefik/dynamic/routes.yml`
**Добавление нового сервиса на main:**
**Добавление нового сервиса:**
1. Добавить контейнер в `docker-compose.yml.j2` в сеть `backend`
2. Добавить роутер в `routes.yml.j2` (НЕ docker labels — используется file provider)
3. Добавить домен в `inventory/group_vars/all/main.yml`
4. Добавить DNS A-запись в Cloudflare
**Добавление сервиса на tools:**
1. Добавить контейнер в `roles/tools/templates/docker-compose.yml.j2`
2. Добавить роутер в `routes.yml.j2` с `url: "http://{{ ip_tools }}:PORT"`
3. Открыть порт в UFW (задача в `roles/tools/tasks/main.yml`)
4. Добавить DNS A-запись в Cloudflare (через API или вручную)
---
@ -107,6 +95,18 @@ ansible-playbook playbooks/deploy.yml --tags backup
Push в `master` → Forgejo Actions запускает:
```
ansible-playbook playbooks/deploy.yml
ansible-playbook playbooks/tools.yml
```
Workflow: `.forgejo/workflows/deploy.yml`
---
## Домены (все на walava.io)
| Сервис | Домен |
|--------|-------|
| Forgejo | git.walava.io |
| Plane | hub.walava.io |
| Docmost | wiki.walava.io |
| n8n | auto.walava.io |
| Traefik dashboard | traefik.walava.io |
| Landing | walava.io |

View file

@ -39,40 +39,6 @@
until: compose_result is succeeded
notify: Stack deployed
- name: Wait for MinIO to be ready
ansible.builtin.command: docker exec plane-minio curl -sf http://localhost:9000/minio/health/live
register: minio_ready
changed_when: false
retries: 15
delay: 10
until: minio_ready.rc == 0
- name: Get plane-internal network name
ansible.builtin.shell: >
docker inspect plane-minio |
python3 -c "import sys,json; d=json.load(sys.stdin)[0];
print([k for k in d['NetworkSettings']['Networks'] if 'plane-internal' in k][0])"
register: plane_internal_network
changed_when: false
- name: Create MinIO uploads bucket via mc container
# minio/mc entrypoint = mc, поэтому нужен --entrypoint sh
# access-key = имя пользователя MinIO (plane-minio), secret-key = пароль
ansible.builtin.shell: |
docker run --rm \
--entrypoint sh \
--network "{{ plane_internal_network.stdout | trim }}" \
-e MC_ACCESS="{{ plane_minio_password }}" \
minio/mc:RELEASE.2025-05-21T01-59-54Z \
-c 'mc alias set local http://plane-minio:9000 plane-minio "{{ plane_minio_password }}" 2>/dev/null \
&& mc mb --ignore-existing local/uploads \
&& echo "Bucket created or already exists"'
register: minio_bucket
changed_when: "'Bucket created' in minio_bucket.stdout"
retries: 5
delay: 10
until: minio_bucket.rc == 0
# ── Forgejo Discord webhooks (deploys → #deploys channel) ────────────────────
- name: Check Discord webhooks on Forgejo repos
ansible.builtin.uri:

View file

@ -1,41 +0,0 @@
# Outline env — generated by Ansible
NODE_ENV=production
SECRET_KEY={{ outline_secret_key }}
UTILS_SECRET={{ outline_utils_secret }}
# Database
DATABASE_URL=postgres://outline:{{ outline_db_password }}@outline-db:5432/outline
PGSSLMODE=disable
# Redis
REDIS_URL=redis://outline-redis:6379
# App URL
URL=https://{{ domain_wiki }}
PORT=3000
# S3 file storage (Timeweb Object Storage)
AWS_ACCESS_KEY_ID={{ s3_access_key }}
AWS_SECRET_ACCESS_KEY={{ s3_secret_key }}
AWS_REGION=ru-1
AWS_S3_UPLOAD_BUCKET_NAME=walava-outline
AWS_S3_UPLOAD_BUCKET_URL=https://s3.twcstorage.ru
AWS_S3_FORCE_PATH_STYLE=true
FILE_STORAGE=s3
# Auth
AUTH_PROVIDERS=email
# SMTP via Resend (direct — main server has outbound SMTP)
SMTP_HOST=smtp.resend.com
SMTP_PORT=587
SMTP_USERNAME=resend
SMTP_PASSWORD={{ resend_api_key }}
SMTP_FROM_EMAIL=noreply@{{ domain_base }}
SMTP_FROM_NAME=Visual Wiki
SMTP_SECURE=false
# Optional
DEFAULT_LANGUAGE=en_US
RATE_LIMITER_ENABLED=true
ENABLE_UPDATES=false

View file

@ -1,13 +0,0 @@
# Generated by Ansible — do not edit manually
apiVersion: 1
providers:
- name: default
orgId: 1
folder: ""
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: false
options:
path: /etc/grafana/provisioning/dashboards/json

View file

@ -1,10 +0,0 @@
# Generated by Ansible — do not edit manually
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
url: http://loki:3100
isDefault: false
editable: false

View file

@ -1,10 +0,0 @@
# Generated by Ansible — do not edit manually
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false