После обновления netbox-docker база выглядит пустой: как пережить переход образа на PostgreSQL 18
Обновили netbox-docker, контейнеры поднялись, а в интерфейсе — пустой NetBox без единого устройства? Данные почти наверняка целы: начиная с 4.0.0 netbox-docker перешёл на PostgreSQL 18 и монтирует базу в новый том `netbox-postgres`, а старый `netbox-postgres-data` просто остался в стороне. Показываю, как в этом убедиться и как перенести базу дампом по процедуре из вики проекта.
Почему база «пустая»: netbox-docker сменил том и мажорную версию PostgreSQL
Если вы уже разбирали похожую ситуацию с обычным Docker Compose и образом postgres:18 — обновили тег с 16-го на 18-й, а контейнер поднял базу с нуля, хотя старый именованный том никуда не делся, — вы наверняка узнаёте симптом. Я подробно разбирал этот случай в статье «Обновил образ до postgres:18 — база создаётся заново, хотя старый том на месте»: там причина в том, что официальный образ postgres с 18-й версии изменил переменную PGDATA на версионированный путь и точку монтирования VOLUME, и если ваш docker-compose.yml жёстко указывает старый путь /var/lib/postgresql/data, новый контейнер инициализирует пустой кластер в другом месте, а старые данные остаются нетронутыми, но невидимыми.
С netbox-docker история похожая по симптому, но устроена иначе — и именно с ней мы чаще всего сталкиваемся в проектах внедрения NetBox. Здесь compose-файл за вас уже переписали авторы проекта. До 4.0.0 (например, в релизах 3.2–3.4) сервис postgres работал на образе postgres:17-alpine, а данные лежали в томе netbox-postgres-data, смонтированном в /var/lib/postgresql/data. Начиная с 4.0.0 в docker-compose.yml стоит postgres:18-alpine, том называется уже netbox-postgres и монтируется в /var/lib/postgresql — ровно туда, куда образ 18-й версии перенёс VOLUME, а PGDATA теперь /var/lib/postgresql/18/docker.
Отсюда и «пустая база». После привычных git pull, docker compose pull и docker compose up -d Docker Compose не находит тома <проект>_netbox-postgres, создаёт его пустым, PostgreSQL 18 инициализирует в нём новый кластер, а контейнер NetBox при старте честно прогоняет миграции и получает чистую схему без единого устройства. Никакой ошибки несовместимости в логах при этом нет — новый сервер старые файлы вообще не видит. Старый том <проект>_netbox-postgres-data с кластером PostgreSQL 17 остаётся на диске нетронутым, только к стеку он больше не подключён. Подключить его «как есть» к PostgreSQL 18 тоже нельзя: файлы кластера одной мажорной версии не читаются бинарниками другой, поэтому release notes 4.0.0 и требуют экспорт и повторный импорт базы.
- netbox-docker до 4.0.0: postgres:17-alpine, том netbox-postgres-data → /var/lib/postgresql/data.
- netbox-docker 4.0.0 и новее: postgres:18-alpine, том netbox-postgres → /var/lib/postgresql.
- После обычного апдейта Compose создаёт новый пустой том — NetBox поднимается на чистой базе.
- Старый том с PostgreSQL 17 цел, но подключить его к PostgreSQL 18 напрямую нельзя — только dump/restore.
Что именно требуют релиз-заметки netbox-docker 4.0.0
Релиз netbox-docker 4.0.0 (3 февраля 2026 года) прямым текстом предупреждает: «это мажорное обновление версии образа PostgreSQL. Вам нужно экспортировать и заново импортировать вашу базу данных» — со ссылкой на раздел PostgreSQL Update вики. Там же отдельное предупреждение: в PR #1259 мейнтейнеры официального образа postgres изменили способ монтирования каталога данных, «проверьте свою конфигурацию». Оба фактора работают вместе: смена мажорной версии PostgreSQL требует dump/restore, а смена имени и точки монтирования тома в compose-файле приводит к тому, что без этой процедуры стек молча поднимается на новом пустом томе. Автоматически перенос данных никто за вас не выполнит.
Второе требование релиза 4.0.0 — совместимость по версии NetBox: «эта версия netbox-docker совместима только с NetBox v4.5.x и выше». Если на момент апгрейда у вас установлена более старая версия NetBox (4.4 и ранее), одновременно с переходом на PostgreSQL 18 нужно поднимать и саму версию NetBox — а это уже отдельная тема совместимости схемы и, возможно, мажорного перехода по правилам самого NetBox, если разрыв версий большой. Актуальная ветка release на 23.09.2026 — netbox-docker 5.1.1 (10 сентября 2026), она совместима только с NetBox 4.7.x и новее, а сама NetBox 4.7 требует PostgreSQL 15+ — с PostgreSQL 18 из compose-файла это требование выполняется.
На практике это означает, что апгрейд netbox-docker до 4.0.0 и новее почти никогда не бывает изолированным изменением одного компонента: он тянет за собой минимум два потенциально мажорных перехода сразу — PostgreSQL и, возможно, самого NetBox, если вы отставали по версии дольше пары релизов. Я всегда рассматриваю такие апгрейды как отдельный проект с явным откатным планом, а не как рутинную операцию по расписанию, каких в норме большинство.
Из этого следует практическое правило: перед обновлением netbox-docker до 4.0.0 или новее всегда сверяйте текущую версию NetBox по её собственным требованиям к минорной цепочке апгрейда, и отдельно — планируйте dump/restore PostgreSQL как обязательный шаг, а не как «на всякий случай». Пропуск любого из двух требований и даёт тот самый эффект «пустая база после апгрейда».
- netbox-docker 4.0.0 (03.02.2026): переход PostgreSQL на v18, обязателен экспорт/импорт базы.
- Совместимо только с NetBox v4.5.x и новее — старую версию NetBox нужно поднимать отдельно.
- Полная инструкция — в разделе PostgreSQL Update вики netbox-docker; актуальный релиз — 5.1.1 для NetBox 4.7.x.
Два разных «апдейта», которые путают: миграция схемы NetBox и апгрейд PostgreSQL
В вики netbox-docker раздел Updating чётко разводит два процесса, которые администраторы обычно воспринимают как один и тот же «апдейт». Обычное обновление — когда меняется только версия самого NetBox, а PostgreSQL остаётся прежней мажорной версии — проходит автоматически: команда docker compose up -d поднимает новые контейнеры, и, по формулировке вики, «это также автоматически смигрирует схему базы данных NetBox». Никакого ручного dump/restore для этого не требуется — Django-миграции самого NetBox применяются к базе на лету при старте контейнера, как и в обычной (не Docker) установке.
Апгрейд самой PostgreSQL между мажорными версиями — процесс принципиально другого рода, и он не выполняется автоматически никогда, ни в 4.0.0, ни в любом другом релизе, где меняется мажорная версия образа СУБД. Мажорная версия PostgreSQL меняет внутренний формат файлов кластера, и новый бинарник просто не умеет читать данные, записанные предыдущей мажорной версией, без специальной процедуры конвертации (либо pg_upgrade, либо дамп/восстановление на уровне SQL — в официальной документации netbox-docker используется именно второй, более простой и надёжный для контейнерных инсталляций путь).
Путаница возникает потому, что оба процесса в быту называют одним словом «обновили netbox-docker». Человек видит, что предыдущий десяток обновлений проходил одной командой docker compose pull && docker compose up -d без единой ручной операции — и предполагает, что так будет всегда. Релиз, где меняется мажорная версия PostgreSQL внутри образа, — редкое, но принципиально иное событие, и именно поэтому авторы вынесли его в раздел Noteworthy Changes релиз-заметок — но читают их, как показывает обсуждение #1634 в netbox-docker, далеко не все.
- Обычный апдейт NetBox (без смены мажорной версии PostgreSQL) — схема мигрирует автоматически при старте.
- Мажорный апгрейд самой PostgreSQL — никогда не автоматический, только ручной dump/restore.
- netbox-docker 4.0.0 — редкий релиз, где оба процесса происходят одновременно.
Процедура перехода: экспорт, замена, импорт
Официальная процедура из раздела PostgreSQL Update вики netbox-docker выполняется до обновления файлов проекта: сначала останавливаете весь стек и поднимаете только контейнер PostgreSQL старой версии, чтобы снять дамп именно с него, работающего:
docker compose down
docker compose up -d postgres
docker compose exec -T postgres sh -c 'pg_dump -cU $POSTGRES_USER $POSTGRES_DB' | gzip > db_dump.sql.gzПосле того как дамп снят и вы убедились, что файл не пустой и не оборвался (проверьте размер архива и, если есть возможность, количество строк COPY внутри), вики предлагает удалить том с данными PostgreSQL — не трогая остальные тома netbox-docker (media, reports, scripts). При переходе на 4.0.0 это старый том netbox-postgres-data: новый стек его уже не использует, а восстановление пойдёт в новый том netbox-postgres, который Compose создаст сам. Я этот шаг откладываю до проверки NetBox на новой версии — место на диске старый том занимает недолго, а откатиться с ним проще:
docker compose down
docker volume rm netbox-docker_netbox-postgres-dataОбщий принцип — снять рабочую копию перед необратимым шагом, проверить её и только потом двигаться дальше — я закладываю в любой регламент бэкапа баз данных, не только для PostgreSQL под NetBox. Дальше подтягиваете новые файлы репозитория и новый образ (git pull, docker compose pull), поднимаете PostgreSQL уже 18-й версии на пустом томе и восстанавливаете дамп в неё:
docker compose up -d postgres
gunzip -c db_dump.sql.gz | docker compose exec -T postgres sh -c 'psql -U $POSTGRES_USER $POSTGRES_DB'
docker compose up -dЕсли вы уже успели запустить новый стек и он создал пустой кластер, перед восстановлением удалите именно новый том: docker compose down и docker volume rm netbox-docker_netbox-postgres (имя проекта у вас может отличаться — проверьте docker volume ls), иначе дамп ляжет поверх свежей схемы и восстановление будет сыпать ошибками, как у автора обсуждения #1634. Последняя команда из блока выше поднимает весь остальной стек — и вот здесь уже отрабатывает обычная автомиграция схемы NetBox, если заодно поднимается и новая версия самого NetBox. Два процесса идут друг за другом: сначала вручную мигрируете данные PostgreSQL, потом NetBox автоматически донастраивает схему под свою актуальную версию поверх уже перенесённых данных.
- 1. Остановить стек, поднять только postgres старой версии.
- 2. `pg_dump -cU $POSTGRES_USER $POSTGRES_DB | gzip > db_dump.sql.gz`.
- 3. Проверить дамп (размер файла, наличие данных).
- 4. Удалить старый том данных PostgreSQL (`docker volume rm ..._netbox-postgres-data`) — лучше после проверки новой версии.
- 5. Подтянуть новые файлы/образ; если новый стек уже запускался — удалить пустой том ..._netbox-postgres; поднять postgres 18 и восстановить дамп через psql.
- 6. Поднять весь стек — дальше отрабатывает автомиграция схемы NetBox.
Кейс: типография «Литерный двор», 20 рабочих мест — обновление после года без апдейтов
У типографии «Литерный двор» (20 рабочих мест) NetBox в связке netbox-docker крутился на выделенном сервере около полутора лет без единого обновления — на netbox-docker 3.2.1 с NetBox 4.2 и PostgreSQL 17 — заводили его под учёт сетевого оборудования производственного цеха и офиса, система работала, руки до апдейтов не доходили. Когда решили обновиться разом до актуальной версии, администратор клиента сделал стандартное git pull && docker compose pull && docker compose up -d — так обновлялись раньше, и раньше это всегда срабатывало без сюрпризов.
На этот раз после поднятия контейнеров NetBox открылся, но старый логин не подошёл, а после создания нового суперпользователя списки устройств, IP-адресов и площадок оказались пустыми — ровно то состояние, которое выглядит как катастрофа, если не знать заранее, что произошло. В логах контейнера postgres никаких ошибок не было — только сообщения initdb о создании нового кластера. Зато docker volume ls показал два тома: новый netbox-docker_netbox-postgres, созданный минутами раньше, и старый netbox-docker_netbox-postgres-data. Всё стало понятно: стек поднялся на новом пустом томе.
Старый том с кластером PostgreSQL 17 остался нетронутым. Остановили стек, переключили рабочую копию обратно на тег 3.2.1 (git checkout 3.2.1), подняли только postgres 17 на старом томе, убедились, что данные на месте, и сняли pg_dump. Дальше — процедура выше: вернулись на ветку release, удалили пустой новый том netbox-postgres, подняли postgres 18, восстановили дамп и запустили актуальный стек netbox-docker 5.1.1 с NetBox 4.7.1 — переход 4.2 → 4.7 в пределах одной мажорной ветки NetBox делает автоматически при старте. Все данные — порядка 340 устройств, 60 IP-префиксов и полная схема стоек цеха — вернулись без потерь. Старый том удалили через неделю, когда убедились, что всё работает.
Вся процедура заняла около 40 минут, из которых большая часть — время на снятие и восстановление дампа на их объёме данных. После этого я составил клиенту отдельную памятку: перед любым мажорным обновлением netbox-docker сначала читать раздел релиз-заметок целиком, а не сразу запускать привычную команду по накатанной.
- 1,5 года без обновлений (netbox-docker 3.2.1, PostgreSQL 17) — стандартный `pull && up -d` дал пустой NetBox.
- В логах postgres — не ошибка, а initdb нового кластера; в `docker volume ls` — два тома.
- Старый том netbox-postgres-data цел — данные просто остались в нём.
- Откат на тег 3.2.1 → pg_dump → новый том → restore → NetBox 4.7.1: около 40 минут, ~340 устройств без потерь.
Что я теперь делаю по умолчанию при апдейтах netbox-docker
Перед любым обновлением netbox-docker, особенно если между текущей и целевой версией прошло больше пары месяцев, я в первую очередь открываю не changelog самого NetBox, а именно релиз-заметки netbox-docker на GitHub — там отдельно фиксируются изменения инфраструктурного слоя (версия PostgreSQL, Redis, переменные окружения), которые в changelog NetBox вообще не упоминаются, потому что относятся не к приложению, а к обвязке Docker.
Второе правило — снимать дамп базы перед любым обновлением, где меняется хотя бы один из компонентов инфраструктуры (не только PostgreSQL, но и, например, версия Redis), даже если релиз-заметки явно не требуют dump/restore. Это занимает пару минут на среднем объёме данных, а отсутствие свежего бэкапа перед мажорным изменением — фактор риска, который совершенно не обязательно материализуется, но если материализуется, стоит часов простоя.
Третье — держать отдельно от общего пайплайна апдейтов регулярную проверку версии NetBox и netbox-docker на совместимость: 4.0.0 привязана к NetBox 4.5.x+, и если версии внутри стека расходятся с этим требованием, апгрейд лучше планировать в два шага — сначала довести NetBox до нужной минорной версии в рамках текущего netbox-docker, потом уже переходить на новый netbox-docker с новой PostgreSQL. Тот же подход — не мешать в одной операции апдейт приложения и апгрейд инфраструктурного слоя — я использую и в регламенте эксплуатации Zabbix: там точно так же смешивают обновление самого Zabbix с обновлением базы под ним.
- Читать релиз-заметки именно netbox-docker, а не только changelog NetBox.
- Снимать дамп базы перед любым обновлением, меняющим версию инфраструктурных компонентов.
- Сверять совместимость версий netbox-docker и NetBox перед апгрейдом, планировать в два шага при расхождении.
Частые вопросы
Чем этот случай отличается от общей проблемы с PGDATA в образе postgres:18?
Механизм родственный: в netbox-docker 4.0.0 compose-файл сам переключил базу на новый том netbox-postgres с точкой монтирования /var/lib/postgresql и PostgreSQL 18. Старые данные остаются в томе netbox-postgres-data, а подключить их к PostgreSQL 18 напрямую нельзя — нужен dump/restore по вики проекта.
Можно ли просто удалить старый том и начать с чистой базы?
Технически да, NetBox поднимется, но вы потеряете все данные — устройства, IP-адреса, кабельные соединения. Сначала снимите дамп со старого тома netbox-postgres-data (на старой версии netbox-docker и PostgreSQL 17) и только потом удаляйте что-либо.
Обязательно ли обновлять NetBox одновременно с переходом на netbox-docker 4.0.0?
netbox-docker 4.0.0 совместим только с NetBox v4.5.x и новее. Если у вас более старая версия NetBox, её нужно поднять отдельно, желательно до перехода на новый netbox-docker, с учётом собственных правил NetBox по мажорным апгрейдам.
Автомиграция схемы NetBox при docker compose up -d затронет данные PostgreSQL?
Нет, это разные процессы. Автомиграция меняет структуру таблиц под текущую версию NetBox в той базе, к которой подключён контейнер. Если это новый пустой том, она создаст пустую схему — старые данные из прежнего тома она не перенесёт.
Как узнать заранее, что апгрейд netbox-docker потребует dump/restore PostgreSQL?
Читайте релиз-заметки конкретной версии netbox-docker на GitHub перед обновлением — такие требования указываются явно, обычно в первых строках описания релиза, как это сделано в 4.0.0.
Источники
- GitHub — netbox-community/netbox-docker, Release 4.0.0 — Точная формулировка требования экспортировать и заново импортировать базу при переходе на PostgreSQL 18, предупреждение о точке монтирования, совместимость с NetBox v4.5.x+: https://github.com/netbox-community/netbox-docker/releases/tag/4.0.0
- GitHub Wiki — netbox-docker: Updating — Разделение обычного апдейта (автомиграция схемы NetBox при docker compose up -d) и мажорного апгрейда PostgreSQL (dump/volume rm/restore): https://github.com/netbox-community/netbox-docker/wiki/Updating
- GitHub — netbox-community/netbox-docker, docker-compose.yml (release) — release-ветка и тег 4.0.0: postgres:18-alpine, том netbox-postgres на /var/lib/postgresql; тег 3.4.2 и ранее: postgres:17-alpine, том netbox-postgres-data на /var/lib/postgresql/data: https://github.com/netbox-community/netbox-docker/blob/release/docker-compose.yml
- Docker Hub — официальный образ postgres, раздел PGDATA — В 18+ PGDATA = /var/lib/postgresql/18/docker, VOLUME перенесён в /var/lib/postgresql (PR docker-library/postgres#1259): https://hub.docker.com/_/postgres
- GitHub Discussion — netbox-docker #1634, Database lost after container upgrade — Реальный случай: после апгрейда по вики не пускает под старым логином, база пустая, restore поверх ругается на существующие данные; ответ — ссылка на раздел PostgreSQL Update: https://github.com/netbox-community/netbox-docker/discussions/1634
- itfresh.ru — Обновил образ до postgres:18: база создаётся заново, хотя старый том на месте — Разбор смежного, но другого случая — смены PGDATA/VOLUME в официальном образе postgres для произвольного Docker Compose стека: https://itfresh.ru/articles/postgres-18-docker-pgdata-volume.html



