dashboard-ui
Отдельный React-интерфейс TaskFlow. Он собирается в собственный контейнер и отдаётся через Nginx router.
Интерактивные сценарии TaskFlow: доставка версии, путь запроса, реакция на сбой и проверка копий. Все действия выполняются локально в браузере и иллюстрируют устройство инфраструктуры.
VPS — внешний edge и SSH entry point. Домашний Debian — application/DevOps server. Два reverse SSH forward создаются исходящими соединениями Debian → VPS, а HTTP и deployment используют их как отдельные транспортные каналы.
Я начинал с задач, где результат виден сразу: рабочее место должно открыться, 1С — запуститься, база — восстановиться, пользователь — продолжить работу. В 2025 году это были Windows Server, 1С, MS SQL/PostgreSQL, Apache, RDP и реальные инциденты.
В 2026-м работа сместилась к веб-проектам: конфигурации, производительность, CMS, REST API и автоматизации. Параллельно я собрал собственную Linux/DevOps-среду и TaskFlow — full-stack приложение, вокруг которого появились CI/CD, blue/green, monitoring и backup.
Профессиональный путь: поддержка пользователей и баз, сопровождение веб-проектов, собственная инфраструктура Linux.
Пользователь, сервер, база и сервис — одна цепочка. Здесь появилась привычка не останавливаться на команде, а проверять, вернулась ли система в рабочее состояние.
Windows Server · 1С · MS SQL · PostgreSQL · Apache · RDP · AnyDesk
TaskFlow связывает интерфейс, API, данные и доставку в одном проекте. Клиентская часть, API и PostgreSQL работают в отдельных контейнерах.
TaskFlow — личный проект для управления задачами, отслеживания выполнения и ведения клиентов. React отвечает за интерфейс, FastAPI — за API, PostgreSQL — за данные. Nginx принимает запросы и выбирает активную версию.
Отдельный React-интерфейс TaskFlow. Он собирается в собственный контейнер и отдаётся через Nginx router.
FastAPI backend работает внутри Docker, получает DATABASE_URL, проверяется через собственный endpoint /health.
База — стабильный stateful-слой. GREEN и BLUE меняют приложение, но работают с общей PostgreSQL через внутреннюю Docker-сеть.
CI проверяет backend отдельно от production: Python 3.13, изолированная SQLite test DB, pytest и coverage. Production compose затем запускает подготовленные frontend/backend images.
Структура приложения описана в технической карте: dashboard-ui/package.json, taskflow-seo/docker-compose.yml и .github/workflows/ci.yml. Инфраструктурные связи ниже продолжают использовать актуальную техническую карту.
Сценарии показывают маршруты запросов, выпуск приложения, сбор метрик и резервное копирование. Каждому этапу соответствует компонент на 3D-схеме.
Сценарий связывает изменение кода, тесты и выпуск. Консоль моделирует проверки Linux, Docker, туннелей и приложения.
Состояние учебной консоли связано со сценарием выпуска и мониторингом.
Запрос проходит через VPS, Nginx и обратный SSH-туннель. На Debian маршрутизатор направляет его в интерфейс или API.
Модель нагрузки иллюстрирует изменение ресурсов, частоты запросов, задержки и соединений с базой. Значения сценарные и не являются результатом нагрузочного теста.
Prometheus получает метрики, Grafana показывает состояние, правила оповещений не сработали.
Копирование проходит через временный архив и проверку структуры. После успешной проверки сохраняются три последних архива; неудачная новая копия не заменяет предыдущие успешные.
Хранятся три последних успешных архива. Проверка свежести запускается отдельно каждый час.
Четыре части TaskFlow, где особенно хорошо видно инженерную логику: права, blue/green, транспорт между VPS и Debian и эксплуатация после запуска.
Пользователь deploy обслуживает туннели и выпуск версии. В sudoers разрешён конкретный сценарий taskflow-deploy; общие права администратора не выдаются.
Для меня инфраструктура начинается не с перезапуска всего подряд. Сначала состояние, потом логи, конфигурация и сеть. Меняю одну вещь — и проверяю результат.
$ systemctl --failedСначала смотрю, что действительно остановилось: одна служба или несколько зависимых компонентов.
Здесь только те детали, которые помогают объяснить систему: edge и tunnels, Docker runtime, deployment, monitoring, backup, доступы, firewall и failure scenarios. Повторяющиеся схемы, audit-only пункты и служебные списки убраны.
Инфраструктура состоит из двух основных серверов:
- Debian — основной домашний сервер, на котором работают TaskFlow, PostgreSQL, Docker, monitoring и backup.
- VPS — внешний edge/jump-host, через который публикуется TaskFlow и проходит CI/CD.
Также используются:
- GitHub / GitHub Actions;
- WireGuard;
- tun0 для удалённого рабочего стола;
- reverse SSH;
- Docker;
- PostgreSQL;
- Nginx;
- Prometheus;
- Grafana;
- Alertmanager;
- exporters;
- Netdata;
- systemd timers.
Главный принцип текущей архитектуры:
INTERNET
|
+--------+--------+
| |
v v
GitHub USERS
| |
| SSH | HTTP
v v
+-------------------------+
| VPS |
| |
| Nginx :80 |
| SSH :22 |
| |
| 127.0.0.1:8080 |
| 127.0.0.1:2222 |
+------------+------------+
|
reverse SSH
|
v
+-------------------------+
| DEBIAN |
| 192.168.0.100 |
| |
| Docker |
| TaskFlow |
| PostgreSQL |
| Monitoring |
| Backup |
+-------------------------+
Debian — основной сервер приложений.
VPS — внешний edge и jump-host.
VPS:
Hostname: edge-vps
OS: Debian GNU/Linux 13
Interface: ens3
Address: <VPS_PUBLIC_IP>/32
В документе публичный IP обозначается:
<VPS_PUBLIC_IP>
Основные роли VPS:
1. внешний HTTP edge;
2. Nginx reverse proxy;
3. SSH entry point для CI/CD;
4. endpoint reverse SSH tunnels.
На VPS нет текущего Docker production stack TaskFlow.
Основные интерфейсы:
enp37s0
192.168.0.100/24
обычная LAN/Internet связь
wg0
10.10.0.1/24
рабочий WireGuard для удалённого доступа
tun0
10.0.0.1/30
рабочий канал удалённого рабочего стола
wg-vps
10.66.66.2/32
исторический канал Debian ↔ VPS
Docker создаёт дополнительные сети:
172.17.0.0/16
172.18.0.0/16
172.19.0.0/16
172.20.0.0/16
172.21.0.0/16
172.22.0.0/16
172.23.0.0/16
wg0 — действующий WireGuard-интерфейс.
Interface: wg0
Address: 10.10.0.1/24
UDP: 51820
Peer:
AllowedIPs: 10.10.0.2/32
Во время аудита был подтверждён свежий handshake.
На момент проверки:
received: ~13.29 MiB
sent: ~147.66 MiB
Следовательно, wg0 реально используется.
Схема:
Remote Client
|
| WireGuard
|
v
Debian
wg0
10.10.0.1
wg0 не связан с текущим CI/CD.
tun0 — действующий канал удалённого рабочего стола.
Address: 10.0.0.1/30
Peer/gateway: 10.0.0.2
Он участвует в policy routing.
Отдельная routing table:
table 2022:
default via 10.0.0.2 dev tun0
Важно:
> tun0 нельзя считать старым или ненужным интерфейсом. Он является частью рабочей инфраструктуры удалённого рабочего стола.
Схематично:
Remote Desktop Client
|
v
tun0
|
v
Debian
|
v
XRDP
tun0 и wg0 выполняют разные задачи.
На Debian существует:
wg-vps
10.66.66.2/32
Конфигурация:
ListenPort = 36732
Endpoint = <VPS_PUBLIC_IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Table = 51821
Изначально схема была:
Debian
|
| WireGuard
| wg-vps
|
v
VPS
Позже этот механизм был заменён на reverse SSH.
На текущем VPS во время аудита:
/etc/wireguard/ отсутствует
WireGuard service отсутствует
UDP :51820 не слушается
wg show не показывает интерфейсов
Поэтому:
wg-vps = исторический механизм
reverse SSH = текущий механизм
Не считать wg-vps частью текущего рабочего деплоя.
Удалять его автоматически также не следует: он является остатком старой архитектуры и может быть очищен отдельной задачей после проверки зависимостей.
Сейчас используется reverse SSH.
Ключевой принцип:
Debian → VPS
а не:
VPS → Debian
Debian сам устанавливает SSH-соединение с VPS и создаёт reverse forwards.
Это позволяет VPS использовать полученные loopback-порты, не открывая Debian напрямую для входящих соединений из интернета.
Unit:
/etc/systemd/system/taskflow-tunnel.service
Пользователь:
deploy
Основной forward:
VPS 127.0.0.1:2222
|
| reverse SSH
v
Debian 127.0.0.1:22
SSH параметры:
ExitOnForwardFailure=yes
ServerAliveInterval=30
ServerAliveCountMax=3
StrictHostKeyChecking=yes
Restart=always
RestartSec=10
Сервис стартует после:
network-online.target
Unit:
/etc/systemd/system/taskflow-web-tunnel.service
Пользователь:
deploy
Зависимость:
Requires=taskflow-tunnel.service
Forward:
VPS 127.0.0.1:8080
|
| reverse SSH
v
Debian 127.0.0.1:80
Таким образом:
Internet
|
v
VPS :80
|
v
VPS Nginx
|
v
127.0.0.1:8080
|
| reverse SSH
v
Debian :80
Конфигурация:
/etc/nginx/sites-enabled/taskflow
Nginx:
listen 80;
listen [::]:80;
server_name _;
Основной proxy:
VPS :80
|
v
127.0.0.1:8080
То есть VPS Nginx не запускает TaskFlow.
Он выполняет роль:
Public Edge
↓
Reverse Proxy
↓
Reverse SSH
↓
Debian
Основная цепочка:
Developer
|
v
GitHub
|
v
GitHub Actions
|
+------ CI
|
+------ Deploy
|
v
VPS :22
|
v
VPS 127.0.0.1:2222
|
| reverse SSH
v
Debian :22
|
v
deploy
|
v
taskflow-deploy
|
v
Docker blue/green
|
v
TaskFlow
Файл:
/opt/company/repositories/TaskFlow/.github/workflows/ci.yml
Запускается для:
push:
main
develop
pull_request:
main
develop
Среда:
ubuntu-latest
Python 3.13
Рабочая директория:
taskflow-seo
Используется тестовая SQLite:
sqlite+aiosqlite:///./data/test.db
Создаются:
data/
logs/
Тест:
pytest --cov=app --cov-report=term
CI не подключается к production PostgreSQL.
Файл:
/opt/company/repositories/TaskFlow/.github/workflows/deploy.yml
Запускается после завершения CI:
workflow_run
workflow = CI
type = completed
branch = main
Условие:
CI conclusion == success
То есть production deployment невозможен через этот workflow, если CI завершился с ошибкой.
GitHub Actions использует:
VPS_SSH_KEY
DEPLOY_SSH_KEY
и другие значения из GitHub Secrets.
Секреты не входят в документацию.
Подключение:
GitHub Actions
|
| SSH
v
VPS :22
|
| ProxyCommand
v
VPS 127.0.0.1:2222
|
| reverse SSH
v
Debian :22
После подключения:
deploy@127.0.0.1
выполняет:
sudo -n /usr/local/sbin/taskflow-deploy <COMMIT>
Основной файл:
/usr/local/sbin/taskflow-deploy
Основные этапы:
1. flock / deployment lock
2. проверка commit
3. проверка Git state
4. fetch origin
5. проверка commit
6. создание release
7. git archive
8. build backend image
9. build frontend image
10. запуск противоположного цвета
11. backend health check
12. frontend check
13. изменение router config
14. nginx -t
15. nginx reload
16. active-color update
17. smoke tests
Release directory:
/opt/company/releases/<commit>
Используются:
green
blue
Текущий active color:
green
Файл:
/opt/company/router/active-color
Содержимое:
green
Принцип:
GREEN = active
BLUE = standby
При новом deployment:
GREEN active
|
v
start BLUE
|
v
health check
|
v
router -> BLUE
Предыдущий color остаётся доступным для rollback.
Если новый release становится проблемным:
BLUE active
|
v
rollback
|
v
restore previous router config
|
v
restore previous active-color
Старая версия уже существует в Docker и release infrastructure.
Это позволяет вернуть production без полного повторного deployment старой версии.
Репозиторий:
/opt/company/repositories/TaskFlow
Remote:
git@github.com:sergeiBogdano/TaskFlow.git
Application:
React frontend
FastAPI backend
PostgreSQL
Nginx router
Router:
taskflow-router
Host:
Debian :80
Router config:
/opt/company/router/nginx.conf
Current config:
/api/
-> taskflow-green-web:8000
/
-> taskflow-green-frontend:80
Схема:
taskflow-router
|
+----------+----------+
| |
v v
green frontend green backend
:80 :8000
|
v
PostgreSQL
Router — public entry point TaskFlow на Debian.
Production containers:
taskflow-green-frontend
taskflow-green-web
taskflow-blue-frontend
taskflow-blue-web
taskflow-router
taskflow-postgres
Blue и green существуют одновременно.
Active:
green
Blue сохраняется как rollback target.
Container:
taskflow-postgres
Image:
postgres:16
Port:
5432
PostgreSQL не имеет публичного host port.
Доступ:
TaskFlow backend
|
| Docker network
v
taskflow-postgres:5432
Database role/name:
taskflow
Пароль намеренно не документируется.
172.20.0.0/16
Основные участники:
green frontend
green web
blue frontend
blue web
postgres
blackbox
postgres_exporter
prometheus
172.21.0.0/16
Участники:
router
green frontend
green web
blue frontend
blue web
prometheus
blackbox
172.23.0.0/16
Участники:
blackbox
cadvisor
alertmanager
postgres_exporter
grafana
prometheus
172.19.0.0/16
Участник:
netdata
Старые/пустые сети:
taskflow-blue_default
taskflow-seo_default
Не считать их текущей production-схемой.
Monitoring stack:
Prometheus
Grafana
Alertmanager
node_exporter
cAdvisor
postgres_exporter
blackbox_exporter
Netdata
Versions recorded during audit:
Prometheus: 3.14.0
Grafana: 13.2.0
node_exporter: 1.10.2
cAdvisor: 0.55.1
postgres_exporter: 0.18.1
blackbox_exporter: 0.27.0
Alertmanager: 0.29.0
Основные alerts:
HostDown
DockerMonitoringDown
PostgreSQLExporterDown
DiskSpaceWarning
DiskSpaceCritical
TaskFlowRouterDown
TaskFlowGreenDown
TaskFlowBlueDown
TaskFlowFrontendDown
Alertmanager работает, но внешние notification receivers не настроены.
Поэтому:
Problem
|
v
Prometheus
|
v
Alertmanager
|
X
external notification
Система обнаруживает проблемы, но не отправляет внешние уведомления.
Основной script:
/usr/local/sbin/taskflow-backup
Service:
/etc/systemd/system/taskflow-backup.service
Timer:
/etc/systemd/system/taskflow-backup.timer
Расписание:
каждый день в 10:00
Timer:
Persistent=true
systemd timer
|
v
taskflow-backup.service
|
v
/usr/local/sbin/taskflow-backup
|
v
pg_dump
|
v
temporary dump
|
v
pg_restore -l
|
+---- invalid ----> reject
|
v
final dump
|
v
retain last 3 successful backups
Формат:
PostgreSQL custom format
Источник:
taskflow-postgres
Service:
/etc/systemd/system/taskflow-backup-check.service
Script:
/usr/local/sbin/taskflow-backup-check
Timer:
/etc/systemd/system/taskflow-backup-check.timer
Schedule:
hourly
Назначение:
проверка свежести backup
Это отдельная задача от создания backup.
Хранятся:
3 последних успешных dump
Во время аудита существовали:
taskflow_2026-09-13.dump
taskflow_2026-09-14.dump
taskflow_2026-09-17.dump
Временные файлы после исправления backup workflow не оставались.
Важно:
> pg_restore -l проверяет структуру backup-файла, но не является полноценным restore test.
Восстановление из резервной копии работает по актуальному уточнению автора от 21.09.2026. Внешнего хранения копий нет.
network-online.target
|
+------------------------+
| |
v v
taskflow-tunnel taskflow-reconcile
| |
v +--> docker.service
VPS reverse SSH
|
v
127.0.0.1:2222
HTTP tunnel:
taskflow-web-tunnel
|
+--> Requires taskflow-tunnel
|
v
127.0.0.1:8080 on VPS
Backup:
docker.service
|
v
taskflow-backup.service
^
|
taskflow-backup.timer
Freshness:
taskflow-backup-check.timer
|
v
taskflow-backup-check.service
|
v
taskflow-backup-check
Основная структура:
/opt/company/
├── repositories/
├── environments/
├── logs/
├── backups/
├── scripts/
├── monitoring/
├── router/
└── releases/
Назначение:
repositories -> исходный код
environments -> environment/config
logs -> логи
backups -> backup data
scripts -> служебные scripts
monitoring -> monitoring
router -> production router
releases -> deployment releases
Каталоги ранее организованы с групповой моделью доступа и setgid.
Пользователи:
debian
sergei
developer
tester
deploy
Группы:
developers
deployers
testers
admins
Роли:
debian
fallback/admin
local + XRDP
sergei
administrator / sudo
developer
development
no general sudo
tester
testing
deploy
deployment + tunnels
restricted sudo
Файл:
/etc/sudoers.d/taskflow-deploy
deploy может выполнять:
/usr/local/sbin/taskflow-deploy
через:
sudo -n
но не получает произвольный root shell через общий sudo.
Это соответствует принципу:
least privilege
UFW установлен:
inactive
Это не означает отсутствие packet filtering.
Docker управляет частью nftables/iptables-nft.
Во время аудита:
IPv4 FORWARD = DROP
IPv6 FORWARD = ACCEPT
Docker создаёт свои NAT/forward rules.
DOCKER-USER пуст.
Поэтому безопасность нельзя оценивать только по статусу UFW.
Debian
VPS
wg0
tun0
reverse SSH
TaskFlow
Docker
PostgreSQL
blue/green
TaskFlow router
GitHub Actions
Prometheus
Grafana
Alertmanager
exporters
Netdata
backup timers
wg-vps как основной канал VPS ↔ Debian
wg-vps остался на Debian, но текущий deployment и публикация TaskFlow через него не идут.
OLD COLOR active
|
v
NEW COLOR start
|
v
health check
|
X
|
v
OLD COLOR remains active
Production не должен переключаться на непрошедший health check release.
OLD COLOR
|
v
NEW COLOR start
|
v
health checks
|
v
nginx -t
|
v
nginx reload
|
v
active-color update
|
v
smoke tests
Monitoring:
service failure
|
v
Prometheus
|
v
alert
|
v
Alertmanager
Если причина связана с последним deployment:
router
|
v
rollback
|
v
previous color
Короткая версия резюме Сергея Богданова: от поддержки 1С и Windows Server к Linux, контейнерам и управляемой доставке веб-приложений.
Начинающий специалист в системном администрировании и DevOps. Сопровождаю серверы, базы данных и корпоративные системы, автоматизирую повторяющиеся процессы и собираю эксплуатационный контур вокруг веб-приложений.
Собрана по итоговой технической карте. Здесь разделены действующие компоненты, исторический транспорт и то, что нельзя утверждать без отдельного теста.
Nginx :80 и SSH :22. Принимает внешний HTTP и вход CI/CD, но production Docker stack TaskFlow здесь не запущен.
<VPS_PUBLIC_IP> · loopback forwardsDebian 13, Ryzen 5 5600, Docker, TaskFlow, PostgreSQL, monitoring и backup. Локальная сеть: 192.168.0.100.
application / DevOps serverDebian сам устанавливает соединение к VPS. 127.0.0.1:8080 ведёт на Debian :80 для HTTP, 127.0.0.1:2222 — на Debian :22 для deployment.
Debian → VPS · HTTP ≠ CI/CDwg0 — рабочий удалённый доступ. tun0 — удалённый рабочий стол и policy routing. wg-vps — исторический механизм, не текущий deployment-транспорт.
wg0 ≠ tun0 ≠ wg-vpstaskflow-router направляет / во frontend, /api/* — в активный FastAPI backend. Green и blue используют общую PostgreSQL и постоянный volume.
React · FastAPI · PostgreSQLCI на main/develop запускает pytest с изолированной SQLite. Deploy после успешного CI передаёт commit SHA и использует restricted deploy + sudo -n.
GitHub Actions · least privilegenode_exporter, cAdvisor, blackbox_exporter и postgres_exporter → Prometheus → Grafana / Alertmanager. Netdata остаётся отдельным realtime-слоем.
метрики ≠ выдуманные live-данныеЕжедневный pg_dump в custom format, pg_restore -l, retention трёх успешных dump и отдельная hourly freshness check. Восстановление из копии работает; внешнее хранение не настроено.
сохранить ≠ восстановить