前端搞Docker

896 阅读5分钟

先搞清楚基本理论

下面我们可以看到有大致三步,我们不讨论具体的关系,直接讲如何跑通这个流程,如果不理解这个流程可以先看看一些入门视频。

前端项目+dockerfile ——》docker镜像 ——》docker容器

第一步:前端项目 + dockerfile文件

我们一般将dockerfile文件放在前端项目,这是一个约定俗成或者图方便的方式,算最佳实践。

同时我们也知道dockerfile文件可以直接生成docker镜像,不需要任何其他文件,但是我们是前端项目,要部署前端项目到容器里,所以是“前端项目+dockerfile”的组合。

我们需要dockerfile生成的镜像能运行容器时是一个前端项目,所以dockerfile要围绕前端项目和前端环境。

下面是dockerfile文件,具体的指令下面解释,这里主要依靠构建前端项目dist和nginx服务两部分组成,同时nginx服务的持续性也使得这个镜像运行的容器不会关闭。


FROM node:21 AS builder

WORKDIR /data

COPY . .

RUN npm config set registry https://registry.npmmirror.com && \
    npm install -g pnpm && \
    pnpm i && \
    pnpm build

FROM nginx

COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /data/dist /usr/share/nginx/html

镜像配置文件的详细解释:

以下场景为dockerfile所编写的逻辑,在构建镜像时执行,构建时会创建临时目录空间。

  • 一个FROM代表一个构建阶段,最后的FROM才是容器实际的环境,前端的构建的操作都是临时,只能被引用(比如--from=builder /data/dist)。
  • FROM从docker hub中拉取基本和公用的基础镜像内容,node:21镜像环境提供包括npm在内的环境,所以可以直接执行npm指令。
  • WORKDIR是创建容器路径,不写,会自动创建。
  • COPY这里是镜像将存在于宿主机中的文件复制到当前阶段的容器里,因为dockerfile镜像构建时一开始只能从FROM选择的基础镜像中获取文件。
  • 因为dockerfile文件放在前端项目根目录里,COPY这里前面的“.”是拷贝前端根目录全部内容,COPY这里后面的“.”是将拷贝的内容复制到容器里,具体位置为容器里的根目录,在具体就是前面“WORKDIR /data”的/data这个位置。这里两个“.”都可以自定义,不过我们推荐用默认。
  • registry.npmmirror.com 是第三方的地址,使得npm下载依赖速度更快。
  • 使用pnpm是前端项目选择,个人可以自定义包管理工具的使用。
  • 在第一个FROM阶段里我们将前端项目临时的复制到一个目录里,然后通过最后的build得到前端项目的构建产物(dist)。
  • 在第二FROM阶段里我们选择nginx基础镜像,一个是为了创建web服务器,另外一个原因是使得最后运行的容器里只有nginx环境,减少前端开发环境node,因为第二的FROM会使得前面的阶段“遗弃”,只能引用其中的内容。可以理解为我们用node环境构建完前端项目后,不再需要并删除node环境换成nginx使用构建产物来搭建web服务器。
  • nginx基础镜像默认会在容器里运行nginx服务,同时有默认的配置地址,所以我们会在前端项目里写一份nginx配置文件,在这里通过COPY来覆盖默认的配置文件,从而实现自定义。
  • “--from=builder /data/dist”这里是一个整体,--from是指令,--from=builder的意思是从FROM node:21 AS builder这个阶段引用内容。前面的AS builder就类似定义一个变量名,--from=builder这里就是使用变量。所以/data/dist就是builder阶段的产物,本身在第二FROM阶段里是没有的。这里builder可以是任何自定义的值。
  • 最后的COPY就是将builder阶段构建的产物复制到nginx服务分发web资源的位置,从而使得nginx代理的内容是我们我开发的前端项目。

第二步:docker镜像

上面的dockerfile关联了前端项目,在构成镜像前都需要保持写好的相对位置,不然下面的build将会失败。

通过下面的指令,我们可以将当前位置下的dockerfile构建成一个镜像。

docker build -t docker_image .

其他一些细节:

  • docker build是构建镜像的核心指令,需要dockerfile文件和其他上下文内容。
  • 最后的"."就是dockerfile文件和其他上下文内容所在位置,也就是当前执行指令时的宿主机位置。
  • -t是一个参数,给镜像命名的,“-t docker_image”意为镜像名为“docker_image”。
  • 因为没有推送到镜像到harbor仓库里,所以默认存放在整个宿主机上,在任何地方都可以调用。

第三步:docker容器

通过下面的指令,我们可以将当前宿主机内的镜像启动成容器。

docker run -itd --name docker_containers --network nginx_network -p 8088:80 docker_image

详细解释:

  • “-itd”是“-i -t -d”三个参数,分布意为“标准输入保持打开状态”“分配一个伪终端,允许你与容器进行交互”“在后台运行”。效果就是可以打开容器的伪终端,同时创建容器时先隐藏在后台。
  • “--name docker_containers”,命名参数,参考上面的“-t”。
  • “--network nginx_network”中“--network”是关联容器网络的参数,这里意为容器连接“nginx_network”的网络。一般是为了容器里可以进入特定网络和其他容器通信。
  • “-p 8088:80”转发端口,宿主机8088,容器80,意为我在宿主机访问8088时转发请求到容器里的80端口
  • 最后放的是镜像名“docker_image”。

推荐工具

使用vscode的remote插件来ssh关联远端宿主机,再使用docker插件来查看和管理镜像和docker,结合终端命令方便管理和控制镜像和容器的创建。

image.png

image.png

ps:有空将会补充视频或图文辅助讲解