我的资料
首页
Linux技术
开发指南
前端技术
快速开始
Gitee
首页
Linux技术
开发指南
前端技术
快速开始
Gitee
  • Linux技术文档

    • Linux 技术文档
    • VSCode SSH远程连接教程
    • LNMP环境安装指南
    • phpMyAdmin 安装与配置
    • ab-test 压力测试
    • Docker Desktop 开发 & 生产部署
    • Docker 静态站点部署指南
    • WSL2 + Docker 本地开发 & 生产部署

Docker 静态站点部署指南

目录

  1. 本地构建与推送
  2. Ubuntu 服务器拉取与部署
  3. 宿主机 Nginx 配置
  4. 日常维护命令
  5. 常见问题

1. 本地构建与推送

1.1 构建项目

# 在项目根目录执行
npm install
npm run docs:build

构建产物输出到 docs/.vuepress/dist/(即 docker-compose.yml 挂载进容器的目录)。 该目录会一并提交到 Git,服务器只需拉取即可直接使用,无需在服务器上安装 Node 重新构建。

1.2 提交并推送到 Git

git add -A
git commit -m "docs: rebuild for deployment"
git push

项目根目录的 .gitattributes 已统一换行符为 LF,避免在 Windows 编辑后带到 Linux 上出错。 确保远程仓库已配置好,且 Ubuntu 服务器有访问该仓库的权限。


1.3 项目docker相关文件

① docker-compose.yml

services:

  # ========================================
  # Nginx (Web 服务器)
  # ========================================
  nginx:
    image: nginx:1.25-alpine
    container_name: doc-nginx
    restart: unless-stopped
    ports:
      # 只绑定本地回环地址,由宿主机 Nginx 反代接入,统一处理 SSL
      - "127.0.0.1:8002:80"
    volumes:
      # 静态站点:本地 npm run docs:build 生成 docs/.vuepress/dist 并提交到 Git
      - ./docs/.vuepress/dist:/var/www/html:ro
      - ./docker/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf:ro
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

② docker/nginx/example.com.conf(宿主机反代模板,占位符 __DOMAIN__)

# 宿主机 Nginx 反向代理配置模板(占位符 __DOMAIN__ 由 run.bash 自动替换)
#
# 推荐用法(在项目根目录执行,脚本会自动替换占位符、安装配置并重载 Nginx):
#   ./run.bash <你的域名>
#
# 手工用法:
#   sed 's/__DOMAIN__/你的域名/g' docker/nginx/example.com.conf \
#     | sudo tee /etc/nginx/sites-available/你的域名
#   sudo ln -sfn /etc/nginx/sites-available/你的域名 /etc/nginx/sites-enabled/你的域名
#   sudo nginx -t && sudo systemctl reload nginx
#
# 前置条件:证书 /etc/nginx/ssl/fullchain.pem 与 /etc/nginx/ssl/privkey.key 已存在

# 强制 HTTP → HTTPS 跳转
server {
    listen 80;
    server_name __DOMAIN__;
    return 301 https://$host$request_uri;
}

# HTTPS 服务
server {
    # 注意:Ubuntu 24.04 自带 Nginx 1.24,须保留 "ssl http2" 写法;
    #       Nginx >= 1.25.1 建议改为 "listen 443 ssl;" + "http2 on;"
    listen 443 ssl http2;
    server_name __DOMAIN__;

    # SSL 证书(使用 acme.sh 申请泛域名证书后,所有站点共用)
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.key;

    # SSL 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # 日志
    access_log /var/log/nginx/doc-access.log;
    error_log  /var/log/nginx/doc-error.log;

    # 客户端上传大小限制
    client_max_body_size 64M;

    # 反代到本项目的 Docker Nginx
    location / {
        proxy_pass http://127.0.0.1:8002;
        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;
    }
}

③ docker/nginx/conf.d/default.conf

# 使用 realip 模块从上游(宿主机 Nginx)获取真实客户端 IP
# 注意:容器经过端口映射后,请求来源是 Docker 网桥网关(172.16.0.0/12),
#      而不是 127.0.0.1,所以只写 127.0.0.1 会导致真实 IP 不被信任。
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 127.0.0.1;
real_ip_header X-Real-IP;
real_ip_recursive on;

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.html index.htm;

    # 不对外暴露 nginx 版本号
    server_tokens off;

    # gzip 压缩
    gzip on;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml image/svg+xml;
    gzip_min_length 1k;
    gzip_vary on;

    # 静态资源缓存
    location ~* \.(gif|jpe?g|png|bmp|swf|ico|svg|webp|woff2?|ttf|eot)$ {
        expires 30d;
        access_log off;
    }

    # JS/CSS(VuePress 产物文件名带 hash,可放心缓存)
    location ~* \.(js|css)$ {
        expires 7d;
        access_log off;
    }

    # 未命中的路径返回 VuePress 生成的 404 页面,并保留 404 状态码
    error_page 404 /404.html;
    location = /404.html {
        internal;
    }

    location / {
        # 依次尝试:真实文件 -> 目录 -> 同名 .html(VuePress 产物形态),
        # 都未命中则 404,避免把不存在的地址伪装成首页 200
        try_files $uri $uri/ $uri.html =404;
    }
}

2. Ubuntu 服务器拉取与部署

2.1 首次部署

# 进入用户 projects 目录
cd ~/projects

# 克隆项目(docs/.vuepress/dist 已包含在仓库中,无需再构建)
git clone <仓库地址> mydoc

# 进入项目目录
cd mydoc

2.2 启动 Docker 容器

项目已提供 docker-compose.yml,直接启动即可:

# 启动容器(后台运行)
docker compose up -d

启动后验证容器状态:

docker compose ps

应能看到 doc-nginx 容器正常运行,监听 127.0.0.1:8002。

2.3 更新部署

当有代码更新时:

cd ~/projects/mydoc

# 拉取最新代码(docs/.vuepress/dist 已包含在提交中)
git pull

# 目录是 bind mount,静态文件立即生效,无需重启容器。
# 仅在改动 docker-compose.yml 或 Nginx 配置后需要重建容器:
docker compose up -d

3. 宿主机 Nginx 配置

请先把你的域名解析到服务器 IP(仓库里不写死域名,由部署脚本传入)。 项目 Docker Nginx 运行在 127.0.0.1:8002,由宿主机 Nginx 反代并统一处理 SSL。

3.1 一键安装(推荐)

项目根目录的 run.bash 会读取模板 docker/nginx/example.com.conf,把域名占位符 __DOMAIN__ 替换为真实域名,安装到 /etc/nginx/sites-available/ 并重载 Nginx:

cd ~/projects/mydoc
chmod +x run.bash
./run.bash doc.example.com          # 换成你的真实域名;不要用 sudo 执行

脚本可重复执行(幂等),并在域名未传、模板缺失、证书不存在时提前报错退出。

3.2 手工安装(不使用脚本时)

cd ~/projects/mydoc
DOMAIN=doc.example.com

sed "s/__DOMAIN__/$DOMAIN/g" docker/nginx/example.com.conf | sudo tee /etc/nginx/sites-available/$DOMAIN
sudo ln -sfn /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/$DOMAIN
sudo nginx -t && sudo systemctl reload nginx

前置条件:证书 /etc/nginx/ssl/fullchain.pem 与 /etc/nginx/ssl/privkey.key 已存在 (用 acme.sh 申请泛域名证书后所有站点共用)。


4. 日常维护命令

操作命令
查看容器状态docker compose ps
查看容器日志docker compose logs -f
重启容器docker compose restart
停止容器docker compose down
重新构建并启动docker compose up -d --build
宿主机 Nginx 重载sudo systemctl reload nginx
宿主机 Nginx 状态sudo systemctl status nginx

5. 常见问题

Q: 为什么 Docker Nginx 绑定在 127.0.0.1:8002 而不是 0.0.0.0:8002?

为了安全。Docker Nginx 只监听本地回环地址,不直接暴露给外网。所有外部请求必须经过宿主机 Nginx(已配置 SSL),再由宿主机转发到 Docker 内部。

Q: 容器启动后访问出现 502 Bad Gateway?

  • 检查 docker compose ps 确认容器是否正常运行
  • 检查宿主机 Nginx 配置中的 proxy_pass 地址是否正确
  • 检查 Docker 容器端口映射:docker port doc-nginx

Q: 更新代码后页面没变化?

cd ~/projects/mydoc
git pull

容器以 bind mount 方式挂载 ./docs/.vuepress/dist,git pull 后新文件立即生效,不需要重启容器。 若页面仍是旧内容,先确认本地是否已重新执行 npm run docs:build 并提交,再用 Ctrl+F5 强制刷新浏览器缓存。

Q: 如何查看构建后的文件是否正确?

ls -la ~/projects/mydoc/docs/.vuepress/dist/
最近更新:: 2026/9/20 13:05
Prev
Docker Desktop 开发 & 生产部署
Next
WSL2 + Docker 本地开发 & 生产部署

MIT 许可 © 2026 我的资料

Gitee 仓库  |  快速开始

皖ICP备2026030673号-1
皖公网安备34040002000683号