Локальная LAN-платформа на одном Debian/Ubuntu: HTTPS-портал, очередь, кэш, базы, Docker registry, CI runner, Maven и Debian-репозитории. Ansible + Docker Compose, без облака.
Хост: devops.local. Портал: https://devops.local/ (английский по умолчанию, переключатель EN/RU). Один раз доверьтесь CA: http://devops.local/ca.crt.
| RabbitMQ | PostgreSQL · Adminer |
|---|---|
![]() |
![]() |
| MongoDB · express | Maven · Reposilite |
|---|---|
![]() |
![]() |
Веб-морды только через nginx HTTPS. AMQP / MQTT / Redis / Postgres / Mongo / Elasticsearch — на нативных портах.
| URL | |
|---|---|
| Портал | https://devops.local/ |
| CA | http://devops.local/ca.crt |
| Portainer | https://devops.local/portainer/ (admin) |
| Registry UI | https://devops.local/registry/ |
| Registry API | https://devops.local/v2/ · docker login devops.local |
| RabbitMQ | https://devops.local/rabbitmq/ · AMQP :5672 · MQTT :1883 · WS :15675 |
| Redis Commander | https://devops.local/redis/ · Redis :6379 |
| PostgreSQL | https://devops.local/postgres/ · :5432 |
| MongoDB | https://devops.local/mongo/ · :27017 |
| Elasticsearch | https://devops.local/elastic/ · :9200 |
| Nextcloud | https://devops.local:8090/ (опционально, NEXTCLOUD_ENABLED=true) |
| Maven | https://devops.local/maven/ |
| Debian APT | https://devops.local/debian/ |
| Gitea MCP | http://devops.local:8080/mcp |
| Локальный Gitea | http://devops.local:3000/ (опционально, GITEA_ENABLED=true) |
Документация: Maven / APT · базы · TLS / docker login · Gitea.
docker login devops.local
docker tag myimg devops.local/myimg
docker push devops.local/myimg| Стек | На хосте | Что внутри |
|---|---|---|
devops |
/opt/compose/devops |
runner, MCP, Maven, Debian, registry, Portainer, TLS/CA; локальный Gitea при GITEA_ENABLED=true |
aiml |
/opt/compose/aiml |
Open WebUI + Speaches (STT/TTS, CPU) · опционально Ollama |
monitoring |
/opt/compose/monitoring |
Grafana + Prometheus + Loki / Alloy (логи контейнеров) |
middleware |
/opt/compose/middleware |
nginx-портал :80→:443, RabbitMQ (+MQTT), Redis, Postgres, Mongo, ES, опционально Nextcloud + Collabora |
Каждый сервис опционален (make setup / .env *_ENABLED).
Runner / MCP всегда ходят на gitea_instance_url (Synology) — URL не переписывается на :3000. См. docs/gitea.md.
Данные на хосте (bind-mount):
| Путь | Содержимое |
|---|---|
/opt/compose/tls |
Приватный CA + сертификат nginx (стек devops) |
/opt/compose/middleware/data/rabbitmq |
RabbitMQ |
/opt/compose/middleware/data/redis |
Redis AOF/RDB |
/opt/compose/middleware/data/postgres |
PostgreSQL |
/opt/compose/middleware/data/mongo |
MongoDB |
/opt/compose/middleware/data/elasticsearch |
Elasticsearch |
/opt/compose/middleware/data/nextcloud |
Nextcloud (файлы, конфиг, приложения) |
/opt/compose/devops/data/runner |
состояние act_runner |
/opt/compose/devops/data/maven |
Reposilite |
/opt/compose/devops/data/debian |
reprepro |
/opt/compose/devops/data/gitea |
Локальный Gitea |
/opt/compose/devops/data/debian-gpg |
ключ APT |
/opt/compose/devops/data/registry |
Registry blobs |
/opt/compose/devops/data/portainer |
Portainer |
/opt/compose/aiml/data/ollama |
модели Ollama (опционально) |
/opt/compose/aiml/data/speaches |
модели Speaches STT/TTS |
/opt/compose/aiml/data/openwebui |
Open WebUI |
/opt/compose/monitoring/data/prometheus |
Prometheus TSDB |
/opt/compose/monitoring/data/loki |
Loki chunks / index |
/opt/compose/monitoring/data/alloy |
Alloy |
/opt/compose/monitoring/data/grafana |
Grafana |
Порядок: make devops (TLS) → make aiml → make monitoring → make middleware.
Ansible работает в WSL. На Windows ansible.ps1 вызывает wsl make. Нативный Windows как control node не поддерживается.
Нужно: WSL с make + python3-venv, SSH-ключ на darvik@devops.local, sudo на целевой машине.
# WSL
sudo apt update && sudo apt install -y make python3-venv python3-pip
cd /mnt/d/Projects/devops/dockerСекреты не правятся в tracked-файлах репозитория. make setup пишет gitignored .env; цели деплоя читают его через .env.yml + inventory/local.ini.
make setup # один раз (или когда меняются хост / URL / пароли)
make ping
make docker # Docker CE + плагин Compose
make devops
make aiml
make monitoring
make middleware
make deploy # всё сразу (site.yml)Windows:
.\ansible.ps1 setup
.\ansible.ps1 ping
.\ansible.ps1 docker
.\ansible.ps1 devops
.\ansible.ps1 aiml
.\ansible.ps1 monitoring
.\ansible.ps1 middleware
.\ansible.ps1 deployДругие цели: make install, make check, make version, make clean, make help.
Makefile использует проектный .venv и выставляет ANSIBLE_CONFIG / ANSIBLE_ROLES_PATH / ANSIBLE_INVENTORY (нужно на world-writable /mnt/d/...).
Playbook выпускает приватный CA + серверный сертификат, ставит CA в OS trust и /etc/docker/certs.d/ на devops.local, insecure-registries не использует. Клиентам в LAN нужен тот же CA (docs/registry-tls.md).
Portainer: пользователь admin, пароль из .env (PORTAINER_PASSWORD, минимум 12 символов). Если логин не проходит: один раз PORTAINER_FORCE_REINIT=true, make devops, потом вернуть false.
Grafana: https://devops.local/grafana/ — логин/пароль из .env (GRAFANA_ADMIN_*). Логи (Docker на этом хосте + удалённые машины / bare-metal через агенты Alloy): docs/logging.md.
Пошагово media-vn (Synology) → devops.local: docs/logging-media-vn.md
(агент = контейнер + общий volume / syslog; без docker.sock хоста).
make devops выпускает TLS в /opt/compose/tls и поднимает registry/portainer/runner/….
Новая карточка на портале: запись в portal_services в inventory/group_vars/middleware.yml и при необходимости location = /status/... в stacks/middleware/nginx/default.conf.j2. Двуязычные строки: portal_i18n + title / description { en, ru }.
Обновить скриншоты (нужен .env и доступный портал; портал снимается на английском):
npm install
npx playwright install chromium
PORTAL_URL=https://devops.local npm run screenshotsCursor MCP:
{
"mcpServers": {
"gitea": {
"url": "http://devops.local:8080/mcp",
"headers": {
"Authorization": "Bearer <gitea_mcp_access_token>"
}
}
}
}Креды и переопределение хоста/URL — в .env (make setup). Дефолты в inventory/group_vars/ — секреты туда не класть.
| Переменная | По умолчанию | Описание |
|---|---|---|
gitea_enabled |
false |
Локальный Gitea (gitea-server). .env: GITEA_ENABLED |
ollama_enabled |
false |
Локальный LLM (OLLAMA_ENABLED=true) |
speaches_enabled / openwebui_enabled |
true |
Голос STT/TTS + чат |
prometheus_enabled / grafana_enabled / loki_enabled |
true |
Метрики + Grafana + Loki/Alloy |
ollama_models |
qwen3:4b-q4_K_M,gemma3:4b-q4_K_M |
Скачиваются при включённом Ollama (3-4B, Q4_K_M, Vulkan) |
openwebui_https_port |
8085 |
Open WebUI HTTPS (root URL — subpaths are unsupported) |
nextcloud_enabled |
false |
Nextcloud + Collabora (NEXTCLOUD_ENABLED=true) |
nextcloud_https_port |
8090 |
Nextcloud HTTPS (root URL — subpaths are unsupported) |
speaches_tts_default |
kokoro |
TTS по умолчанию (kokoro или piper; оба предзагружены) |
portal_lang |
en |
Язык портала по умолчанию (en / ru); переключатель в UI всё равно работает |
gitea_instance_url |
URL Synology | Цель runner/MCP. Не переписывается на локальный :3000 |
gitea_http_port / gitea_ssh_port |
3000 / 2222 |
Локальный Gitea HTTP / SSH |
gitea_root_url |
http://devops.local:3000/ |
ROOT_URL только локального сервера |
gitea_runner_name |
devops.local |
Имя runner в Gitea |
gitea_runner_labels |
devops.local:docker://catthehacker/ubuntu:act-latest |
Метки runner |
gitea_mcp_port |
8080 |
Порт gitea-mcp HTTP на хосте |
maven_http_port |
8083 |
Reposilite на localhost (nginx /maven/) |
debian_http_port |
8084 |
Debian www на localhost (nginx /debian/) |
gitea_runner_force_reregister |
false |
Удалить .runner и зарегистрировать заново |
middleware_http_port |
80 |
Nginx HTTP → HTTPS + /ca.crt |
middleware_https_port |
443 |
Портал, UI, registry /v2/ |
tls_enabled |
true |
Приватный CA + сертификат nginx |
tls_extra_dns / tls_extra_ips |
[] |
Дополнительные SAN в сертификате |
rabbitmq_amqp_port |
5672 |
RabbitMQ AMQP |
rabbitmq_mqtt_port |
1883 |
RabbitMQ MQTT (как в iot-platform-go) |
rabbitmq_mqtt_ws_port |
15675 |
RabbitMQ MQTT over WebSocket |
redis_port |
6379 |
Redis |
postgres_port |
5432 |
PostgreSQL |
mongo_port |
27017 |
MongoDB |
elastic_http_port |
9200 |
Elasticsearch HTTP |
elastic_java_opts |
-Xms512m -Xmx512m |
Heap ES |
compose_root |
/opt/compose |
Каталог стеков на целевой машине |
Не коммить .env, .env.yml, inventory/local.ini.
- Добавить
stacks/<name>/docker-compose.ymlи.env.j2 - Добавить группу inventory и playbook с ролью
compose_stackиcompose_stack_name: <name>
Старый passlib + bcrypt 5.x несовместимы. Хеш считается в scripts/bcrypt_hash.py. Переустановите зависимости venv:
make install
make middlewareСломан системный Ansible. Используйте только venv из Makefile:
make clean
make install
make deployПосле первой регистрации runner хранит скрытый /opt/compose/devops/data/runner/.runner. Если токен сбросили, runner удалили в UI Gitea или данные скопировали/мигрировали — Declare отдаёт 500. Пока .runner есть, переменные регистрации игнорируются.
ssh darvik@devops.local
sudo docker compose -f /opt/compose/devops/docker-compose.yml stop devops-runner
sudo rm -f /opt/compose/devops/data/runner/.runner
sudo docker compose -f /opt/compose/devops/docker-compose.yml up -d devops-runnerИли один раз GITEA_RUNNER_FORCE_REREGISTER=true и make devops, потом вернуть false. Нужен свежий токен: Gitea → Site Administration → Actions → Runners.
ssh darvik@devops.local
sudo docker compose -f /opt/compose/devops/docker-compose.yml ps
sudo docker compose -f /opt/compose/devops/docker-compose.yml logs
sudo docker compose -f /opt/compose/middleware/docker-compose.yml ps
sudo docker compose -f /opt/compose/middleware/docker-compose.yml logs




