chore: delete dead templates, remove duplicate MinIO task, update CLAUDE.md
- 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:
parent
5f44441bd1
commit
ccd7c44293
6 changed files with 24 additions and 132 deletions
48
CLAUDE.md
48
CLAUDE.md
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in a new issue