记录一次node项目优化方案

优化前:

  1. 以ubuntu发行版为基础镜像
  2. 不带小版本号
  3. 每次构建都从头构建(这里也推荐将package*json先copy过来进行install再copy . .,如果文件没变化,那就使用缓存,不重新构建)

优化后:

  1. 建立runtime基础镜像(包含提前安装好的基础依赖和环境, 包括node_modules),并使用alpine为基础镜像发行版
  2. 使用nexus管理项目包(docker/npm/maven)
  3. 指定具体版本号(只有 major version,没有指定 minor version、patch version。当该基础镜像 minor 或 patch 版本更新后,如果本地的镜像缓存也被清除了,那么打包就会使用新版本的基础镜像)
  4. 构建 Docker 镜像的时候,会缓存 Dockerfile 中尚未更改的所有步骤。所以,如果新构建时更改任何指令,将后的指令步骤将会重新来不再使用缓存。举例来说,就是指令 3 发生了变更,其后的 4-n 就会重跑并重新生成缓存。
    因此,编写 Dockerfile 的时候,就需要将最不可能产生更改的指令放在前面。比如,可以把 WORKDIR/ENV 等命令放在前面,COPY/ADD 等命令放在后面。这样,在构建过程中较多的使用了缓存,就可以节省很多时间了。
  5. 多阶段构建,以减小镜像体积(多阶段构建会减慢构建速度, 可以参考加快多阶段构建速度篇)
  6. .dockerignore(排除那些容器运行时不需要的文件;排除那些不会在构建过程中[这里更多指copy和add的时候]使用的中间文件)
    1
    2
    3
    4
    5
    6
    7
    package.json
    package-lock.json
    node_modules
    .gitlab-ci.yml
    deployment.yaml
    Dockerfile
    .gitignore

dockerfile例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 这里还需要注意ARG在from之前,那就只能用在from指令上,而且如果有变动则后续都无法使用缓存
ARG NODE_ENV
FROM xxx:5000/${NODE_ENV}/node-basic:12.22.0-alpine-backend as build
WORKDIR /user/src/app
ARG PROJETC_NAME
# 这里使用的使runtime基础镜像中早已构建好的node_modules(仅使用版本依赖不会频繁更新的项目)
RUN mv /data/app/${PROJETC_NAME}/node_modules /data/app/${PROJETC_NAME}/package.json .
# 这里是不包含多余依赖以及组件的runtime基础镜像,仅使用上阶段构建好的node_modules,以减小镜像体积
FROM xxx:5000/${NODE_ENV}/node-basic:12.22.0-alpine as runtime
WORKDIR /user/src/app
COPY . .
COPY --from=build /user/src/app/node_modules ./node_modules/
COPY --from=build /user/src/app/package.json .
COPY --from=build /usr/local/lib/node_modules/pm2 /usr/local/lib/node_modules/pm2/
RUN ln -s /usr/local/lib/node_modules/pm2/bin/pm2-runtime /usr/local/bin/pm2-runtime \
&& ln -s /usr/local/lib/node_modules/pm2/bin/pm2-docker /usr/local/bin/pm2-docker \
&& ln -s /usr/local/lib/node_modules/pm2/bin/pm2-dev /usr/local/bin/pm2-dev \
&& ln -s /usr/local/lib/node_modules/pm2/bin/pm2 /usr/local/bin/pm2 \
&& chmod +x /usr/local/bin/pm2*
CMD [ "pm2", "start", "pm2.json", "--no-daemon" ]

补记:配置加速源

腾讯云主机建议优先考虑配置 https://mirror.ccs.tencentyun.com

1
2
3
4
5
6
7
8
9
10
11
12
vim /etc/docker/daemon.json

{
"insecure-registries": ["xxx:xxx"],
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
"features": { "buidkit": true },
"storage-driver": "overlay2"
}


systemctl daemon-reload
systemctl restart docker