Files
iotlcm/docs/deploy/docker-nginx.md
T
Dai0814 22a177c569 docs: 部署手册拆分为多页,左侧形成三层目录
原单页塞了 13 个二级标题、右侧目录过长。拆成 7 页:
- 概览(含选型指引与环境对照表)
- 路径前缀必读(独立成页,最高频故障)
- 推荐环境:Docker + nginx
- 静态托管部署(nginx 子路径/根路径、Apache、Caddy、对象存储、pnpm)
- 内网与离线部署(4 种方案 + 对比表)
- 本地开发与预览(含新增页面步骤)
- 常见问题(部署/构建/运行三类 + 自检清单)

侧边栏分为三组:部署手册 / 部署方式 / 开发与排错
2026-10-26 17:12:18 +08:00

3.9 KiB
Raw Blame History

title, description, outline
title description outline
Docker + nginx 部署 推荐环境部署方式:多阶段构建镜像 + nginx 托管 deep

推荐环境部署:Docker + nginx

适用:生产环境、需要长期稳定运行、机器上不想装 Node。

仓库自带多阶段 Dockerfile:Node 阶段执行 vitepress build,最终镜像只含 nginx 与静态产物,不含 Node 和 node_modules。

构建镜像

SHA=$(git rev-parse --short HEAD)
docker build -t iotlcm-docs:$SHA .

用 commit sha 做标签,便于追溯与回滚;不建议只用 latest。

启动容器

docker run -d \
  --name iotlcm-docs \
  --restart unless-stopped \
  -p 8019:80 \
  iotlcm-docs:$SHA

nginx 配置(关键)

docker/nginx.conf 用 alias 把 /docs/ 前缀剥掉:

server {
    listen 80;
    server_name _;

    root /usr/share/nginx/html;
    index index.html;

    # 产物按 base=/docs/ 生成,资源引用形如 /docs/assets/xxx
    location /docs/ {
        alias /usr/share/nginx/html/;
        try_files $uri $uri.html $uri/ $uri/index.html =404;
    }

    # 根路径跳到文档入口,避免访问 / 时白屏
    location = / {
        return 302 /docs/;
    }

    location / {
        try_files $uri $uri.html $uri/ =404;
    }
}

try_files 里的 $uri.html 与 $uri/index.html 是必需的:配置启用了 cleanUrls: true,页面 URL 不带 .html 后缀,需要服务器做内部映射。

原理说明见 路径前缀必读。

部署后自检

# 1. 入口可访问(应返回 200)
curl -o /dev/null -s -w '%{http_code}\n' http://127.0.0.1:8019/docs/

# 2. 根路径应 302 到 /docs/
curl -o /dev/null -s -w '%{http_code}\n' http://127.0.0.1:8019/

# 3. 静态资源不能 404(最容易出问题的一步)
ASSET=$(curl -s http://127.0.0.1:8019/docs/ | grep -o '/docs/assets/style[^"]*\.css' | head -1)
curl -o /dev/null -s -w '%{http_code}\n' "http://127.0.0.1:8019$ASSET"

# 4. 抽查正文页面
curl -o /dev/null -s -w '%{http_code}\n' http://127.0.0.1:8019/docs/manual/web/

四项都返回 200(第 2 项返回 302)才算部署成功。

通过外层反向代理对外

生产常见做法:容器只监听 127.0.0.1,由外层 nginx 转发。

upstream iotlcm_docs {
    server 127.0.0.1:8019;
}

location = /docs {
    return 301 /docs/;
}

location /docs/ {
    proxy_pass http://iotlcm_docs;   # 末尾不要加斜杠
    proxy_http_version 1.1;
    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;
}

::: danger proxy_pass 末尾斜杠 写成 proxy_pass http://iotlcm_docs/;(带末尾斜杠)会把 /docs/ 前缀剥掉,转发到容器变成 /,导致资源全部 404 白屏。必须不带末尾斜杠。 :::

docker compose

docker-compose.yml 中镜像名是占位值,需替换为自己的仓库地址:

services:
  docs:
    image: your-registry/iotlcm/iotlcm-docs:${TAG:-latest}
    container_name: iotlcm-docs
    restart: unless-stopped
    ports:
      - "127.0.0.1:8019:80"
    networks:
      - iotlcm-network

networks:
  iotlcm-network:
    external: true
    name: iotlcm-network

compose 文件声明 iotlcm-network 为外部网络,若不存在需先创建:

docker network create iotlcm-network

启动:

TAG=$(git rev-parse --short HEAD) docker compose up -d

版本固定与升级

开源仓按固定版本发布(无 git 历史,单次初始提交)。部署时请记录并锁定 commit:

SHA=$(git rev-parse HEAD)
echo "部署基线: $SHA" >> deploy.log
docker build -t iotlcm-docs:$SHA .

升级文档时,从上游选定基线重新发布后,按新 sha 重建镜像并滚动替换容器:

docker rm -f iotlcm-docs
docker run -d --name iotlcm-docs --restart unless-stopped -p 8019:80 iotlcm-docs:$NEW_SHA