
如果你的工作里经常要和 IP 地址段、VLAN、机柜、设备台账打交道那 Netbox 这个名字你应该不陌生。这是一个开源的数据中心基础设施管理工具IPAMIP 地址管理和 DCIM数据中心基础设施管理是它的两大核心模块。我们团队从 2022 年就在产线环境里用 Docker 方式部署 Netbox版本也从 v3.2 一路升到 v3.7中间踩了不少坑。这篇文章就把 Docker 模式下 Netbox 版本升级的完整流程和注意事项整理出来尤其是数据库备份、镜像标签更换、迁移执行这些关键节点给后面要升级的同学一个可以直接抄的作业。升级本身不复杂Docker 模式下无非是换个镜像 tag 再重启容器这么个表面动作但真正容易出问题的是底层数据库兼容性、Redis 版本、插件依赖这些藏在“表面动作”下面的环节。下文我按实际操作顺序从升级前准备一直讲到升级后验证尽量把每一步背后为什么要这么做说清楚避免你只是照着敲命令、出了问题一脸懵。1. 升级前准备先搞清楚你手上是什么版本很多人在升级时犯的第一个错误就是没搞清楚自己当前跑的是什么版本、基于什么方式部署的。Netbox 的部署方式五花八门有裸机安装、有 Docker Compose、有 Kubernetes Helm Chart每种方式的升级路径差异很大。这篇文章聚焦 Docker Compose 模式这也是官方推荐、社区使用最广的方式。1.1 确认当前版本和部署方式确认当前版本有两种方式。第一种最直接登录 Netbox 界面右上角用户菜单里能看到版本号类似于 “NetBox v3.5.9”。第二种是走 API访问/api/根路径返回的 JSON 里有一个netbox-version字段这个字段在自动化脚本里也很好用。同时确认一下 Docker Compose 的项目目录。通常你会有一个专门存放 Netbox 部署文件的目录比如/opt/netbox-docker里面至少包含docker-compose.ymlconfiguration/configuration.py或者configuration.yml如果有插件还会有plugins/目录和一些额外配置数据持久化目录或者 Docker volume注意升级前必须确认当前部署目录里有没有你自己改过的东西。很多人拿官方 docker-compose.yml 下来改了端口、改了 PostgreSQL 密码、加了插件结果升级时直接拉最新镜像旧配置不兼容容器起不来。建议先执行下面几个命令把现状摸清楚docker compose ps docker compose exec netbox cat /opt/netbox/netbox/netbox/settings.py | grep VERSION docker compose config其中docker compose config会合并展示当前 compose 文件的完整内容方便你确认当前镜像 tag、环境变量、卷映射、端口映射这些信息升级前后要对得上。1.2 完整备份数据库、配置、文件存储升级 Netbox 本质上是一次有状态应用的更新数据库一旦出了问题光靠镜像回滚是救不回来的。所以备份这一节我说得细一点每一步都有实际踩坑的背景。数据库备份是所有备份里优先级最高的。Netbox 使用 PostgreSQL推荐用pg_dump做逻辑备份而不是直接复制数据文件。逻辑备份生成的 SQL 文件可以跨 PostgreSQL 小版本恢复而且文件体积通常不大方便传输和归档。cd /opt/netbox-docker docker compose exec -T postgres pg_dump -U netbox -d netbox netbox_$(date %Y%m%d_%H%M%S).sql这里有几个细节值得注意。-T参数是必须的它的作用是禁止 Docker 分配伪终端否则在脚本或 CI 环境里会报the input device is not a TTY错误。-U netbox指定数据库用户-d netbox指定数据库名这俩值来自 compose 文件里的POSTGRES_USER和POSTGRES_DB环境变量如果你改过名字要对应调整。备份完检查一下文件大小和内容一个正常的 Netbox 备份文件应该有几 MB 到几百 MB文件开头应该是-- PostgreSQL database dump字样。经常有人备份完发现文件是 0 字节多半是 pg_dump 命令报错但被重定向吞掉了错误信息。稳妥起见再加一个2 backup_error.log把标准错误单独存下来。配置文件备份同样重要尤其是configuration.py和docker-compose.yml。建议整个部署目录打个 tar 包连同插件目录一起备份tar czf netbox-config-$(date %Y%m%d).tar.gz -C /opt netbox-docker文件存储部分Netbox 在运行过程中会产生三类需要持久化的文件上传的图片和附件netbox-media-files、自定义报表netbox-reports、自定义脚本netbox-scripts。如果这些数据放在 Docker volume 里可以用一个一次性容器来打包备份docker run --rm -v netbox-docker_netbox-media-files:/data -v $(pwd):/backup alpine:3.18 tar czf /backup/netbox-media-$(date %Y%m%d).tar.gz -C /data .注意 volume 名称前面的前缀netbox-docker是 Compose 项目名如果你的项目目录叫别的volume 名称会跟着变。可以用docker volume ls | grep netbox查看实际的 volume 名称。1.3 检查兼容性矩阵和版本间差异备份归备份升级前还有一道功课要做查看新版本官方文档里的升级说明和兼容性要求。Netbox 官方在 GitHub 的 Release Notes 里会明确列出当前版本支持的 Python、PostgreSQL、Redis 版本范围这个信息直接影响你是否需要顺带升级中间件容器。尤其是跨大版本升级比如 v3.x 升到 v4.x中间件版本要求通常会有变化。一个常见的场景是旧部署用了 PostgreSQL 13而新版 Netbox 要求 PostgreSQL 14 以上。如果你直接换 Netbox 镜像PostgreSQL 还是 13应用起来后会报数据库版本不兼容的错误而且这种错误在日志里不一定很明显。实操心得跨大版本升级时我习惯先把官方 Upgrade Guide 里“Breaking Changes”一节通读一遍特别留意配置项名称变化和弃用警告。比如 Netbox 有些版本改了ALLOWED_HOSTS的校验逻辑有些版本改了CSRF_TRUSTED_ORIGINS的格式这些配置虽然不直接影响容器启动但会导致登录后界面报 403 错误排查起来很浪费时间。如果涉及 PostgreSQL 大版本升级比如从 PostgreSQL 13 升到 15建议先用pg_dump把数据导出再启动新版 PostgreSQL 容器最后用psql导入。不要尝试在数据目录上原地升级容器场景下原地升级数据目录容易出权限和版本标记问题。2. 核心升级流程从拉镜像到跑迁移准备工作做完下面进入正题。整个升级过程可以拆成“改镜像版本、拉取镜像、启动容器、执行迁移、收集静态文件、重启 worker”六个步骤。前两步是物理层面的替换后几步是应用层面的更新缺一不可。2.1 修改镜像版本号和关键环境变量打开docker-compose.yml找到 netbox、netbox-worker、netbox-housekeeping 这几个服务。通常情况下它们引用的是同一个镜像只是 command 不同。要升级就是把这些服务里的镜像 tag 从旧版本改成目标版本。services: netbox: image: netboxcommunity/netbox:v4.0.6 ... netbox-worker: image: netboxcommunity/netbox:v4.0.6 ... netbox-housekeeping: image: netboxcommunity/netbox:v4.0.6 ...这里有一个容易漏掉的细节如果你旧版本用的是:latesttag建议趁这次升级改成固定版本号。:latest在重新docker compose pull时拉到的不一定是哪个版本生产环境用固定版本号才能保证可重复部署和回滚。我自己踩过这个坑有一次docker compose pull把镜像从 v3.5 直接拉到了 v3.6刚好赶上 v3.6 改了插件 APIworker 容器一直报错。除了镜像 tag还需要对照新版 Release Notes 检查环境变量。Netbox 的 Docker 镜像支持几十个环境变量最常需要调整的有SECRET_KEYDjango 签名密钥一般保持不变ALLOWED_HOSTS升级后可能校验更严格务必包含你实际访问用的域名或 IPCSRF_TRUSTED_ORIGINS新版要求显式声明信任的来源SUPERUSER_*管理员账号初始化变量首次启动有效DB_*/REDIS_*数据库和 Redis 连接配置一般不动2.2 拉取镜像并启动容器修改完docker-compose.yml后先拉取新镜像docker compose pull这一步会按 compose 文件里的定义把 netbox、postgres、redis、nginx 等所有服务的新镜像拉取到本地。如果只是升级 Netbox 本身PostgreSQL 和 Redis 的镜像 tag 不修改这两个服务的镜像不会被重新拉取。拉取完成后启动容器docker compose up -d官方镜像的 entrypoint 脚本在容器启动时会自动执行数据库迁移和静态文件收集所以理论上up -d之后 Netbox 自己会完成大部分升级动作。但自动执行的好处是省事坏处是错误被吞在启动日志里你看到容器起来了实际上 netbox 服务可能一直在报错。所以我更推荐的做法是先docker compose up -d然后马上看日志docker compose logs -f netbox日志里如果出现Migrating...或者Running migrations:字样说明迁移已经自动触发。如果日志里出现Traceback或者OperationalError说明迁移失败需要手动干预。在迁移大版本时自动迁移可能耗时较长容器会一直处于 starting 状态这是正常的耐心等待即可。2.3 手动执行数据库迁移和静态文件收集即使容器自动跑了迁移我还是建议手动执行一遍关键步骤。原因很简单手动执行能看到完整的错误输出而且可以精确控制执行顺序。官方镜像中 manage.py 的路径通常是/opt/netbox/netbox/manage.py执行迁移docker compose exec netbox /opt/netbox/netbox/manage.py migrate如果看到类似Applying netbox.0012_... OK的输出说明迁移成功。迁移是增量操作重复执行不会造成破坏所以多跑一次问题也不大。迁移完成后执行静态文件收集docker compose exec netbox /opt/netbox/netbox/manage.py collectstatic --no-inputcollectstatic的作用是把 Django 应用里的静态资源CSS、JS、图片统一收集到指定目录由 nginx 直接伺服。如果跳过了这一步升级后界面会变得非常难看样式全部丢失甚至报 404。--no-input参数表示不交互确认方便脚本化执行。有些版本还建议清理旧缓存和 session 表docker compose exec netbox /opt/netbox/netbox/manage.py clearsessions这一步是可选的主要作用是清理过期 session让升级后的登录态更干净。我一般顺手执行几秒钟的事。2.4 启动验证与健康检查迁移和静态文件收尾后重启所有服务确保 worker 和 housekeeping 也加载了新版代码docker compose restart netbox netbox-worker netbox-housekeeping nginx然后检查容器状态docker compose ps正常情况下所有服务应该是Up或者running状态。接着用 API 验证版本号curl -s http://localhost:8080/api/ | python3 -m json.tool返回 JSON 里的netbox-version字段应该已经变成目标版本。UI 层面也要快速过一遍登录页是否能打开、登录后仪表盘是否正常、IP 地址列表页面是否展示正常、点击一个前缀进入详情页看是否有报错。如果前端有 JS 报错右键页面查看控制台多半是静态文件没收集干净或者浏览器缓存了旧资源强制刷新一下一般能解决。3. 升级过程中最容易踩的坑这一节说些不太会写在官方文档里、但实战中大概率碰到的问题。我按“中间件兼容性、插件冲突、容器异常”三类来梳理基本覆盖了 Docker 模式下升级 Netbox 的主要故障场景。3.1 Redis 和 PostgreSQL 的兼容性断层升级 Netbox 后有时候应用容器起来了迁移也跑了但页面一打开就 500。看 netbox 容器的日志报错信息指向 Redis 连接超时或者Redis ConnectionError。这种问题十有八九是 Redis 版本不满足新版本 Netbox 的要求。Netbox 对 Redis 的版本要求一直在提高低版本的 Redis 在高版本的 Netbox 下会出现连接不稳定、数据结构操作不兼容等问题。如果你的docker-compose.yml里 Redis 镜像还是redis:5-alpine这种老 tag建议一并升到redis:7-alpine。升级 Redis 本身不复杂但有一点要注意Redis 里缓存的数据在升级后可能格式不兼容轻则功能异常重则启动时直接报错。升级完 Netbox 和 Redis 镜像后清一次 Redis 缓存docker compose exec redis redis-cli FLUSHALL这条命令会把 Redis 里所有的缓存数据清空Netbox 会按需重新生成缓存损失只是冷启动慢几秒但能规避大量诡异问题。执行前跟团队确认一下有没有其他服务共用了这个 Redis 实例如果有FLUSHALL 会把别人的缓存也清了。PostgreSQL 这边的问题主要集中在版本和磁盘空间。大版本迁移时 PostgreSQL 需要大量临时磁盘空间来执行表结构变更如果数据目录所在磁盘剩余空间不足迁移会在中途报no space left on device而且这种失败可能留下不完整的 schema 变更需要手动清理非常麻烦。注意升级前用docker system df和df -h检查磁盘空间预留出至少数据库当前体积两倍以上的可用空间。另外确认一下 PostgreSQL 数据目录的 volume 没有跑满 inode。3.2 插件不兼容导致启动失败Netbox 的插件生态很丰富但插件恰恰是升级时最容易翻车的环节。升级前先在容器里看下装了哪些插件docker compose exec netbox /opt/netbox/netbox/manage.py plugin list或者直接看 pip 列表docker compose exec netbox pip list | grep -i netbox如果发现插件列表里有第三方插件比如用于拓扑可视化的、用于设备自动发现的务必去插件项目的 Release Notes 里确认它是否支持你即将升级的 Netbox 版本。很多插件在 Netbox 大版本升级后会出现 API 不兼容轻则插件页面打不开重则整个 Netbox 服务都无法启动。升级完 Netbox 主镜像后同步更新插件docker compose exec netbox pip install --upgrade netbox-xxx-plugin如果你用的是configuration/plugins.yml或configuration.py里的插件包管理机制就在配置里根据插件官方要求调整版本号然后重启容器。还有一种情况比较隐蔽插件虽然支持新版 Netbox但插件自身的数据库表结构没更新。Netbox 在升级后会运行 Django 的migrate正常来说插件的数据表迁移也会被一起执行。但有些插件需要在 Netbox 之前先升级到特定版本否则它的迁移文件依赖的 Netbox API 已经变了迁移会失败。遇到这种情况就按“先升级插件到兼容新版 Netbox 的最低版本再升级 Netbox 镜像”的顺序来回折腾。3.3 502、500 和容器反复重启的排查思路升级后最常见的故障表现是 nginx 返回 502 Bad Gateway。这说明 nginx 容器活着但后端的 netbox 应用没有正常响应。出现 502 时按下面的步骤排查第一步看 netbox 容器是否还在运行docker compose ps如果 netbox 容器显示restarting说明进程启动失败被 Docker 的 restart policy 反复拉起。直接看日志docker compose logs --tail 200 netbox日志里一般会给出具体原因。我遇到过的几种高频原因包括SECRET_KEY缺失或格式不对PostgreSQL 连接被拒通常是指定了错误的密码或网络旧的迁移文件和代码不匹配启动时模型校验失败磁盘空间不足Django 无法写日志文件第二步如果 netbox 容器正常运行但还是 502手动请求一下看看应用本身是否响应docker compose exec netbox curl -I http://127.0.0.1:8080/如果容器内正常但外部 502问题多半出在 nginx 和 netbox 之间的网络或端口配置上检查 compose 文件里 nginx 的 upstream 端口和 netbox 实际监听端口是否一致。500 错误则要区分是全局 500 还是特定页面 500。全局 500 大概率是配置问题比如ALLOWED_HOSTS或CSRF_TRUSTED_ORIGINS没配好登录后会跳转到一个报错页。特定页面 500 一般是插件代码兼容性问题看 netbox 容器日志里的 Django traceback定位到具体插件后回退该插件的版本。4. Windows 环境部署 Netbox 的几个特殊点现在不少团队是在 Windows 机器上用 Docker Desktop 跑 Netbox 做测试或者小规模使用这和 Linux 服务器上部署有很大差异。尤其是升级操作Windows 下的坑集中在虚拟化环境、文件路径和命令差异三个方向。4.1 Docker Desktop 的虚拟化依赖和性能差异Windows 上跑 Docker 容器底层依赖 Hyper-V 或 WSL2 后端。如果你在升级前 Docker Desktop 本身启动不起来看到的报错信息大多和虚拟化支持有关比如检测不到虚拟化支持、WSL2 内核版本太老等。先把 Docker Desktop 本身修好再谈 Netbox 升级。Docker Desktop 在 Windows 下有两种后端基于 Hyper-V 的和基于 WSL2 的。新版本默认使用 WSL2因为资源占用更少、启动更快。但 WSL2 对磁盘 IO 的性能影响很大尤其是在跨文件系统读写时速度可能比 Linux 原生环境慢几倍。这意味着同样的pg_dump备份操作在 Windows 上耗时会更长等待时不要以为卡死了。实操心得在 Windows 的 Docker Desktop 里部署 Netbox强烈建议把 Netbox 的持久化数据放在 Docker volume 里而不是用 bind mount 挂载 Windows 目录。Docker volume 由 Docker 引擎管理文件读写走的是 WSL2 虚拟机内部的文件系统性能远高于挂载 Windows 宿主目录。这一点在升级时同样适用数据库迁移涉及大量读写如果数据放在 Windows 目录的 bind mount 上迁移时间会成倍增长。4.2 Windows 文件路径和权限坑Linux 的docker-compose.yml在 Windows 上通常可以直接用但有几个路径相关的坑。第一个是相对路径和绝对路径的分隔符。Windows 的路径是C:\path\to\file但docker-compose.yml里最好统一用相对路径或者/分隔的路径避免反斜杠转义问题。第二个是配置文件权限。Netbox 官方镜像的 entrypoint 会对/etc/netbox/config下的配置文件做权限校验如果配置文件的所有者不是容器内的netbox用户就会启动失败。在 Windows 上文件所有者信息映射比较复杂经常出现配置文件从 Windows 目录 bind mount 进去后权限不对的情况。解决办法就是前面说的用 volume 而不是 bind mount或者对配置文件所在的 bind mount 目录在容器启动后手动调整权限docker compose exec netbox chown -R netbox:netbox /etc/netbox/config第三个是 PowerShell 的命令语法差异。如果你在 PowerShell 里执行备份命令环境变量的写法、通配符的展开和 bash 都不一样。比如$(date %Y%m%d)在 PowerShell 里不是合法的命令替换需要用Get-Date -Format yyyyMMdd或者直接写固定文件名。最简单的办法是避免在 PowerShell 里跑复杂的 shell 命令而是用docker compose exec进入容器后在容器内完成备份再把文件从容器里拷贝出来。4.3 Windows 下升级操作的具体建议Windows 上执行 Netbox 升级建议按以下方式来拉取新镜像、启动容器、看日志这些命令和 Linux 没什么区别都是docker compose命令。差异主要在命令的跨平台兼容性上。例如备份时我习惯先创建一个存放备份的目录再在 PowerShell 里执行docker compose exec -T postgres pg_dump -U netbox -d netbox netbox_backup.sql这里没有使用$(date)套件文件名固定避免 PowerShell 的语法兼容问题。备份完再把文件重命名。这个方法有点土但在 Windows 上最不容易出错。升级完成后Windows 上还有一个独特的缓存问题浏览器会缓存旧的静态资源导致界面样式错乱。如果你用的是 Web 界面访问升级后记得强制刷新页面CtrlF5或者干脆开一个隐身窗口测试不然很容易误判成升级失败。如果 Windows 上 Docker Desktop 因为虚拟化支持问题无法启动排查方向主要在两块一是 BIOS 里有没有开启 Virtualization TechnologyVT-x/AMD-V二是 Windows 功能里有没有启用“适用于 Linux 的 Windows 子系统”和“虚拟机平台”。这块和 Netbox 本身无关但确实是 Windows 用户在升级道路上卡得最久的一步。5. 升级完后的检查和长期维护升级不是跑完命令就结束验证和后续维护同样重要。这里分享一份我每次升级后都会过一遍的检查清单以及几条长期维护的经验。5.1 升级后的功能验证清单仅仅看到版本号变了不代表升级成功我建议按下面的清单逐项验证。第一项IPAM 核心功能。新建一个测试前缀Prefix在它下面分配一个 IP 地址再删除掉。这个流程覆盖了前缀管理、IP 分配、VLAN 关联的多数代码路径。如果这条链路有问题说明核心数据模型迁移出了岔子。第二项设备和机柜管理。进到设备列表页面打开一台已有设备的详情尝试编辑并保存。这一步验证的是 DCIM 模块的读写功能。第三项用户和权限。用非管理员账号登录确认角色权限没有被重置这是后台权限模型迁移后最容易出错的地方。第四项自定义脚本和报表。如果日常依赖 Netbox 的自定义脚本做 IP 申请自动化升级后务必跑一个真实脚本验证。脚本依赖的 API 在新版本中可能变化编译错误往往要到执行时才暴露。第五项邮件通知和 Webhook。如果配置了设备变更通知测试一个变更操作确认通知能正常发出。这个功能依赖后台任务队列如果 Redis 或 worker 配置有问题这里会暴露。以上每一项出问题处理思路都是先看容器日志再定位是应用层还是插件层不要一上来就回滚。5.2 后续升级的节奏和备份策略Netbox 的版本发布节奏较快社区活跃小版本通常一个月左右一个大版本一年左右一个。不建议每个小版本都追但也不要拖太久不升跨好几个大版本再升级兼容性风险和升级成本都会成倍增加。我目前的节奏是大版本发布后等两个月的 patch 版本稳定期然后安排升级。小版本如果包含安全补丁就及时升如果只是功能更新就攒一攒和大版本一起处理。备份策略上建议全量备份每周一次数据库逻辑备份每天一次。保留最近两周的备份文件同时把备份文件定期拷贝到独立存储避免和 Docker 数据卷在同一块磁盘上。不要问为什么磁盘故障和误删除从来都是挑你最松懈的时候来的。关于备份恢复的演练我不多展开但至少你要确保一件事在测试环境里能把备份文件恢复到一个全新的 Netbox 实例上。这个动作如果从来没做过建议在升级前专门做一次不然备份文件其实是废纸。5.3 升级前最后的检查清单最后列一份精简的升级前检查清单照着做能规避大部分问题[ ] 确认当前版本和目标版本阅读官方 Release Notes 的 Breaking Changes[ ] 备份 PostgreSQL 数据库确认备份文件非空且可读[ ] 备份 docker-compose.yml 和所有配置文件[ ] 备份 media、reports、scripts 数据卷[ ] 确认磁盘剩余空间大于数据库体积的两倍[ ] 确认 Redis 和 PostgreSQL 镜像版本满足目标版本要求[ ] 确认已安装插件与目标版本的兼容性[ ] 确认 SECRET_KEY 不变ALLOWED_HOSTS 和 CSRF_TRUSTED_ORIGINS 已更新[ ] 记录当前镜像 tag便于回滚回滚方案也要提前想好。Docker 模式的优势就在于回滚比较简单把镜像 tag 改回旧版本docker compose up -d重新拉起容器数据库如果已经在升级过程中被迁移过了用备份文件恢复数据库即可。注意回滚时数据库要恢复到升级前的备份点不然新旧代码操作同一套数据库 schema 大概率出问题。我个人在实际操作中的体会是Netbox 升级这件事真正花时间的从来不是命令本身而是升级前的梳理和升级后的验证。Docker 镜像帮你把应用层打包好了但数据层、配置层、插件层的兼容性还是得靠人肉确认。把上面这套流程完整跑一遍单次升级时间控制在半小时以内是完全可以做到的。希望这份实操笔记能帮你少走弯路。