Инвентаризация и визуализация оборудования в серверной: разворачиваем Rackula на Docker
1. Диагноз: почему схема стойки в Excel всегда врёт
Поднял новый сервер. Воткнул в третий юнит сверху. Забыл обновить таблицу. Через полгода на эту таблицу смотрит уже не тот человек, который её вёл — и видит совсем не то, что реально в стойке.
Знакомо? Инвентаризация оборудования в серверной обычно живёт в одном из трёх состояний: бумажная наклейка на дверце шкафа, файл Excel на расшаренном диске, который никто не открывает уже год, или диаграмма в Visio, нарисованная один раз перед аудитом и забытая сразу после.
Все три варианта ломаются по одной причине — обновление схемы никак не встроено в процесс монтажа оборудования. Смонтировал сервер — и пошёл настраивать ОС, а не открывать редактор диаграмм.
Rackula решает это иначе. Ты не рисуешь схему заранее и не сверяешь потом руками. Ты перетаскиваешь блок устройства на нужный юнит мышкой, прямо во время планирования установки, и схема сразу становится актуальной документацией, а не архивным артефактом.
На выходе этой статьи у тебя будет:
- Развёрнутый в Docker Rackula с постоянным хранением данных (persist-режим)
- Понимание разницы между клиентским и серверным режимом хранения
- Рабочая схема стойки с IP-адресами и заметками по каждому устройству
- Настроенный реверс-прокси для доступа из локальной сети
- Список из пяти типовых поломок и команды для их диагностики
- Схема бэкапа данных стойки
- Понимание когда Rackula не подходит и что взять вместо него
Займёт минут двадцать активного времени, если не считать чтение логов при первом факапе с правами на каталог. А он будет — про это ниже, в разделе про осложнения.
2. Причины: почему ручная инвентаризация оборудования в стойке не работает
Разберём конкретно, что именно ломает учёт оборудования в стойке при ручном подходе.
| Причина | Почему ломает процесс |
|---|---|
| Схема отделена от процесса монтажа | Обновление документации — отдельное действие после установки, а не часть установки. Отдельное действие пропускают первым |
| Файл лежит на файловом ресурсе, а не в системе с версионированием | Нет истории изменений, нет понимания кто и когда последний раз трогал схему |
| Формат не поддерживает метаданные устройства | Прямоугольник в Visio не хранит IP, серийник или дату установки — только название |
| Нет единого источника правды для распределённой команды | У каждого инженера своя версия файла, синхронизация вручную по почте |
| Порог входа в тяжёлые CMDB-системы слишком высокий | NetBox и подобные решают проблему, но разворачивать полноценный DCIM ради одной стойки — избыточно |
| Отсутствует визуальная привязка к U-позиции | Текстовый список «что где стоит» не отвечает на вопрос «сколько места осталось» с первого взгляда |
Последний пункт — самый частый. Ты открываешь таблицу, видишь список из сорока строк текстом, и всё равно идёшь физически считать свободные юниты в стойке руками. Смысл документации теряется полностью.
3. Рецепт: разворачиваем Rackula с сохранением данных
Подготовка
Нужен Docker Engine и Docker Compose v2 на хосте. Проверь версии перед началом:
docker --version
docker compose version
Rackula поставляется в двух режимах образа. Тег latest — чистый фронтенд, всё хранится в браузере через localStorage, данные не переживают смену компьютера. Тег persist — фронтенд плюс отдельный контейнер rackula-api, который пишет YAML-файлы на диск хоста. Для инвентаризации оборудования в серверной, которую смотрит вся команда, годится только persist-режим. Клиентский режим — это про быстро набросать схему на коленке и всё.
mkdir -p /opt/docker/rackula/data
cd /opt/docker/rackula
chown -R 1001:1001 data
Шаг 1. Docker Compose файл
Создай docker-compose.yml. Ниже — рабочий вариант с лимитами ресурсов и базовым hardening, без reverse proxy — просто для проверки на локальном порту.
services:
rackula:
image: ghcr.io/rackulalives/rackula:persist
container_name: rackula
ports:
- "8080:8080"
environment:
- API_HOST=rackula-api
- API_PORT=${RACKULA_API_PORT:-3001}
- RACKULA_LISTEN_PORT=8080
- API_WRITE_TOKEN=${RACKULA_API_WRITE_TOKEN:-}
- RACKULA_AUTH_MODE=none
restart: unless-stopped
stop_grace_period: 10s
depends_on:
rackula-api:
condition: service_healthy
networks:
- rackula-network
deploy:
resources:
limits:
cpus: "0.50"
memory: 128M
reservations:
cpus: "0.10"
memory: 16M
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /var/cache/nginx:size=10M
- /var/run:size=1M
- /tmp:size=5M
- /etc/nginx/conf.d:size=1M,uid=101,gid=101
rackula-api:
image: ghcr.io/rackulalives/rackula-api:latest
container_name: rackula-api
restart: unless-stopped
stop_grace_period: 10s
volumes:
- ./data:/data
networks:
- rackula-network
environment:
- DATA_DIR=/data
- RACKULA_API_PORT=${RACKULA_API_PORT:-3001}
- CORS_ORIGIN=${CORS_ORIGIN:-http://localhost:8080}
- RACKULA_API_WRITE_TOKEN=${RACKULA_API_WRITE_TOKEN:-}
- RACKULA_AUTH_MODE=none
- RACKULA_AUTH_SESSION_COOKIE_SECURE=false
- RACKULA_AUTH_CSRF_PROTECTION=true
- ALLOW_INSECURE_CORS=false
deploy:
resources:
limits:
cpus: "0.25"
memory: 128M
reservations:
cpus: "0.05"
memory: 32M
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp:size=5M
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:${RACKULA_API_PORT:-3001}/health"]
interval: 30s
timeout: 10s
start_period: 5s
retries: 3
networks:
rackula-network:
name: rackula-network
driver: bridge
Обрати внимание на лимит памяти у rackula-api. В оригинальных примерах из документации ставят 64M — на практике этого мало, контейнер валится по OOM с кодом выхода 137 уже на первом импорте библиотеки устройств. Ставь 128M сразу, сэкономишь вечер разбора логов.
Шаг 2. Файл переменных окружения
RACKULA_API_WRITE_TOKEN=сгенерируй_случайную_строку_32_символа
CORS_ORIGIN=http://IP_ТВОЕГО_ХОСТА:8080
CORS_ORIGIN должен буква в букву совпадать с адресом, по которому ты открываешь интерфейс в браузере. Не совпал протокол или порт — получишь молчаливый отказ в записи, без внятной ошибки на экране.
Шаг 3. Запуск
docker compose up -d
docker compose logs -f
Результат: два контейнера в статусе running, rackula-api — healthy. В логах rackula-api не должно быть строк про permission denied на запись в /data.
Шаг 4. Реверс-прокси
Публиковать порт 8080 напрямую в интернет не стоит — у Rackula нет встроенной защиты от перебора, если ты не поднял OIDC. Логичнее повесить сервис за твой обычный reverse proxy с базовой авторизацией или за SSO-портал. Пример для nginx:
server {
listen 443 ssl http2;
server_name rackula.example.local;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
После публикации через HTTPS не забудь поменять CORS_ORIGIN на новый адрес и включить RACKULA_AUTH_SESSION_COOKIE_SECURE.
Архитектура развёртывания
4. Проверка: работает ли инвентаризация корректно
После запуска стека проверь три вещи по порядку — статус контейнеров, здоровье API и статус в самом интерфейсе.
docker compose ps
Оба сервиса должны быть Up, rackula-api — Up (healthy). Дальше проверь эндпоинт здоровья напрямую:
curl -s http://127.0.0.1:3001/health
Открой веб-интерфейс в браузере. В правом верхнем углу должна быть надпись Online, а не Offline. Создай тестовую стойку, перетащи один блок устройства, обнови страницу. Если блок остался на месте после обновления — сохранение в persist-режиме работает.
Последний тест — сохрани данные, останови стек полностью и подними заново:
docker compose down
docker compose up -d
Стойка должна появиться на месте сразу после загрузки страницы, без импорта файла руками. Это и есть разница между persist-режимом и обычным клиентским.
5. Осложнения: что ломается чаще всего
Обычно в этом месте пишут — не переживай, всё не так страшно. Врать не буду: первый запуск почти у всех спотыкается на правах доступа. Зато чинится это одной командой.
| Ошибка | Причина | Решение |
|---|---|---|
| «Server offline or unavailable» в интерфейсе | Каталог data принадлежит root, контейнер не может писать | Выполни chown -R 1001:1001 data и перезапусти rackula-api |
| rackula-api выходит с кодом 137, статус unhealthy | OOM Kill — лимит памяти 64M из типового примера в документации слишком мал | Подними лимит memory до 128M и выше в секции deploy.resources.limits |
| Пустой экран или ошибка сети при сохранении | CORS_ORIGIN в .env не совпадает с реальным адресом обращения к интерфейсу | Выставь CORS_ORIGIN буква в букву как в адресной строке браузера, перезапусти rackula-api |
| С другого компьютера не видно тех же стоек | Развёрнут клиентский тег latest, а не persist, либо оба компьютера смотрят на разные инстансы API | Убедись что образ фронтенда именно persist и что оба клиента ходят на один и тот же адрес rackula-api |
| Не получается выделить устройство на carrier-модуле (половинной ширины) | Известная проблема выбора вложенных устройств в старых сборках | Обнови образ до актуального релиза — модель carrier-устройств переработана в релизах серии 26.x |
| После апдейта OIDC-логин зацикливается на ERR_TOO_MANY_REDIRECTS | С релиза, добавившего смену дефолтного redirect URI, старый путь колбэка больше не обслуживается | Зарегистрируй в identity-провайдере путь /auth/callback либо зафиксируй старый путь через RACKULA_OIDC_REDIRECT_URI |
| docker compose up падает на зависимости rackula-api unhealthy | Healthcheck не успевает пройти за start_period в 5 секунд на слабом хосте | Увеличь start_period здоровья до 15-20 секунд, перезапусти сборку |
6. Альтернативы: когда Rackula не подходит
Rackula — не единственный вариант для инвентаризации оборудования в серверной, и не всегда лучший. Вот с чем его реально сравнивать.
| Инструмент | Когда выбрать вместо Rackula |
|---|---|
| NetBox | Нужна полноценная CMDB как источник правды для Ansible, IPAM, учёт кабелей и виртуализации — не только визуальная схема |
| RackTables | Команда уже держит легаси-инфраструктуру на PHP-стеке и не хочет добавлять новый Docker-сервис |
| GLPI | Инвентаризация нужна вместе с service desk и учётом лицензий, а не только с физическим размещением |
| count.racku.la (публичный хостинг) | Нужна разовая схема без развёртывания своей инфраструктуры — данные хранятся только в браузере |
| Excel / Visio | Честно — почти никогда не выбирай, если уже дочитал досюда |
Выбор Rackula в этой статье обоснован просто: порог входа ниже, чем у NetBox, а результат — визуальный, а не только табличный. Если тебе нужна полная CMDB с интеграцией в Ansible-инвентарь — иди сразу в NetBox, не трать время на промежуточное решение.
7. Профилактика: чтобы не потерять данные стойки
Данные Rackula в persist-режиме — это просто YAML-файлы в каталоге data. Значит бэкапить их так же просто, как любой конфиг.
| Что | Как часто | Куда |
|---|---|---|
| Каталог ./data целиком | Ежедневно, по cron | Отдельный сервер бэкапов через rsync или BorgBackup |
| Файл docker-compose.yml и .env | При каждом изменении | Git-репозиторий инфраструктуры, без секретов в открытом виде |
| Образы контейнеров | Перед каждым обновлением | Локальный registry или тег latest минус один, для быстрого отката |
borg create --stats /path/to/repo::rackula-{now} /opt/docker/rackula/data
Одна потерянная папка data без бэкапа — это не катастрофа, а просто вечер, потраченный на восстановление схемы по памяти и старым скриншотам в Telegram-чате.
Для автозапуска после перезагрузки хоста restart-политика unless-stopped в docker-compose.yml уже это закрывает — ничего дополнительно настраивать не нужно. Для мониторинга доступности добавь проверку HTTP-статуса на порту 8080 в свою систему мониторинга, будь то Zabbix или что-то попроще.
8. FAQ: частые вопросы про инвентаризацию оборудования в стойке
Почему сохранение стойки не работает после настройки Rackula?
Чаще всего дело в правах на каталог data — контейнер rackula-api пишет от UID 1001, а каталог создан от root. Смени владельца командой chown и перезапусти контейнер.
Как проверить что Rackula работает правильно?
Три проверки подряд: статус контейнеров docker compose ps, эндпоинт /health на порту API, и статус Online в правом верхнем углу интерфейса после открытия страницы.
Что делать если rackula-api постоянно падает?
Проверь код выхода контейнера. Код 137 означает OOM Kill — контейнеру не хватает памяти по лимиту из docker-compose.yml. Подними лимит memory до 128M и выше.
Чем Rackula отличается от NetBox для инвентаризации серверной?
Rackula — про визуальную схему стойки и её физический layout, разворачивается за 15 минут. NetBox — полноценная CMDB с IPAM, учётом кабелей, интеграцией в Ansible, но требует заметно больше времени на настройку и понимания схемы данных.
9. Прогноз
После этой установки у тебя есть Rackula в persist-режиме, данные пишутся в YAML на диск хоста, а не живут только в браузере одного инженера. Схема стойки обновляется прямо в момент монтажа оборудования, а не превращается в отдельную задачу «когда-нибудь потом».
Дальше — дело привычки. Заведи правило: смонтировал юнит — сразу перетащил блок в Rackula, до того как пошёл настраивать ОС. Через месяц схема стойки будет точнее, чем любая таблица, которую вела вся команда полгода. Если после установки статус всё равно показывает offline или контейнер падает не по тем причинам, что описаны выше — пиши в комментарии, разберёмся.
Системные требования
| Компонент | Минимальная версия |
|---|---|
| Docker Engine | 24.x и новее |
| Docker Compose | v2 (плагин compose, не отдельный docker-compose 1.x) |
| Образ фронтенда | ghcr.io/rackulalives/rackula:persist |
| Образ API | ghcr.io/rackulalives/rackula-api:latest |
| ОЗУ на хосте | от 512 МБ свободных сверх лимитов контейнеров |
На момент публикации актуальны указанные теги образов. Перед установкой проверь свежие релизы в GitHub Releases проекта — версии выходят часто, и changelog иногда требует ручных действий при апдейте (пример — смена OIDC redirect URI в одном из релизов).
Таблица портов
| Порт | Протокол | Назначение | Доступен снаружи? |
|---|---|---|---|
| 8080 | HTTP/TCP | Веб-интерфейс Rackula (frontend) | Через reverse proxy, не напрямую |
| 3001 | HTTP/TCP | Rackula API — сохранение и чтение YAML | Нет, только внутри docker-сети |
Безопасность
- Не публикуй порт 3001 наружу ни при каких обстоятельствах — это прямой доступ к операциям записи
- Закрой порт 8080 на файрволе хоста, публикуй только через reverse proxy с TLS
- Используй RACKULA_API_WRITE_TOKEN — без токена запись открыта любому, кто достучится до API
- Если данные стойки чувствительны — повесь на reverse proxy базовую авторизацию или заведи OIDC через SSO-провайдер
- Держи RACKULA_AUTH_SESSION_COOKIE_SECURE=true при работе через HTTPS, иначе сессионная кука уходит открытым текстом
- Контейнеры уже запущены с read_only и cap_drop ALL в примере compose-файла — не убирай эти опции без причины
Обновление
Перед обновлением всегда читай changelog релиза — Rackula быстро развивается, и часть изменений требует правки .env, как это было с OIDC redirect URI.
docker compose pull
docker compose up -d
docker compose logs -f rackula-api
Для отката зафиксируй в docker-compose.yml не latest, а конкретный тег предыдущего релиза и подними стек заново — данные в каталоге data при этом не трогаются, схема останется на месте.
FAQ-разметка Schema.org (для справки редактора)
Дополнительно к HowTo-разметке в начале статьи рекомендуется добавить FAQPage-разметку по блоку FAQ выше — вынесено отдельно, чтобы не перегружать основной JSON-LD.
Оставайтесь на связи
Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.
Подписаться на IT-Аптеку →


