部署仓已改为开箱即用:config/ 直接是配置文件、口令等值内置在
docker-compose.yml、不再有 .env。
同步调整:
- 概览:部署流程改为 git clone + docker compose up -d 三步
- 配置说明:重写为「编排层 + 应用层」,说明为何不用环境变量
(GoFrame 不展开配置文件中的 ${VAR})、改口令需同步三处、
口令不能含 @ : / 等字符
- 启动与验证:去掉准备步骤,schema 脚本数改为 13 个
- 环境准备:镜像仓库改为描述编排文件中的实际地址
- 升级备份/离线/分离/自建镜像:.env 相关操作改为修改编排文件
8.9 KiB
title, description, outline
| title | description | outline |
|---|---|---|
| 二进制部署 | 直接编译 Go 程序运行,不依赖 Docker | deep |
二进制部署
不使用容器,把各服务编译为可执行文件,用 systemd 托管。
适用场景
- 服务器不允许安装 Docker
- 需要把服务纳入既有的 systemd / 进程管理体系统一运维
- 需要针对特定 CPU 架构或内核参数做优化
构建环境
| 项 | 要求 |
|---|---|
| Go | 按各服务 go.mod 要求,最低 1.23(见下表) |
| GCC | admin-svr 需要(CGO_ENABLED=1,内存库用 SQLite) |
| 系统 | 建议与目标服务器同发行版,避免 libc 差异 |
# Debian / Ubuntu
apt-get install -y build-essential
# CentOS / Rocky
yum groupinstall -y "Development Tools"
::: tip 其余服务可静态编译
除 admin-svr 外,其余服务 CGO_ENABLED=0,产物为静态二进制,可直接拷到任意同架构 Linux 运行。
:::
各服务构建参数
| 服务 | 仓库 | Go 版本 | CGO | 构建目录 | 产物名 | 监听端口 |
|---|---|---|---|---|---|---|
| admin-svr | iotlcm-admin-svr |
1.23 | 需开启 | server/ |
iotlcmadmin_svc |
8008 |
| openapi | iotlcm-openapi |
1.23 | 关闭 | 根目录 | iotlcm-openapi |
8000 |
| worker-svr | iotlcm-worker-svr |
1.25 | 关闭 | 根目录 | iotlcm-worker-svr |
无(队列消费) |
| upstream-chan | iotlcm-upstream-chan |
1.25 | 关闭 | 根目录 | iotlcmupstreamchan_svc |
8110 / 8310 |
| upstream-proxy | iotlcm-upstream-proxy |
1.25 | 关闭 | 根目录 | iotlcmupstreamproxy_svc |
8510 |
| app-server | iotlcm-app |
1.23 | 关闭 | server/ |
iotlcm-app-server |
8010 |
| sms | iotlcm-sms |
1.25 | 关闭 | 根目录 | iotlcm-sms |
11190 / 11200 |
| bot | iotlcm-bot |
1.23 | 关闭 | cmd/iotlcm-bot |
iotlcm-bot |
无 |
::: warning 仓库里的 Dockerfile 不能直接照搬
部分仓库的 Dockerfile 基础镜像指向私有仓库(见自建镜像),二进制构建不受影响,但 FROM 行需要替换。
:::
构建
admin-svr(需要 CGO)
git clone https://git.5iot.com/iotlcm-public/iotlcm-admin-svr.git
cd iotlcm-admin-svr/server
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -trimpath \
-ldflags "-s -w \
-X main.BuildVersion=$(git describe --tags --always) \
-X main.CommitID=$(git rev-parse --short HEAD) \
-X main.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
-o iotlcmadmin_svc .
其余服务(静态编译)
git clone https://git.5iot.com/iotlcm-public/iotlcm-openapi.git
cd iotlcm-openapi
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -trimpath \
-ldflags "-s -w \
-X main.BuildVersion=$(git describe --tags --always) \
-X main.CommitID=$(git rev-parse --short HEAD) \
-X main.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
-o iotlcm-openapi .
替换仓库名与产物名即可用于其他服务,bot 需要指定子目录:
cd iotlcm-bot
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -o iotlcm-bot ./cmd/iotlcm-bot
交叉编译说明
| 服务 | 能否交叉编译 |
|---|---|
| admin-svr(CGO) | ❌ 需在目标架构上编译,或用对应架构的交叉工具链 |
| 其余(静态) | ✅ 可直接 GOOS=linux GOARCH=arm64 |
查看服务器架构:
uname -m # x86_64 → amd64;aarch64 → arm64
部署布局
/opt/iotlcm/
├── admin-svr/
│ ├── iotlcmadmin_svc
│ ├── config/config.yaml ← 从 config/admin-svr 复制
│ ├── logs/
│ ├── upload/
│ └── cache/
├── openapi/
│ ├── iotlcm-openapi
│ ├── config/config.yaml
│ └── logs/
├── worker-svr/
│ ├── iotlcm-worker-svr
│ ├── config/config.yaml
│ └── logs/
├── upstream-chan/
├── upstream-proxy/
├── app-server/
│ ├── iotlcm-app-server
│ ├── config/config.yaml
│ └── resource/
│ ├── log/server/
│ └── upload/
├── sms/
└── bot/
配置文件放 config/config.yaml(相对工作目录),这是 GoFrame 的默认搜索路径。启动时工作目录必须在服务目录内。
目录准备
sudo mkdir -p /opt/iotlcm/{admin-svr,openapi,worker-svr,upstream-chan,upstream-proxy,app-server,sms,bot}
sudo useradd -r -s /sbin/nologin iotlcm
sudo chown -R iotlcm:iotlcm /opt/iotlcm
修改配置中的服务地址
容器部署时配置里写的是服务名(mysql:3306、upstream-proxy:8510),二进制部署必须改为实际地址:
# admin-svr / openapi / worker-svr / app-server
database:
default:
link: "mysql:u_iotlcm:<口令>@tcp(127.0.0.1:3306)/db_iotlcm?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai"
redis:
default:
address: "127.0.0.1:6379"
rabbitmq:
dsn: "amqp://<用户>:<口令>@127.0.0.1:5672/"
# upstream-chan / upstream-proxy
registry:
address: "127.0.0.1:8500"
# 上游服务地址
upstream:
proxy:
address: "127.0.0.1:8510"
gateway:
address: "127.0.0.1:8110"
::: danger logger.path 也要改
配置里的 logger.path 在容器版本中是 /app/logs,二进制部署要改为实际路径,例如 /opt/iotlcm/admin-svr/logs,否则会因目录不存在启动失败。
:::
systemd 托管
以为 admin-svr 为例,保存为 /etc/systemd/system/iotlcm-admin-svr.service:
[Unit]
Description=IotLCM Admin Service
After=network-online.target mysql.service redis.service
Wants=network-online.target
[Service]
Type=simple
User=iotlcm
Group=iotlcm
WorkingDirectory=/opt/iotlcm/admin-svr
ExecStart=/opt/iotlcm/admin-svr/iotlcmadmin_svc
Restart=always
RestartSec=5s
LimitNOFILE=65535
# 环境变量(JWT 密钥等敏感值建议放独立文件)
EnvironmentFile=-/etc/iotlcm/admin-svr.env
# 日志交给 journald,也可用配置里的文件日志
StandardOutput=journal
StandardError=journal
# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/opt/iotlcm/admin-svr
[Install]
WantedBy=multi-user.target
/etc/iotlcm/admin-svr.env:
JWT_SIGNING_KEY=<与其它服务一致的密钥>
启用:
sudo systemctl daemon-reload
sudo systemctl enable --now iotlcm-admin-svr
sudo systemctl status iotlcm-admin-svr
各服务的差异点
| 服务 | 特殊处理 |
|---|---|
| admin-svr | 需 ReadWritePaths 包含 upload 与 logs 目录 |
| worker-svr | 无监听端口,After 需包含 rabbitmq |
| upstream-chan / proxy | After 需包含 consul |
| app-server | 需 resource/log/server 与 resource/upload 可写 |
| bot | ExecStart 需带参数:/opt/iotlcm/bot/iotlcm-bot watch --config /opt/iotlcm/bot/config/config.yaml |
启动顺序
MySQL / Redis / RabbitMQ / Consul
↓
admin-svr、openapi、worker-svr、upstream-chan、upstream-proxy、app-server、sms
↓
admin-ui、app-web、docs(静态文件,由 nginx 托管)
用 systemd 依赖表达:
[Unit]
After=iotlcm-admin-svr.service
Requires=iotlcm-admin-svr.service
静态前端
admin-ui、app-web、docs 是静态文件,二进制部署时不需要跑容器,把构建产物交给 nginx:
# admin-ui:需 Node 构建
cd iotlcm-admin-ui/vue
npm ci && npm run build
sudo cp -r apps/web-antd/dist /var/www/iotlcm/admin-ui
nginx 配置参考部署仓的 config/admin-ui/default.conf 与 config/nginx/iotlcm.conf,把 proxy_pass http://admin-svr:8008 改为 http://127.0.0.1:8008。
验证
# 进程状态
systemctl status iotlcm-admin-svr
journalctl -u iotlcm-admin-svr -n 50 --no-pager
# 端口监听
ss -lntp | grep -E '8008|8000|8510|8110'
# 接口
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8008/api.json
与容器部署的差异
| 项 | 容器部署 | 二进制部署 |
|---|---|---|
| 配置路径 | /app/config(挂载) |
<服务目录>/config |
| 日志路径 | /app/logs |
需在配置里改成实际路径 |
| 服务互访 | 服务名(Docker DNS) | 127.0.0.1 或内网 IP |
| 进程管理 | Docker restart policy | systemd |
| 升级 | 换镜像 + up -d |
停服务 → 换二进制 → 起服务 |
| 时区 | 镜像已内置 | 依赖宿主机 tzdata |
升级流程
# 1. 备份配置与程序
sudo tar czf /backup/iotlcm-admin-svr-$(date +%F).tar.gz -C /opt/iotlcm admin-svr
# 2. 停服务
sudo systemctl stop iotlcm-admin-svr
# 3. 替换二进制
sudo cp iotlcmadmin_svc /opt/iotlcm/admin-svr/
sudo chown iotlcm:iotlcm /opt/iotlcm/admin-svr/iotlcmadmin_svc
# 4. 起服务并验证
sudo systemctl start iotlcm-admin-svr
sudo systemctl status iotlcm-admin-svr
回滚
保留上一版二进制,回滚只需换回:
sudo systemctl stop iotlcm-admin-svr
sudo cp /opt/iotlcm/admin-svr/iotlcmadmin_svc.bak /opt/iotlcm/admin-svr/iotlcmadmin_svc
sudo systemctl start iotlcm-admin-svr