Dockerfile 是一个文本文件,包含了一系列的指令和指令,这些指令和指令被 Docker 用来主动化构建 Docker 镜像的进程。Docker 镜像是轻量级、可履行的独立软件包,包含了运转一个运用所需的一切内容:代码、运转时环境、库、环境变量和装备文件。
Dockerfile 的主要用途如下:

  1. 界说环境:Dockerfile 答应你精确地界说运转你的运用所需求的操作系统环境、库以及依靠。
  2. 主动化构建:经过 Dockerfile,Docker 能够主动化构建镜像的进程,保证镜像的构建是可重复且共同的。
  3. 代码到布置的共同性:运用 Dockerfile 构建的镜像,能够保证开发、测验和出产环境中的运转环境共同性,减少了“在我机器上能运转”的问题。
  4. 版别操控和追寻:Dockerfile 能够像运用代码相同,被放在版别操控系统中,这样你能够追寻到环境的任何变更,以及回退到任何历史版别。
  5. 便捷的分发和布置:构建好的 Docker 镜像能够被推送到 Docker Hub 或其他容器镜像库房,然后方便地被分发和布置到任何支持 Docker 的平台上。

一个基本的 Dockerfile 或许包含以下指令:

  • FROM:指定根底镜像。一切的 Dockerfile 都有必要以一个 FROM 指令开端,它界说了即将构建的镜像的根底(父)镜像。
  • RUN:履行指令并创立新的镜像层,用于装置软件包和做其他装备。
  • COPY 和 ADD:从构建上下文中仿制文件到镜像中。
  • CMD:供给容器默许履行的指令。Dockerfile 中只能有一个 CMD 指令。
  • ENTRYPOINT:装备容器发动时运转的指令,答应容器像运用程序相同运转。
  • EXPOSE:声明容器运转时监听的端口。
  • ENV:设置环境变量。
  • WORKDIR:设置作业目录,即容器内部的当时目录。
  • VOLUME:创立一个能够从本地主机或其他容器挂载的挂载点(或称为卷)。

运用 Dockerfile 构建镜像的指令是 docker build。这个进程包含读取 Dockerfile 的每一条指令,履行它们,终究创立一个可用的 Docker 镜像。

前端

在前端项目中运用 Docker 一般是为了保证共同的开发环境和简化布置流程。
Dockerfile 一般包含了构建前端项目所需的一切过程,包含装置依靠、构建静态文件以及运转服务。以下是一个典型的前端项意图 Dockerfile 示例:

# 运用多阶段构建,首要界说构建阶段
# 挑选一个带有Node.js的轻量级根底镜像
FROM node:16-alpine as build-stage
# 设置作业目录
WORKDIR /app
# 仿制package.json和package-lock.json(假如存在)
COPY package*.json ./
# 装置项目出产依靠
# 运用Docker缓存层,假如 package.json 没有变化,则不会从头装置node modules
RUN npm install --only=production
# 仿制项目文件到作业目录
COPY . .
# 构建运用
RUN npm run build
# 阶段2:运转
# 运用 Nginx 镜像作为根底来供给前端静态文件服务
FROM nginx:stable-alpine as production-stage
# 界说环境变量,例如NODE_ENV
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR /app
# 从构建阶段拷贝构建出的文件到Nginx目录
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 装备nginx,假如有自界说的nginx装备能够取消注释并修正下面的行
# COPY nginx.conf /etc/nginx/conf.d/default.conf
# 露出80端口
EXPOSE 80
# 发动Nginx服务器
CMD ["nginx", "-g", "daemon off;"]

这个 Dockerfile 包含了两个阶段:

  1. 构建阶段:这个阶段运用了一个带有 Node.js 的 Docker 镜像。在这个阶段中,首要设置了作业目录 /app,然后仿制了 package.json 和 package-lock.json 文件,并履行了 npm install 来装置依靠。接下来,仿制了一切项目文件,并履行了构建指令(例如 npm run build),这一般会生成一个 dist 文件夹,包含了一切静态文件。
  2. 运转阶段:这个阶段运用了一个轻量级的 Nginx 镜像来作为静态文件服务器。它从构建阶段仿制了 dist 文件夹的内容到 Nginx 的服务目录。终究,露出了端口 80,并设置了默许的发动指令来运转 Nginx。

当你运转这个 Docker 容器时,它会发动 Nginx 服务器并供给你的前端运用。
挑选官方、经过验证的根底镜像,以保证安全性和可维护性。运用尽或许精简的根底镜像,比如 alpine,减少终究镜像的大小。
在这个 Dockerfile 中,咱们运用了多阶段构建和运用 Docker 缓存层。这样做的优点是能够减小终究镜像的大小,由于构建阶段所需的依靠和工具在终究镜像中一般是不需求的。所以运用 Docker 的层次结构,将常常变化的指令放在 Dockerfile 的底部,这样能够充分运用缓存。
运用 ARG 和 ENV 来设置构建时和运转时的环境变量。这样能够在不修正 Dockerfile 的情况下从头构建镜像,更灵敏。运用 ARG 声明的 NODE_ENV 构建参数,运用 ${NODE_ENV} 来取。花括号可加可不加。
运用多阶段构建能够将编译和运转环境分隔,终究只将运转时有必要的文件打包进镜像。
依据你的项目实践情况,或许还需求调整构建指令、仿制的文件途径等。例如,假如你的构建指令不是 npm run build,就需求修正对应的 RUN 指令。假如你的静态文件输出目录不是 dist,也需求修正终究一个 COPY 指令中的途径。
此外,你或许还需求装备 Nginx,比如增加自界说的 nginx.conf 文件。这能够经过在第二个阶段增加一个 COPY 指令来完成,将你的装备文件仿制到容器中的 Nginx 装备目录下。
保证在 Dockerfile 所在的目录结构中有你的前端代码和一切必要的文件,然后你能够经过以下指令来构建和运转你的Docker容器

docker build -t my-frontend-app .
docker run -it -p 80:80 my-frontend-app

以上指令中 -t my-frontend-app 为构建出的镜像设置了一个标签,-p 80:80 将容器的 80 端口映射到宿主机的 80 端口。这样你就能够经过浏览器拜访宿主机的 80 端口来拜访你的前端运用了。
假如想要在服务器上运转,过程如下:
例如运转 Ubuntu 的云服务器,以及一个在 Docker Hub 上公开可用的前端运用容器。

  1. 登录到你的服务器:运用 SSH 衔接到你的服务器。
ssh [your-username]@[your-server-ip]

替换[your-username][your-server-ip]为你的服务器登录用户名和 IP 地址。

  1. 装置 Docker(假如没有装置,装置了的):运用服务器的包办理器装置 Docker。
sudo apt update
sudo apt install docker.io
  1. 发动 Docker 服务(假如没有运转):
sudo systemctl start docker

并保证 Docker 在每次发动时主动运转:

sudo systemctl enable docker
  1. 拉取 Docker 镜像:从 Docker Hub 或你的私有库房拉取你的前端运用镜像。
sudo docker pull myusername/my-frontend-app:tag
  1. 运转 Docker 容器:一旦镜像被拉取到服务器上,运用docker run指令来发动你的容器。
sudo docker run -d --name my-frontend-app-container -p 80:80 myusername/my-frontend-app:tag

这儿的-d选项意味着“detached”形式,即在后台运转容器。--name给容器分配一个称号,以便于后续办理。
尽量为构建的镜像运用有意义的标签,并遵循版别操控最佳实践。
-p 80:80是端口映射,将容器内的 80 端口映射到主机的 80 端口上,这样外界拜访服务器的 80 端口时,实践上是拜访到了容器中运转的前端运用。

  1. 验证容器运转状态:检查容器是否正在运转。
sudo docker ps

现在,假如一切设置正确,你应该能够经过服务器的IP地址或绑定的域名在浏览器中拜访你的前端运用了。
假如你需求检查运用的日志,能够运用:

sudo docker logs my-frontend-app-container

假如你需求停止容器,能够运用:

docker stop my-frontend-app-container

假如你需求从头发动容器,能够运用:

docker restart my-frontend-app-container

保证服务器的防火墙设置答应来自外部的 HTTP(端口80)和 HTTPS(端口 443,假如你运用 SSL)流量。
假如你需求装备 SSL 或设置一个更复杂的布置(如运用 Docker Compose,Kubernetes 等),这些过程会愈加复杂。
请注意,详细的指令或许会依据你的服务器装备、Docker 镜像设置以及你的需求有所不同。

后端 nest

在创立 Nest.js 项意图 Dockerfile 时,你需求考虑几个关键过程:装置依靠项、构建运用程序和运转运用程序。以下是一个简略的 Dockerfile 示例,它将帮助你将 Nest.js 运用程序容器化:

# Step 1: 运用带有Node.js的根底镜像
FROM node:16-alpine as builder
# 设置作业目录
WORKDIR /usr/src/app
# 仿制package.json和package-lock.json(假如可用)
COPY package*.json ./
# 装置项目依靠
RUN npm install --only=production
# 仿制一切文件到容器中
COPY . .
# 构建运用程序
RUN npm run build
# Step 2: 运转时运用更精简的根底镜像
FROM node:16-alpine
WORKDIR /usr/src/app
# 从builder阶段仿制构建好的文件
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/node_modules ./node_modules
# 露出3000端口
EXPOSE 3000
# 运转Nest.js运用程序
CMD ["node", "dist/main"]

这个 Dockerfile 分为两个过程:

  1. 构建过程(builder stage):运用 node:16-alpine 作为根底镜像,装置依靠,并构建 Nest.j s运用程序。这个阶段会生成构建好的运用程序代码。
  2. 运转时过程(runtime stage):再次运用 node:16-alpine 作为根底镜像,但这次只是仿制构建过程中生成的 dist 目录和 node_modules 目录到新的作业目录中。这样做的意图是坚持镜像尽或许的精简。由于构建过程中的依靠、源代码和其他不必要的文件在运转时阶段是不需求的。

终究,经过 EXPOSE 指令声明容器运转时需求露出的端口,然后经过 CMD 指令指定容器发动时运转的指令。
在你的实践项目中,你或许还需求设置环境变量、处理私有依靠库或者增加额外的装备文件。记得依据你项意图实践需求调整 Dockerfile。

gitlab 主动布置

下面是一个示例 .gitlab-ci.yml 文件,用于主动化构建和布置前端运用程序到 Docker 容器中:

stages:
  - build
  - deploy
build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t your-image-name .
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker push your-image-name
deploy:
  stage: deploy
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker pull your-image-name
    - docker run -d --name your-container-name -p 80:80 your-image-name
  only:
    - master

上述示例中的.gitlab-ci.yml文件界说了两个阶段(stage):build 和 deploy。
在 build 阶段,运用 Docker 构建你的镜像,并将其推送到你的 Docker 注册表(registry)。
在 deploy 阶段,从 Docker 注册表中拉取镜像,并在容器中运转运用程序。
only 关键字指定了只有在推送到 master 分支时才会履行布置作业。
请注意,上述示例中运用了 GitLab CI/CD 供给的 CI/CD 变量(CI_REGISTRY_USER、CI_REGISTRY_PASSWORD 和 CI_REGISTRY),这些变量需求在 GitLab 项意图设置中进行装备。
你需求依据你的详细情况修正上述示例中的镜像称号、容器称号和端口映射等参数,以适应你的项目需求。此外,你还能够依据需求在 script 部分增加其他指令或过程,例如运转测验、履行静态代码分析等。
完成后,将上述内容保存为 .gitlab-ci.yml 文件,并将其提交到你的 GitLab 代码库房中。GitLab 将依据装备的 .gitlab-ci.yml 文件主动履行构建和布置操作。

docker 的环境变量

Docker 容器中的环境变量是一个关键特性,用于办理容器内的装备。环境变量能够在容器运转时传递给容器内部的运用程序,然后答运用户调整容器行为而无需修正运用程序代码。
在 Docker 中,你能够经过几种不同的方式设置环境变量:

  1. 运用 Dockerfile

Dockerfile 中,能够运用 ENV 指令来设置环境变量。这些变量在构建镜像时被设置,并且在运转容器时坚持不变。

ENV MY_VARIABLE my_value
  1. 在指令行中运用 docker run 指令:

当运用 docker run 指令发动容器时,能够经过 -e--env 选项来传递环境变量。

docker run -e "MY_VARIABLE=my_value" my_image

假如你有多个环境变量需求设置,能够多次运用 -e 选项。

  1. 运用环境变量文件:

假如你有许多环境变量需求设置,能够运用文件来存储这些变量,然后在运用 docker run 指令时经过 --env-file 选项指定该文件。

docker run --env-file my_env_file.txt my_image

其间 my_env_file.txt 文件包含了环境变量的键值对,每行一个,如下所示:

MY_VARIABLE=my_value
ANOTHER_VARIABLE=another_value
  1. docker-compose.yml 文件中设置:

假如你运用的是 Docker Compose,能够在 docker-compose.yml 文件中的 environment 部分设置环境变量。

version: '3'
services:
  my_service:
    image: my_image
    environment:
      MY_VARIABLE: my_value

这些环境变量在容器发动时对容器内运转的运用程序可见,能够用于装备运用程序的行为,比如数据库衔接信息、外部服务的 API 密钥等。