Skip to content

Linux 部署 ​

生产环境首选。适用于 x86_64 的 Ubuntu、Debian、CentOS / Rocky / AlmaLinux、openEuler、麒麟 V10(x86 版)、统信 UOS(x86 版)等发行版。可执行文件是静态编译的,不依赖 glibc 版本,也不需要安装任何运行库。

使用交付包:linux-amd64.zip。

三种托管方式任选其一:

方式适合开机自启崩溃自动拉起
一、systemd 托管(推荐)长期运行✅✅
二、start.sh 脚本临时验证❌❌
三、deploy.sh 远程推送包在你的电脑上,目标是远程服务器取决于服务器上的托管方式同左

想用 Docker 的看 Linux(Docker)。

1. 准备服务器 ​

1.1 确认架构 ​

bash
uname -m

输出 x86_64 才能用 linux-amd64 包。输出 aarch64 说明是 ARM 服务器,需要联系我方单独构建。

1.2 创建运行用户与目录 ​

不要用 root 运行服务:

bash
sudo useradd --system --create-home --home-dir /opt/apexpm --shell /usr/sbin/nologin apexpm

1.3 放置文件 ​

把交付包传到服务器并解压:

bash
# 在你的电脑上
scp acme-apexpm-vX.Y.Z.tar.gz user@服务器IP:/tmp/

# 在服务器上
sudo tar xzf /tmp/acme-apexpm-vX.Y.Z.tar.gz -C /opt/apexpm --strip-components=1
sudo chmod +x /opt/apexpm/apexpm /opt/apexpm/*.sh
sudo chown -R apexpm:apexpm /opt/apexpm

收到的是 zip 时用 unzip linux-amd64.zip -d /opt/apexpm。

1.4 放行端口 ​

bash
# firewalld(CentOS / Rocky / openEuler / 麒麟)
sudo firewall-cmd --permanent --add-port=9000/tcp && sudo firewall-cmd --reload

# ufw(Ubuntu / Debian)
sudo ufw allow 9000/tcp

云服务器还要在控制台的安全组里放行同一端口。

常见错误 ​

现象原因处理
cannot execute binary file: Exec format error架构不符,比如把 amd64 包放到了 ARM 服务器上按 1.1 确认架构,换对应的包
Permission denied(执行 ./apexpm 时)文件没有可执行权限,或所在分区挂载了 noexecchmod +x apexpm;mount | grep noexec 检查,换到其他分区
useradd: user 'apexpm' already exists用户已存在可以忽略,直接进行下一步
浏览器访问超时,服务器上 curl 127.0.0.1:9000 正常防火墙或安全组没放行按 1.4 放行,检查云控制台安全组

2. 配置 ​

bash
cd /opt/apexpm
[ -f config.yaml ] || sudo -u apexpm cp config.example.yaml config.yaml
sudo -u apexpm vi config.yaml

Linux 上至少改这几项:

字段怎么改
jwt.secretopenssl rand -hex 32 生成后填入
server.port需要换端口时修改,同时改防火墙规则
server.public_base_url填 http://<服务器内网IP>:9000,多网卡时尤其要填
license.webhook.url填飞书 / 钉钉机器人地址

每个字段的完整说明见配置文件 config.yaml。

确认授权文件就位:

bash
ls -l /opt/apexpm/data/license.lic

确认授权绑定的 IP 与本机网卡一致:

bash
ip -4 addr show | grep inet

常见错误 ​

现象原因处理
config.yaml 保存后启动报 yaml: line N缩进用了 Tab 或冒号后没有空格vi 里 :set list 显示 Tab,改成空格
ls: cannot access 'data/license.lic'授权文件没放进去把我方提供的 .lic 复制到 data/license.lic,注意文件名
ip addr 里没有签发授权时提供的 IP服务器 IP 变过,或提供的是公网 IP(云服务器公网 IP 不在网卡上)把 ip addr 里看到的内网 IP 发给我方重新签发

方式一:systemd 托管(推荐) ​

创建服务文件 /etc/systemd/system/apexpm.service:

ini
[Unit]
Description=ApexPM
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=apexpm
Group=apexpm
# 必须是部署目录:程序在这里找 config.yaml 并创建 data/
WorkingDirectory=/opt/apexpm
ExecStart=/opt/apexpm/apexpm
Restart=on-failure
RestartSec=5
# 停止时给 10 秒优雅退出
TimeoutStopSec=10
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

启用并启动:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now apexpm
sudo systemctl status apexpm

查看日志:

bash
journalctl -u apexpm -f              # 实时
journalctl -u apexpm -n 100 --no-pager   # 最近 100 行

日常操作:

bash
sudo systemctl restart apexpm        # 改完 config.yaml 后
sudo systemctl stop apexpm

常见错误 ​

现象原因处理
status=203/EXECExecStart 路径错或文件不可执行核对路径,chmod +x /opt/apexpm/apexpm
status=200/CHDIRWorkingDirectory 目录不存在核对路径
status=217/USER服务文件里的 User 不存在按 1.2 创建用户,或改成已有用户
日志 create data dir failed ... permission denied运行用户对部署目录没有写权限sudo chown -R apexpm:apexpm /opt/apexpm
日志 bind: address already in use端口被占用sudo ss -lntp | grep 9000 找到占用进程;或改 server.port
Unit apexpm.service not found没执行 daemon-reload,或文件名、位置不对确认文件在 /etc/systemd/system/ 下后执行 daemon-reload
进程反复重启,systemctl status 显示 activating (auto-restart)启动即退出,被 Restart=on-failure 不断拉起journalctl -u apexpm -n 50 看退出前的 "level":"fatal" 日志,对照故障排查总表

方式二:start.sh 脚本 ​

适合临时验证。不开机自启,进程挂了也不会自动拉起。

bash
cd /opt/apexpm
sudo -u apexpm ./start.sh     # 后台启动,pid 写 apexpm.pid,日志追加到 apexpm.log
sudo -u apexpm ./stop.sh      # 优雅停止,10 秒未退出则强制结束
tail -f apexpm.log

不要和 systemd 混用

同一个部署目录只用一种托管方式。已经用 systemd 托管时再执行 start.sh,第二个进程会因端口被占用而退出。

常见错误 ​

输出原因处理
Error: config.yaml not found.部署目录下没有 config.yaml按第 2 步从模板复制
apexpm is already running (pid N)已经在运行不需要处理;要重启就先 ./stop.sh
apexpm started 但访问不了进程启动后立即退出了tail -50 apexpm.log 看 fatal 日志
stop.sh 输出 timed out, sending SIGKILL10 秒内没退出,被强制结束偶发可忽略;频繁出现请保留日志联系我方
apexpm is not running (stale pid N)进程已经不在,pid 文件是残留脚本已自动清理,直接 ./start.sh

方式三:deploy.sh 远程推送 ​

交付包在你的电脑上(Linux 或 macOS),服务要跑在远程 Linux 服务器上时使用。脚本不编译任何东西,只推送文件并重启。

前提:本机有 ssh 和 rsync,且能免密登录目标服务器(ssh-copy-id user@服务器IP)。服务器上也需要装 rsync 和 curl。

bash
cd apexpm-vX.Y.Z          # 解压后的交付包目录
SERVER=ubuntu@1.2.3.4 ./deploy.sh
SERVER=ubuntu@1.2.3.4 DEPLOY_DIR=/opt/apexpm ./deploy.sh   # 默认 /home/deploy/apexpm

脚本依次完成四步:

  1. 检查:本机工具、交付包完整性、包内二进制与服务器架构是否匹配
  2. 推送:二进制先推为 apexpm.new,同步 start.sh / stop.sh / config.example.yaml / data/license.lic
  3. 备份 + 重启:已有数据库时先把 data/ 备份为 data.bak-时间戳(保留最近 5 份),然后停服、换二进制、启动。首次部署会从模板生成 config.yaml
  4. 健康检查:最多等 18 秒请求 /health,成功后打印授权状态

首次部署后必须改配置

首次部署时 config.yaml 是从模板直接生成的,jwt.secret 仍是默认值。登录服务器修改后执行 ./stop.sh && ./start.sh。

与 systemd 搭配

deploy.sh 用 start.sh / stop.sh 启停进程。服务器已改用 systemd 托管时,不要再用 deploy.sh,改用手工升级。

常见错误 ​

输出原因处理
请设置 SERVER没带 SERVER 变量SERVER=user@IP ./deploy.sh
!! 本机缺少 rsync本机没装 rsyncmacOS:brew install rsync;Ubuntu:sudo apt install rsync
!! 当前目录没有 apexpm不在交付包目录里执行cd 到解压后的目录再执行
Permission denied (publickey)没配置免密登录ssh-copy-id user@IP 后重试
!! 包里的二进制与服务器架构不符包与服务器架构不一致换对应架构的包;ARM 服务器联系我方
!! 未知服务器架构服务器既不是 x86_64 也不是 aarch64不支持该架构
rsync: command not found(远端)服务器上没装 rsync在服务器上安装 rsync
mkdir: cannot create directory ... Permission deniedSSH 用户对 DEPLOY_DIR 的上级目录没有写权限换一个有权限的 DEPLOY_DIR,或先在服务器上建好目录并 chown
!! 服务未就绪,日志末尾:启动失败或 18 秒内没起来看脚本打印的日志末尾,对照故障排查总表。数据已备份,可以放心排查

可选:Nginx 反向代理与 HTTPS ​

需要用域名或 HTTPS 访问时,在前面加一层 Nginx:

nginx
server {
    listen 443 ssl;
    server_name pm.example.com;

    ssl_certificate     /etc/nginx/certs/pm.example.com.pem;
    ssl_certificate_key /etc/nginx/certs/pm.example.com.key;

    # 附件上传大小上限,按需调整
    client_max_body_size 200m;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }
}

同时把 config.yaml 的 server.public_base_url 改成 https://pm.example.com,否则电子签名二维码里的链接会指向内网地址。

现象原因处理
上传附件报 413 Request Entity Too LargeNginx 默认只允许 1 MB 的请求体调大 client_max_body_size
导出大报表时报 504 Gateway Time-out代理超时调大 proxy_read_timeout
扫码签名打开的是内网地址没配 public_base_url按上文配置

升级 ​

升级只换可执行文件,config.yaml 和 data/ 一律保留。完整说明与回滚见版本升级。

systemd 托管:

bash
cd /opt/apexpm
sudo systemctl stop apexpm
sudo -u apexpm cp -a data "data.bak-$(date +%Y%m%d-%H%M%S)"     # 必做
sudo unzip -o /tmp/linux-amd64.zip apexpm -d /opt/apexpm
sudo chmod +x apexpm && sudo chown apexpm:apexpm apexpm
sudo systemctl start apexpm
curl -fsS http://127.0.0.1:9000/health && journalctl -u apexpm -n 30 --no-pager

start.sh 托管: 同上,把 systemctl stop/start 换成 ./stop.sh / ./start.sh。

deploy.sh: 在本机的新版本交付包目录里重新执行一次 SERVER=... ./deploy.sh,备份与替换都会自动完成。

卸载 ​

bash
sudo systemctl disable --now apexpm
sudo rm /etc/systemd/system/apexpm.service && sudo systemctl daemon-reload
# 确认 data/ 已备份后再删
sudo rm -rf /opt/apexpm && sudo userdel apexpm
研值云图·© 2026 研值云图 版权所有