Snipe-IT 是开源的 IT 资产管理平台,适合记录电脑、服务器、显示器、软件许可证、耗材和借用关系。把它部署在自己的 VPS 上,团队可以用统一的资产编号、二维码和审计记录管理设备,不必把内部资产清单交给第三方 SaaS。自托管同时意味着你要自己维护数据库、上传文件、邮件、定时任务、备份和升级。
本文以 Ubuntu 24.04、Docker Compose、MariaDB 和 Caddy 为例,搭建一个适合小团队使用的 Snipe-IT 单机环境。Snipe-IT 不同版本的镜像变量和初始化流程可能变化,生产部署前请以当前官方文档为准。
资产管理页面本身不重,但附件、二维码、导入任务和数据库会持续增长。建议准备:
| 项目 | 测试环境 | 小团队生产环境 |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU 起 |
| 内存 | 2 GB | 4 GB 起 |
| 磁盘 | 30 GB SSD | 60 GB SSD 起 |
| 系统 | Ubuntu 22.04/24.04 | Ubuntu 24.04 LTS |
| 域名 | snipe.example.com | 独立资产管理子域名 |
为域名添加 A/AAAA 记录指向 VPS。云防火墙只开放 SSH、80 和 443,MariaDB 不要映射到公网。多应用共用 VPS 时,先用 free -h、df -h 和 docker stats 检查资源;容量规划可参考 VPS 配置怎么选。
sudo apt update
sudo apt install -y ca-certificates curl openssl
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"
newgrp docker
sudo mkdir -p /opt/snipeit
sudo chown -R "$USER":"$USER" /opt/snipeit
cd /opt/snipeit
openssl rand -base64 32
把数据库密码和应用密钥保存到 .env,不要提交到 Git。生产环境可以再使用 Docker secrets 或密码管理器。
下面是服务结构示例。镜像版本、变量名称和健康检查要与当前 Snipe-IT 文档保持一致:
services:
db:
image: mariadb:10.11
restart: unless-stopped
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_DATABASE: snipeit
MYSQL_USER: snipeit
MYSQL_PASSWORD: change-a-long-password
MYSQL_ROOT_PASSWORD: change-a-root-password
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 15
snipeit:
image: snipe/snipe-it:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
APP_ENV: production
APP_DEBUG: "false"
APP_KEY: base64:replace-with-a-generated-key
APP_URL: https://snipe.example.com
DB_HOST: db
DB_DATABASE: snipeit
DB_USERNAME: snipeit
DB_PASSWORD: change-a-long-password
MAIL_MAILER: smtp
ports:
- "127.0.0.1:8080:80"
volumes:
- snipeit_data:/var/lib/snipeit
volumes:
db_data:
snipeit_data:
不要直接依赖 latest。确认当前稳定版本后固定镜像标签,并把敏感变量移到 .env。启动前检查 Compose:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=150 snipeit
如果官方模板拆分了缓存或定时任务容器,按模板完整部署。只启动 Web 容器可能导致资产页面能打开,但邮件、报表和提醒不执行。
容器稳定后先用 SSH 隧道访问:
ssh -L 8080:127.0.0.1:8080 root@SERVER_IP
浏览器打开 http://127.0.0.1:8080,完成安装向导。数据库主机填 Compose 服务名 db,不要填 localhost。首次登录后立即完成:
- 设置站点名称、默认时区和日期格式;
- 创建管理员强密码并启用 MFA(当前版本支持时);
- 创建公司、部门、地点和资产状态;
- 设置资产标签格式、序列号规则和二维码打印尺寸;
- 创建普通用户和只读审计角色;
- 配置上传文件大小和允许的附件类型。
资产编号一旦投入使用,不要频繁改规则。建议把购买年份、设备类别和流水号拆开保存,型号、序列号和资产标签分别录入,方便盘点和审计。
安装 Caddy:
sudo apt install -y caddy
sudo nano /etc/caddy/Caddyfile
写入反向代理:
snipe.example.com {
encode gzip zstd
reverse_proxy 127.0.0.1:8080
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
}
}
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
curl -I https://snipe.example.com
如果 VPS 已有 Nginx Proxy Manager 或其他网关,只让一个服务监听 80/443。反向代理和 HTTPS 排错可参考 VPS 用 Caddy 反向代理完全指南。
没有可靠 SMTP,用户邀请、密码重置、资产到期提醒和审计通知都会失败。建议使用事务邮件服务,并完成:
- 使用独立发件地址和显示名称;
- 配置 SPF、DKIM 和 DMARC;
- 设置正确的 PTR/反向 DNS;
- 先测试邀请、重置密码和到期提醒;
- 检查退信和垃圾邮件,不要把 SMTP 密码写进公开仓库。
邮件域名最好与资产管理域名分开。营销邮件和系统通知不要共用同一个低信誉发件地址,避免影响内部通知送达率。
首次上线时不要手动录入几百台设备。先整理 CSV,统一字段名称和序列号格式,再分批导入。导入前处理重复序列号和空白资产标签,导入后随机抽查地点、负责人、保修日期和状态。
二维码只应编码到资产详情页或资产编号,不要把管理员 Token、数据库连接或内部密码放入二维码。打印标签后,用手机扫码测试登录权限和 HTTPS 证书。
权限建议按最小权限分配:
- 仓库或 IT 管理员负责创建和借出资产;
- 部门负责人只能查看本部门设备;
- 审计账号只读资产变更记录;
- 普通员工只能查看分配给自己的资产;
- API Token 按系统拆分并设置过期和撤销流程。
如果使用 LDAP 或 SSO,先保留一个本地应急管理员,并测试 LDAP 中断时的登录路径。
Snipe-IT 的提醒、报表、邮件队列和清理任务依赖 scheduler。根据当前版本文档配置 Cron,下面是常见结构示例:
* * * * * cd /opt/snipeit && docker compose exec -T snipeit php artisan schedule:run >> /dev/null 2>&1
先手动运行一次确认命令可用,再交给 Cron。不要同时在容器和宿主机运行两套 scheduler,否则可能重复发送提醒或造成数据库锁。报表和批量导入任务执行期间,观察 CPU、内存和 MariaDB 慢查询。
Snipe-IT 的可恢复性取决于 MariaDB、snipeit_data、.env 和 APP_KEY。缺少 APP_KEY 可能导致加密字段无法恢复。每天导出数据库并打包应用数据:
mkdir -p /opt/snipeit/backups
docker compose exec -T db mysqldump -usnipeit -p"YOUR_DB_PASSWORD" snipeit | gzip > /opt/snipeit/backups/snipeit-$(date +%F).sql.gz
docker run --rm -v snipeit_snipeit_data:/data -v /opt/snipeit/backups:/backup alpine sh -c 'tar czf /backup/snipeit-data-$(date +%F).tgz -C /data .'
cp .env docker-compose.yml /opt/snipeit/backups/
实际 Volume 名称用 docker volume ls 确认。备份至少保存一份异地副本并加密,不要只依赖 VPS 快照。恢复前在干净 VPS 还原一次,验证管理员登录、资产附件、二维码、借用归还、邮件和审计记录。完整方法见 VPS 备份恢复演练。
升级前固定版本并保存配置:
docker compose config > /opt/snipeit/backups/compose-$(date +%F).yaml
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 snipeit
先在测试实例执行数据库迁移,再安排生产升级。不要在没有备份和回滚方案时直接跟随 latest。
docker compose ps
docker compose logs --tail=200 snipeit
sudo journalctl -u caddy -n 100 --no-pager
ss -lntp | grep -E ':8080|:80|:443'
确认容器绑定的是 127.0.0.1:8080,Caddy 指向相同端口,APP_URL 使用最终 HTTPS 地址。
查看 scheduler 日志,确认 Cron 用户可以执行 Docker,并检查 SMTP 端口、DNS 和供应商退信记录。若只有到期提醒失败,检查资产的保修日期、时区和通知开关。
检查 PHP 上传限制、Caddy 请求体限制、磁盘空间和容器数据目录权限。不要为了上传大文件而把整个管理后台暴露给公网;后台可以放到 WireGuard、Tailscale 或其他受控网络中。
- 域名、HTTPS、管理员登录和二维码访问正常;
- SMTP、邀请、密码重置和提醒邮件已验证;
- MariaDB 和管理端口未暴露公网;
- 资产编号、地点、用户和权限模型已确定;
- .env、APP_KEY、数据库和附件都有异地备份;
- 完成过一次恢复演练;
- 已固定版本并记录升级回滚步骤。
Snipe-IT 的价值不只是“记录有哪些电脑”,而是让资产从采购、领用、维修到归还都有可追溯记录。先统一数据字段和权限,再逐步导入设备,后续盘点、审计和设备到期提醒才会稳定运行。
