一.dify-web的Dockerfile文件
dify-web的Dockerfile文件如下所示:
# base image
FROM node:20.11-alpine3.19 AS base
LABEL maintainer="[email protected]"
# if you located in China, you can use aliyun mirror to speed up
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache tzdata
# install packages
FROM base as packages
WORKDIR /app/web
COPY package.json .
COPY yarn.lock .
# if you located in China, you can use taobao registry to speed up
# RUN yarn install --frozen-lockfile --registry https://registry.npmmirror.com/
RUN yarn install --frozen-lockfile
# build resources
FROM base as builder
WORKDIR /app/web
COPY --from=packages /app/web/ .
COPY . .
RUN yarn build
# production stage
FROM base as production
ENV NODE_ENV production
ENV EDITION SELF_HOSTED
ENV DEPLOY_ENV PRODUCTION
ENV CONSOLE_API_URL http://127.0.0.1:5001
ENV APP_API_URL http://127.0.0.1:5001
ENV PORT 3000
# set timezone
ENV TZ UTC
RUN ln -s /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone
# global runtime packages
RUN yarn global add pm2 \
&& yarn cache clean
WORKDIR /app/web
COPY --from=builder /app/web/public ./public
COPY --from=builder /app/web/.next/standalone ./
COPY --from=builder /app/web/.next/static ./.next/static
COPY docker/pm2.json ./pm2.json
COPY docker/entrypoint.sh ./entrypoint.sh
ARG COMMIT_SHA
ENV COMMIT_SHA ${COMMIT_SHA}
EXPOSE 3000
ENTRYPOINT ["/bin/sh", "./entrypoint.sh"]
二.Dockerfile文件分析
1.基础镜像设置
FROM node:20.11-alpine3.19 AS base
LABEL maintainer="[email protected]"
- FROM node:20.11-alpine3.19 AS base:此行指定后续指令的基础镜像。这里使用的是基于 Alpine Linux 3.19 的 Node.js 镜像(
node:20.11
),并命名此阶段为base
。 - LABEL maintainer=“takatost@gmail.com”:为镜像添加标签,指定维护者的邮箱。
2.配置中国镜像源(被注释)
# if you located in China, you can use aliyun mirror to speed up
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
- 这部分被注释了,如果在中国,可以通过修改
apk
的源到阿里云来加速包的下载。
3.安装时区数据
RUN apk add --no-cache tzdata
- RUN apk add --no-cache tzdata:安装
tzdata
包,这允许容器使用正确的时区数据。
4.安装依赖包阶段
FROM base as packages
WORKDIR /app/web
COPY package.json .
COPY yarn.lock .
# if you located in China, you can use taobao registry to speed up
# RUN yarn install --frozen-lockfile --registry https://registry.npmmirror.com/
RUN yarn install --frozen-lockfile
- FROM base as packages:从
base
镜像开始新的阶段,命名为packages
。 - WORKDIR /app/web:设置工作目录为
/app/web
。 - COPY package.json . 和 COPY yarn.lock .:将
package.json
和yarn.lock
文件复制到工作目录。 - RUN yarn install --frozen-lockfile:使用 Yarn 安装依赖项,锁定版本。
5.构建资源阶段
FROM base as builder
WORKDIR /app/web
COPY --from=packages /app/web/ .
COPY . .
RUN yarn build
- FROM base as builder:从
base
镜像开始新的阶段,命名为builder
。 - **COPY --from=packages /app/web/ .**:从
packages
阶段复制所有内容到工作目录。 - **COPY . .**:复制当前目录下所有文件到工作目录。
- RUN yarn build:执行构建命令。
6.生产阶段设置
FROM base as production
ENV NODE_ENV production
...
- FROM base as production:从
base
镜像开始新的阶段,命名为production
。 - ENV NODE_ENV production:设置环境变量
NODE_ENV
为production
。 - ENV TZ UTC:设置时区为 UTC。
- RUN yarn global add pm2 \ && yarn cache clean:全局安装 PM2(Node.js 的进程管理器)并清理 Yarn 缓存。
7.最终命令和端口设置
EXPOSE 3000
ENTRYPOINT ["/bin/sh", "./entrypoint.sh"]
- EXPOSE 3000:暴露端口 3000。
- ENTRYPOINT [“/bin/sh”, “./entrypoint.sh”]:设置容器启动时执行的入口点脚本。
该Dockerfile 不仅构建了一个 Node.js 应用的容器环境,还考虑了环境优化和多阶段构建来减小最终镜像的大小。
三.不同构建阶段详解
在 Dockerfile 中使用多阶段构建可以帮助优化最终镜像的大小和安全性,通过构建过程中的不同阶段来管理不同的任务和资源。下面是您的 Dockerfile 中提到的各个阶段(
base
、
packages
、
builder
、
production
)之间的关系和作用:
1. Base 阶段
目的:设置一个共通的基础环境,以供后续的所有阶段使用。这个阶段安装了 Node.js 环境和基础的时区数据(通过安装
tzdata
包)。
优点:所有后续阶段都从这个基础环境继承,这样可以避免重复安装相同的基础软件,减少了构建时间和镜像大小。
2. Packages 阶段
目的:在独立的阶段中安装应用的依赖。这个阶段利用
base
阶段的环境,复制
package.json
和
yarn.lock
文件,并执行
yarn install
命令来安装依赖。
优点:将依赖安装在独立的阶段中可以缓存依赖,除非
package.json
或
yarn.lock
发生变化,否则 Docker 在构建时可以重用缓存的依赖层,这大大加速了构建过程。
3. Builder 阶段
目的:执行应用的构建过程。这个阶段同样基于
base
阶段,并从
packages
阶段复制安装好的依赖及应用代码,然后运行
yarn build
命令来构建应用。
优点:由于此阶段专注于应用的构建,因此可以独立管理构建资源和过程,构建完成后,只需要将构建产物(例如编译后的文件)转移到最终的生产镜像中。
4. Production 阶段
目的:设置用于运行应用的生产环境。这一阶段也是基于
base
阶段,设置了多个环境变量,并从
builder
阶段复制构建产物。此外,安装了 PM2 作为进程管理器来管理 Node.js 应用,并设置了容器的启动入口点。
优点:这个阶段产生了最终的生产镜像,仅包含运行应用所必需的文件和设置,没有包括用于构建应用的依赖和工具,从而确保了生产环境的精简和安全。
5.阶段之间的关系
- 继承性:每个阶段都从
base
阶段继承,保证了环境的一致性。 - 依赖性:
builder
阶段依赖packages
阶段提供的依赖,production
阶段依赖builder
阶段提供的构建产物。 - 优化性:每个阶段聚焦于特定任务,优化了构建过程和最终镜像的大小。
通过这种方式,Dockerfile 的多阶段构建不仅提高了构建的效率,还确保了镜像的整洁和安全,使得维护和部署都更为便捷和可靠。
版权归原作者 NLP工程化 所有, 如有侵权,请联系我们删除。