diff --git a/docs/drafts/timeweb-migration-log.md b/docs/drafts/timeweb-migration-log.md index 903970c..fb5baae 100644 --- a/docs/drafts/timeweb-migration-log.md +++ b/docs/drafts/timeweb-migration-log.md @@ -8,6 +8,70 @@ --- +## Шаг 9 — раскатана база и приложения без запуска (2026-05-23, выполнено) + +На свежей Timeweb-машине прогнаны два плейбука без даунтайма источника +(контейнеры на target не запускались). + +### 9a. Системная база + +```bash +uv run ansible -i timeweb.yml -m ping server # pong +uv run ansible-playbook -i timeweb.yml --diff playbook-all-setup.yml +``` + +После прогона на target поднято: apt-пакеты (`geerlingguy.security`), +docker + сети (`web_proxy_network`, `monitoring_network`), eget с +инструментами (restic, rclone, btop, zellij и др.), ufw (порты 22, +2222, 80, 443), fail2ban, backup-инфра (`backup-all.py`, +resticprofile, cron). + +Заодно `geerlingguy.security` отключил root по SSH и +`PasswordAuthentication` — root-канал закрыт, доступ только через +`major` + ключ. Перепроверено `ssh major@<новый-ip>` — работает. + +### 9b. Application-плейбуки без запуска контейнеров + +```bash +uv run ansible-playbook -i timeweb.yml --diff \ + --skip-tags run-app \ + playbook-all-applications.yml +``` + +На target созданы все ``-пользователи с правильными uid/gid +(совпадают с источником, см. таблицу в [плане](timeweb.md)), каталоги +`/srv/applications//{data,config,backups}`, отрендерены +`docker-compose.yml` и application-конфиги. Контейнеры **не** +запускались — это шаг 5 cutover'а (после rsync'а данных). + +OAuth-аутентификация в `cr.yandex` (из Шага 3) сработала с +Timeweb-айпишника без замечаний — `community.docker.docker_login` в +плейбуках homepage и transcriber прошёл. + +### Обнаруженный латентный bug ordering'а в goaccess + +На fresh-install упала задача +`playbook-goaccess.yml:55 «Ensure caddy access log exists before +goaccess starts»` — пыталась туч'ить файл в `/var/log/caddy/`, который +к этому моменту не существовал. Причина: каталог создаётся в +`playbook-caddyproxy.yml`, а в `playbook-all-applications.yml` +goaccess идёт **раньше** caddyproxy (caddyproxy специально последний, +чтобы стартовать после backends). На предыдущем сервере не проявлялось +— каталог уже существовал от прошлых прогонов. + +Фикс: добавил в `playbook-goaccess.yml` явное создание +`caddy_logs_dir` перед touch'ем `access.log`. Owner/mode выставит +caddyproxy при своём прогоне, идемпотентность сохранена. + +**Backlog (после миграции):** `caddy_logs_dir` — shared-ресурс между +плеями (caddyproxy пишет, goaccess читает), концептуально это +provisioning-time забота. Вынести его создание в `playbook-system.yml` +(или в отдельный shared-resources плей в `playbook-all-setup.yml`) и +убрать дубль из goaccess/caddyproxy. Делать после переезда отдельным +PR, не во время миграции. + +--- + ## Шаг 8 — VPS заказан, пользователь `major` создан (2026-05-23, выполнено) Заказан Cloud VPS в Timeweb по тарифу из плана (4 × 3.3 ГГц, 8 ГБ RAM, diff --git a/playbook-all-applications.yml b/playbook-all-applications.yml index 0451704..3c31cfd 100644 --- a/playbook-all-applications.yml +++ b/playbook-all-applications.yml @@ -1,63 +1,63 @@ --- -- name: 'Configure netdata' +- name: "Configure netdata" ansible.builtin.import_playbook: playbook-netdata.yml # -- name: 'Configure dozzle' +- name: "Configure dozzle" ansible.builtin.import_playbook: playbook-dozzle.yml -- name: 'Configure goaccess' - ansible.builtin.import_playbook: playbook-goaccess.yml - -- name: 'Configure gitea' +- name: "Configure gitea" ansible.builtin.import_playbook: playbook-gitea.yml -- name: 'Configure gramps' +- name: "Configure gramps" ansible.builtin.import_playbook: playbook-gramps.yml -- name: 'Configure memos' +- name: "Configure memos" ansible.builtin.import_playbook: playbook-memos.yml -- name: 'Configure miniflux' +- name: "Configure miniflux" ansible.builtin.import_playbook: playbook-miniflux.yml -- name: 'Configure outline' +- name: "Configure outline" ansible.builtin.import_playbook: playbook-outline.yml -- name: 'Configure rssbridge' +- name: "Configure rssbridge" ansible.builtin.import_playbook: playbook-rssbridge.yml -- name: 'Configure wakapi' +- name: "Configure wakapi" ansible.builtin.import_playbook: playbook-wakapi.yml -- name: 'Configure wanderer' +- name: "Configure wanderer" ansible.builtin.import_playbook: playbook-wanderer.yml -- name: 'Configure calibre' +- name: "Configure calibre" ansible.builtin.import_playbook: playbook-calibre.yml -- name: 'Configure remembos' +- name: "Configure remembos" ansible.builtin.import_playbook: playbook-remembos.yml -- name: 'Configure apprise' +- name: "Configure apprise" ansible.builtin.import_playbook: playbook-apprise.yml -- name: 'Configure tuwunel' +- name: "Configure tuwunel" ansible.builtin.import_playbook: playbook-tuwunel.yml # -- name: 'Configure homepage' +- name: "Configure homepage" ansible.builtin.import_playbook: playbook-homepage.yml -- name: 'Configure transcriber' +- name: "Configure transcriber" ansible.builtin.import_playbook: playbook-transcriber.yml # -- name: 'Configure authelia' +- name: "Configure authelia" ansible.builtin.import_playbook: playbook-authelia.yml -- name: 'Configure caddy proxy' +- name: "Configure caddy proxy" ansible.builtin.import_playbook: playbook-caddyproxy.yml + +- name: "Configure goaccess" + ansible.builtin.import_playbook: playbook-goaccess.yml diff --git a/playbook-goaccess.yml b/playbook-goaccess.yml index 2bb83bf..1334971 100644 --- a/playbook-goaccess.yml +++ b/playbook-goaccess.yml @@ -52,6 +52,13 @@ - "{{ db_dir }}" - "{{ report_dir }}" + # Owner/mode проставит caddyproxy при своём (позднем) прогоне. + - name: "Ensure caddy logs directory exists" + ansible.builtin.file: + path: "{{ caddy_logs_dir }}" + state: "directory" + mode: "0755" + - name: "Ensure caddy access log exists before goaccess starts" ansible.builtin.copy: content: "" @@ -77,8 +84,8 @@ group: "{{ app_user }}" mode: "{{ item.mode }}" loop: - - {name: "Dockerfile", mode: "0640"} - - {name: "entrypoint.sh", mode: "0750"} + - { name: "Dockerfile", mode: "0640" } + - { name: "entrypoint.sh", mode: "0750" } - name: "Run application with docker compose" community.docker.docker_compose_v2: