一、前端镜像制作的基本思路

前端项目和后端项目的容器化思路有一个很大的不同点:

  • 前端通常先在构建环境里产出静态文件
  • 最终镜像里通常只需要一个静态 Web 服务器,例如 Nginx

这意味着前端镜像往往不需要把 Node 构建环境放进最终运行镜像。

二、准备源码和构建环境

原始示例使用的源码地址:

https://gitee.com/dukuan/vue-project.git

用于构建的基础镜像:

registry.cn-hangzhou.aliyuncs.com/abroad_images/node:lts

构建命令:

npm install --registry=https://registry.npmmirror.com/
npm run build

三、为什么建议先用临时容器构建

示例不是直接在宿主机安装 Node,而是启动一个临时容器来完成构建:

git clone https://gitee.com/dukuan/vue-project.git

docker run -it --rm \
  -v `pwd`/vue-project/:/mnt/ \
  registry.cn-hangzhou.aliyuncs.com/abroad_images/node:lts bash

进入容器后执行:

cd /mnt/
npm install --registry=https://registry.npmmirror.com/
npm run build

这种做法有几个明显好处:

  • 宿主机无需安装 Node 构建环境
  • 构建环境更加统一
  • 团队成员更容易复现实验结果

四、如何确认前端构建真的成功了

构建完成后,要先确认 dist 目录已经生成:

ls dist/

然后回到宿主机再次确认 dist 目录已经映射出来:

ll vue-project/

只要宿主机目录中已经看到 dist,就说明这次前端构建产物已经可以拿来制作运行镜像了。

五、前端镜像为什么通常用 Nginx

前端项目在生产环境里通常不需要 Node 持续运行,很多时候只需要一个稳定、简单、性能不错的静态文件服务器即可,因此 Nginx 是最常见的选择。

对应的 Dockerfile 非常简洁:

FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/nginx:1.15.12
COPY dist/ /usr/share/nginx/html/

这份 Dockerfile 体现了一个非常重要的思想:

  • 构建环境和运行环境分离

Node 只负责产出静态文件,而最终镜像只保留 Nginx 和打包结果。

六、这里最容易踩的坑是什么

原始笔记里提到一个很关键的细节:

COPY dist/ /usr/share/nginx/html/

这里不能写成:

COPY dist/* /usr/share/nginx/html/

原因是带 * 时,dist 目录下的子目录结构,尤其是 static 目录,可能无法按预期完整复制进去,最终导致前端资源访问异常。

所以更稳妥的方式就是直接复制整个 dist/ 目录内容。

七、构建和运行前端镜像

在项目目录下构建镜像:

docker build -t registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1 .

然后启动容器:

docker run -d -p 18080:80 registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1

这里把宿主机 18080 端口映射到容器内 Nginx 的 80 端口。

八、如何验证前端镜像是否可用

可以直接用 curl 验证:

curl 10.0.0.12:18080

如果返回了页面 HTML 内容,并且浏览器访问能正常加载静态资源,说明下面几步都已经成功:

  • 前端构建成功
  • dist 内容正确复制到 Nginx 目录
  • Nginx 容器正常运行
  • 端口映射和网络访问都没有问题

九、把这套流程迁移到其他前端项目时,重点关注什么

当你把这套方法用到其他 Vue、React 或 H5 项目时,最需要关注的通常是下面几点:

  • 构建命令是不是 npm run build
  • 产物目录是不是 dist
  • 是否需要额外的 Nginx 配置文件
  • 前端是否依赖运行时环境变量注入

但整体流程通常不会有本质变化:先构建,再把静态产物交给 Nginx。

这也是前端容器化最核心的经验:不要把开发环境、构建环境和运行环境混成一团,分清职责之后,镜像会更小,部署也会更稳。