NetBox 生产部署指南:使用 Gunicorn 搭建 WSGI 服务并纳入 systemd 托管

发布时间:2026/9/20 16:32:58
NetBox 生产部署指南:使用 Gunicorn 搭建 WSGI 服务并纳入 systemd 托管 NetBox 生产部署指南使用 Gunicorn 搭建 WSGI 服务并纳入 systemd 托管【免费下载链接】netboxThe premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/products/free-netbox-cloud/项目地址: https://gitcode.com/gh_mirrors/ne/netbox本文是 NetBox 官方安装流程的第 4 步对应 docs/installation/4a-gunicorn.md讲解如何将 NetBox 这一 Django 应用以 WSGI 形式跑在 Gunicorn 之上并通过 systemd 将 Web 服务与后台任务 worker 一并托管。读完本文你将掌握 NetBox 官方默认的 Gunicorn 配置逐项含义、netbox.service与netbox-rq.service两个 systemd 单元的部署与调参方法、启动/验证/排障的完整命令链以及它如何与后续的 nginx/Apache 反向代理衔接。一、Gunicorn 在 NetBox 应用栈中的位置NetBox 本质上是构建在 Django 之上的 Python Web 应用而 Django 应用对外提供的是 WSGIWeb Server Gateway Interface 接口因此 NetBox 必须运行在某个 WSGI 服务器之后。Gunicorn 正是扮演这个角色它是一个纯 Python 实现的 WSGI HTTP 服务器负责接收来自前端 HTTP 服务器的代理请求并调用 NetBox 的 WSGI 应用入口处理请求。从官方架构说明见 docs/installation/index.md可以看到完整的数据流nginx / ApacheHTTP 反向代理接收外部 HTTPS 请求gunicornWSGI HTTP 服务器承接反向代理转发的请求rqworker后台 worker消费 Redis 队列中的任务与 Web 进程共享同一个 NetBox 应用NetBoxDjango 应用处理业务逻辑读写 PostgreSQL并借助 Redis 做缓存与任务排队。其中 gunicorn 与 rqworker 都由 systemd 托管是本篇的核心内容。NetBox 的 WSGI 应用入口位于 netbox/netbox/wsgi.py其内容非常精简设置DJANGO_SETTINGS_MODULE为netbox.settings然后通过django.core.wsgi.get_wsgi_application()构建 application 对象。Gunicorn 启动时正是通过netbox.wsgi这个模块路径加载该应用。值得注意的是Gunicorn 会随 NetBox 自动安装无需单独安装。在仓库根目录的 requirements.txt 中可以看到gunicorn26.2.0这一依赖项本文撰写时仓库所锁定版本。因此只要你按 docs/installation/3-netbox.md 跑过upgrade.sh完成虚拟环境构建/opt/netbox/venv/bin/gunicorn就已就位。说明NetBox 官方同时支持 uWSGI 作为备选 WSGI 服务器。如果计划使用 uWSGI请直接参考对应文档本文后续所有命令与配置文件均针对 Gunicorn。二、配置 Gunicorn复制官方默认配置NetBox 发行包内置了一份面向生产环境的 Gunicorn 默认配置。使用它的方式是把它从contrib目录复制到 NetBox 根目录而不是直接引用原文件sudo cp /opt/netbox/contrib/gunicorn.py /opt/netbox/gunicorn.py之所以强调“复制一份”而非“原地引用”官方文档给出的理由是确保你后续对配置的本地修改不会在未来的 NetBox 升级中被覆盖。这一点在 docs/installation/upgrading.md 的升级流程中也有呼应——升级新版本时需显式执行sudo cp /opt/netbox-$OLDVER/gunicorn.py /opt/netbox/把旧的 gunicorn 配置带过来。这份默认配置位于仓库的 contrib/gunicorn.py完整内容如下# The IP address (typically localhost) and port that the NetBox WSGI process should listen on bind 127.0.0.1:8001 # Number of gunicorn workers to spawn. This should typically be 2n1, where # n is the number of CPU cores present. workers 5 # Number of threads per worker process threads 3 # Timeout (in seconds) for a request to complete timeout 120 # The maximum number of requests a worker can handle before being respawned max_requests 5000 max_requests_jitter 500 # Uncomment this line to accept HTTP headers containing underscores, e.g. for remote # authentication support. See https://docs.gunicorn.org/en/stable/settings.html#header-map # header-map dangerous官方默认配置足以支撑绝大多数初次安装场景若需调整监听地址/端口或做性能调优编辑这份文件即可。以下逐项说明各参数的作用与调优建议。bind监听地址与端口bind 127.0.0.1:8001指定 Gunicorn 进程监听的 IP 与端口。默认绑定到本机回环地址127.0.0.1的8001端口——这是一个关键的安全设计WSGI 服务本身不直接暴露给外部网络而是由前端 HTTP 服务器nginx/Apache通过反向代理访问。8001这个端口号与官方 contrib/nginx.conf 中proxy_pass http://127.0.0.1:8001;保持一致修改端口时务必同步修改代理配置。workers工作进程数workers 5定义 Gunicorn 派生的 worker 进程数量。官方配置注释给出了经验公式2n1其中 n 为服务器 CPU 核心数。例如 2 核机器建议 5 个 worker、4 核机器建议 9 个 worker。由于每个 worker 是独立的 Python 进程会占用一定的内存从后文systemctl status输出可以看到单实例约 500MB 级别的常驻内存调大 workers 时需权衡内存容量。threads每进程线程数threads 3指定每个 worker 进程内运行的线程数量。启用多线程可以让单个 worker 并发处理多个请求在 I/O 密集场景NetBox 大量数据库与 Redis 交互下有助于提升吞吐同时比单纯增加进程数更节省内存。timeout请求超时timeout 120表示单个请求允许的最大处理时间秒。如果 worker 在 120 秒内未完成响应Gunicorn 会终止该 worker 并重启它。NetBox 某些重操作如大范围数据导入、配置渲染可能耗时较长若遇到“worker 被频繁杀掉”的现象可以适当调大此值。max_requests 与 max_requests_jitter防内存泄漏的滚动重启max_requests 5000与max_requests_jitter 500组合使用每个 worker 在处理完 5000 个请求后会被回收重建且实际阈值会在 0–500 的范围内随机抖动。这套机制用于规避长时间运行导致的 Python 进程内存膨胀问题——即使应用存在轻微内存泄漏也会在达到阈值时通过重启 worker 得到缓解引入 jitter抖动则是为了避免所有 worker 在同一时刻集体重启造成服务空窗。header-map远程认证专用选项文件中被注释掉的header-map dangerous用于启用对含下划线 HTTP 头的接收。这一选项主要服务于远程认证场景——例如某些 SSO 反向代理通过X-Remote-User这类带下划线的请求头传递用户身份。默认情况下 Gunicorn 出于安全考量会拒绝此类头部对应 WSGI 规范中关于 HTTP 头字段命名的限制只有在明确需要远程认证支持时才取消注释启用它。三、使用 systemd 托管 Gunicorn 与后台 workerNetBox 官方建议用 systemd 同时管理两个服务Web 应用进程Gunicorn与后台任务 workerRQ worker。部署服务单元文件首先把发行包内置的两个 systemd 单元复制到/etc/systemd/system/并重新加载 systemd 守护进程sudo cp -v /opt/netbox/contrib/*.service /etc/systemd/system/ sudo systemctl daemon-reload警告务必检查用户与组。发行包自带的 service 文件假定服务以netbox用户和netbox组运行。如果你的安装环境使用了不同的用户名/组名必须同步修改两个 service 文件中的User与Group字段。这一假设与 docs/installation/3-netbox.md 中创建系统用户netbox的步骤相对应。解析 netbox.service仓库中的 contrib/netbox.service 控制 Gunicorn 进程关键配置如下[Unit] DescriptionNetBox WSGI Service Documentationhttps://docs.netbox.dev/ Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Usernetbox Groupnetbox PIDFile/var/tmp/netbox.pid WorkingDirectory/opt/netbox # Remove the following line if using uWSGI instead of Gunicorn ExecStart/opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --config /opt/netbox/gunicorn.py netbox.wsgi # Uncomment the following line if using uWSGI instead of Gunicorn #ExecStart/opt/netbox/venv/bin/uwsgi --ini /opt/netbox/uwsgi.ini Restarton-failure RestartSec30 PrivateTmptrue [Install] WantedBymulti-user.target逐项说明Typesimplesystemd 将ExecStart启动的 gunicorn 主进程视为服务主进程不做额外 fork 探测Usernetbox/Groupnetbox以低权限系统用户运行避免以 root 暴露 Web 服务PIDFile/var/tmp/netbox.pid与命令行中--pid参数配套供 systemd 追踪主进程WorkingDirectory/opt/netbox服务工作目录ExecStart一行是核心调用虚拟环境中的 gunicorn 可执行文件通过--pythonpath /opt/netbox/netbox指定 Django 项目路径--config /opt/netbox/gunicorn.py指定第二节复制的配置文件最后的netbox.wsgi即 WSGI 应用模块对应 netbox/netbox/wsgi.py;Restarton-failureRestartSec30进程异常退出后 30 秒自动重启PrivateTmptrue为服务提供独立的临时目录命名空间提升安全性文件中同时保留了 uWSGI 的注释行仅当切换 uWSGI 时才需要取消注释并注释掉 gunicorn 行。解析 netbox-rq.service仓库中的 contrib/netbox-rq.service 控制 NetBox 的后台任务 worker[Unit] DescriptionNetBox Request Queue Worker Documentationhttps://docs.netbox.dev/ Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Usernetbox Groupnetbox WorkingDirectory/opt/netbox ExecStart/opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py rqworker high default low Restarton-failure RestartSec30 PrivateTmptrue [Install] WantedBymulti-user.target核心是ExecStart中的python3 manage.py rqworker high default low通过 Django 管理命令启动 RQ worker并依次监听high、default、low三个优先级队列。NetBox 的异步任务如 Webhook 投递、脚本/报告执行、配置渲染等都会写入这些队列Redis 的tasks数据库由该 worker 消费执行——所以 Web 服务与 worker 必须同时运行NetBox 才能完整工作。启动并设置开机自启sudo systemctl enable --now netbox netbox-rqenable --now一步完成两件事注册开机自启对应单元文件中的WantedBymulti-user.target并立即启动服务。验证服务状态使用systemctl status确认 WSGI 服务正在运行systemctl status netbox.service正常输出类似于● netbox.service - NetBox WSGI Service Loaded: loaded (/etc/systemd/system/netbox.service; enabled; preset: enabled) Active: active (running) since Mon 2026-01-26 11:00:00 CST; 7s ago Docs: https://docs.netbox.dev/ Main PID: 7283 (gunicorn) Tasks: 6 (limit: 4545) Memory: 556.1M (peak: 556.3M) CPU: 3.387s CGroup: /system.slice/netbox.service ├─7283 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox ├─7285 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox ├─7286 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox ├─7287 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox ├─7288 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox └─7289 /opt/netbox/venv/bin/python3 /opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox Jan 26 11:00:00 netbox systemd[1]: Started netbox.service - NetBox WSGI Service. ...解读这份输出Active: active (running)表示服务健康Main PID: 7283 (gunicorn)是 gunicorn 主进程CGroup列表中出现 1 个主进程 5 个 worker 子进程正好对应配置中workers 5的默认值——这是验证配置是否生效的直观手段Tasks: 6与Memory: 556.1M反映服务进程数与内存占用可作为调整 worker 数量的依据。故障排查如果 NetBox 服务启动失败使用journalctl查看日志定位问题journalctl -eu netbox-e直接从日志尾部开始显示-u netbox仅过滤该单元。常见的启动失败原因包括configuration.py中数据库/Redis 连接信息有误、netbox用户对目录无权限、端口被占用等日志中通常会有明确的 Python traceback 可供定位。四、与 HTTP 反向代理对接WSGI 服务验证通过后下一步是安装 HTTP 服务器详见 docs/installation/5-http-server.md。以官方 contrib/nginx.conf 为例反向代理的关键段落如下location / { # Remove these lines if using uWSGI instead of Gunicorn proxy_pass http://127.0.0.1:8001; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; ... }nginx 将外部请求转发到 Gunicorn 监听的127.0.0.1:8001并透传原始 Host、客户端 IP 与协议信息——NetBoxDjango依赖这些X-Forwarded-*头正确识别真实客户端与请求协议。如果修改了 gunicorn.py 中的 bind 端口必须同步修改此处的proxy_pass。若外部可以访问但返回502 Bad Gateway按 docs/installation/5-http-server.md 的排查清单依次检查WSGI worker 是否在运行systemctl status netbox应显示active (running)反向代理是否指向 Gunicorn 实际监听端口默认 8001SELinux 是否拦截反向代理连接必要时执行setsebool -P httpd_can_network_connect 1放行。五、升级与日常维护Gunicorn 的配置与 service 文件在 NetBox 升级时需要特别留意详见 docs/installation/upgrading.mdgunicorn.py 属于本地配置升级新版本时需要把旧版本中的gunicorn.py复制到新版本根目录避免本地调优丢失sudo cp /opt/netbox-$OLDVER/gunicorn.py /opt/netbox/service 文件以 contrib 目录为准升级后对比contrib/下新增的示例单元文件必要时同步更新/etc/systemd/system/中的副本升级完成后重启两个服务sudo systemctl restart netbox netbox-rq注意必须同时重启两者——只重启 Web 服务而不重启 worker会导致 Web 端与后台队列消费端运行在不同代码版本上。六、小结与下一步至此你已完成 NetBox 生产部署链条中承上启下的一环Gunicorn 作为 WSGI 服务器承载 Django 应用配合 rqworker 消费后台任务队列两者统一由 systemd 托管并支持开机自启、崩溃自动重启与日志排障。其核心工作流可概括为复制 contrib/gunicorn.py 为本地配置按 CPU/内存调整workers、threads、timeout等参数复制 contrib/netbox.service 与 contrib/netbox-rq.service 到 systemd 目录核对User/Group后enable --now用systemctl status netbox验证 worker 数量与内存用journalctl -eu netbox排障继续 HTTP 服务器安装让 nginx/Apache 代理到127.0.0.1:8001对外提供 HTTPS 访问。完整安装流程的其余步骤可参考 docs/installation/index.md 中的清单PostgreSQL、Redis、NetBox 本体、WSGI 服务器本文、HTTP 服务器与可选的 LDAP 认证。【免费下载链接】netboxThe premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/products/free-netbox-cloud/项目地址: https://gitcode.com/gh_mirrors/ne/netbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考