Dockerfile 语法教程
文章目录
- Dockerfile 语法教程
- Dockerfile 语法教程
- 基础概念
- Dockerfile 简介
- 镜像、容器、仓库的概念
- Dockerfile 基本语法
- Dockerfile 基本语法
- Dockerfile 的基本结构
- 注释的使用
- 指令的格式
- 指令的执行顺序
- Dockerfile 常用指令
- FROM 指令
- RUN 指令
- CMD 指令
- ENTRYPOINT 指令
- ENV 指令
- ARG 指令
- 构建镜像
- 使用 Dockerfile 构建镜像
- .dockerignore 文件的使用
- 多阶段构建
- Dockerfile 最佳实践
- 1. 编写可复用的 Dockerfile
- 2. 避免使用 root 用户
- 3. 优化镜像大小
Dockerfile 语法教程
基础概念
Dockerfile 简介
Dockerfile 是一个文本文件,其内包含了一系列用户可以调用docker build命令自动构建 Docker 镜像的指令。每一条指令都会在镜像上创建一个新的层,因此每一条指令的内容,都会作为下一次创建新的层的基础。
镜像、容器、仓库的概念
-
镜像:Docker 镜像是一个只读的模板,包含了创建 Docker 容器(可以运行应用程序)和 Docker 镜像(可以运行容器)所需的所有内容。例如,一个镜像可能包含已安装的应用程序、系统工具、库和配置文件。
-
容器:Docker 容器是镜像的一个运行实例。您可以使用 Docker API 或 CLI 来创建、启动、停止、移动或删除容器。每个容器都是独立和安全的应用平台。
-
仓库:Docker 仓库是用来存储和管理 Docker 镜像的地方。您可以通过 Docker Hub 或其他公开的仓库来获取别人共享的镜像,也可以将自己的镜像推送到公开或私有的仓库中供他人使用。
Dockerfile 基本语法
Dockerfile 由一系列的指令组成,每一条指令对应一条命令。下面是一些常用的 Dockerfile 指令:
FROM
:指定基础镜像。RUN
:在镜像内部执行命令。CMD
:提供默认的命令,当容器启动时会自动执行。ENTRYPOINT
:配置容器启动时运行的命令,与 CMD 不同的是,使用 ENTRYPOINT 指定的命令不会被 shell 覆盖,而 CMD 指定的命令会被 shell 覆盖。ENV
:设置环境变量。ADD
/COPY
:将本地文件添加到镜像中。WORKDIR
:设置工作目录。EXPOSE
:声明运行时容器提供服务端口。VOLUME
:创建一个可以从宿主主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据。
Dockerfile 基本语法
Dockerfile 的基本结构
Dockerfile 是一个文本文件,其内包含了一系列用户可以调用 docker 命令自动构建镜像的指令。一个基础的 Dockerfile 文件通常包括:一个基础镜像信息、维护者信息、镜像操作指令等。
# 基础镜像信息
FROM ubuntu:18.04
# 维护者信息
MAINTAINER Your Name <your.email@example.com>
# 镜像操作指令
RUN apt-get update && apt-get install -y python3
注释的使用
在 Dockerfile 中,可以使用 #
来添加注释。单行注释以 #
开头,直到该行的结束。多行注释使用 /*
和 */
包围起来。
# 这是一个单行注释
RUN echo "Hello, World!" > /tmp/hello.txt # 这是一行注释内容/*
这是一个多行注释
可以跨越多行
*/
指令的格式
Dockerfile 的每一行都是一个指令,格式为 instruction argument
。例如,RUN
指令用于执行命令,CMD
指令用于指定容器启动时要运行的命令。
RUN apt-get update && apt-get install -y python3 # 更新并安装 Python3
CMD ["python3", "app.py"] # 运行 app.py 脚本
指令的执行顺序
Dockerfile 中的指令按照从上到下的顺序执行。用户可以通过 docker build
命令来构建镜像,这个过程中,Docker会按照 Dockerfile 中指令的顺序来执行。
Dockerfile 常用指令
Dockerfile 是用于构建 Docker 镜像的文本文件,它包含了一系列的指令和参数。以下是一些常用的 Dockerfile 指令:
FROM 指令
FROM
指令用于指定基础镜像。例如,如果我们想要基于 ubuntu:18.04
镜像来构建我们的应用,我们可以这样写:
FROM ubuntu:18.04
RUN 指令
RUN
指令用于在镜像中执行命令。例如,我们可以使用 RUN
指令来安装一些必要的软件包:
RUN apt-get update && apt-get install -y curl
CMD 指令
CMD
指令用于指定容器启动时默认执行的命令。例如,我们可以使用 CMD
指令来启动一个 web 服务器:
CMD ["service", "nginx", "start"]
ENTRYPOINT 指令
ENTRYPOINT
指令用于指定容器启动时的入口点。与 CMD
不同的是,ENTRYPOINT
指定的命令不会被 docker run
命令后面的参数所覆盖。例如,我们可以使用 ENTRYPOINT
指令来启动一个 web 服务器:
ENTRYPOINT ["service", "nginx", "start"]
ENV 指令
ENV
指令用于设置环境变量。例如,我们可以使用 ENV
指令来设置数据库连接字符串:
ENV DB_CONNECTION_STRING="server=db;user id=myuser;password=mypassword;database=mydb"
ARG 指令
ARG
指令用于定义可以在构建过程中使用的变量。例如,我们可以使用 ARG
指令来定义版本号:
ARG VERSION=1.0.0
构建镜像
使用 Dockerfile 构建镜像
Dockerfile 是一个文本文件,其包含了一系列用户可以调用 docker build 命令自动执行的命令。以下是一个基本的 Dockerfile 示例:
# 使用官方 Python 运行时作为父镜像
FROM python:3.7-slim# 设置工作目录
WORKDIR /app# 将当前目录内容复制到容器的 /app 目录
ADD . /app# 使用 pip 安装任何需要的包
RUN pip install --no-cache-dir -r requirements.txt# 使端口 80 可用于此应用程序
EXPOSE 80# 定义环境变量
ENV NAME World# 在容器启动时运行 app.py
CMD ["python", "app.py"]
.dockerignore 文件的使用
.dockerignore
文件用于排除不需要的文件和目录。以下是一个 .dockerignore
文件的示例:
# 忽略所有 .pyc 文件和文件夹
*.pyc
__pycache__/# 忽略所有 .log 文件和文件夹
*.log
logs/
多阶段构建
多阶段构建允许你将构建过程分为多个阶段,每个阶段都有自己的输出。以下是一个多阶段构建的示例:
# 第一阶段:获取依赖项并编译源代码
FROM node:14 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build# 第二阶段:使用 Nginx 运行应用
FROM nginx:1.19-alpine as production
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Dockerfile 最佳实践
在编写 Dockerfile 时,遵循一些最佳实践可以帮助我们编写出更高效、可复用和安全的镜像。本教程将介绍以下三个最佳实践:编写可复用的 Dockerfile、避免使用 root 用户和优化镜像大小。
1. 编写可复用的 Dockerfile
为了提高开发效率,我们可以编写一个通用的 Dockerfile,然后在需要的时候继承它。这样可以避免重复编写相同的基础设置。例如,我们可以创建一个名为 base
的 Dockerfile,包含所有通用设置,然后在其他 Dockerfile 中通过 FROM base
指令继承它。
# base Dockerfile
FROM alpine:latest
RUN apk update && apk add --no-cache git
WORKDIR /app
在其他 Dockerfile 中,我们可以这样继承 base
Dockerfile:
# app Dockerfile
FROM base
COPY . /app
RUN make build
CMD ["./app"]
2. 避免使用 root 用户
在容器中以 root 用户身份运行进程可能会导致安全风险。因此,建议在容器中以非 root 用户身份运行进程。可以通过以下方式实现:
- 在 Dockerfile 中使用
USER
指令切换到非 root 用户。 - 确保应用程序在运行时以非 root 用户身份运行。
例如,我们可以在 base
Dockerfile 中添加以下内容:
USER nobody
然后,在需要使用非 root 用户的应用程序的 Dockerfile 中,确保应用程序以非 root 用户身份运行。例如:
# app Dockerfile
FROM base
COPY . /app
RUN chown -R nobody:nobody /app && make build
USER nobody
CMD ["./app"]
3. 优化镜像大小
为了减少镜像的大小,我们可以采取以下措施:
- 使用多阶段构建。多阶段构建可以将多个构建阶段合并到一个镜像中,从而减少层数和大小。例如:
# multi-stage build example
FROM node:14 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run buildFROM alpine:latest as production
WORKDIR /app
COPY --from=builder /app/build ./build
CMD ["./build"]
- 清理不必要的文件。在构建过程中,可能会生成一些临时文件或缓存文件。可以使用
RUN
指令删除这些文件,以减小镜像大小。例如:
# remove unnecessary files example
RUN apk del gcc musl-dev && rm -rf /var/cache/apk/* && adduser -D user && mkdir -p /home/user/app && chown -R user:user /home/user/app && mv /app/* /home/user/app/ && rm -rf /app/* && chown -R user:user /home/user/app && mv /home/user/app/* /app/ && rm -rf /home/user/app/* && rm -rf /var/cache/apk/* && rm -rf /tmp/* && apk update && apk add --no-cache libc6-compat && apk add --no-cache libstdc++6 && apk add --no-cache zlib && apk add --no-cache libgcc-s.so.1 && apk add --no-cache libssl1.1 && apk add --no-cache libffi-dev && apk add --no-cache openssl-dev && apk add --no-cache python3 && apk add --no-cache py3-pip && pip3 install --upgrade pip setuptools wheel && pip3 install uwsgi==2.0.19 && pip3 install psutil==5.7.0 && pip3 install requests==2.25.1 && pip3 install httpie==1.0.3 && pip3 install boto3==1.16.48 && pip3 install botocore==1.19.48 && pip3 install cryptography==3.4.7 && pip3 install grpcio==1.34.0 && pip3 install google-api-python-client==1.7.12 && pip3 install google-auth==1.23.0 && pip3 install google-auth-httplib2==0.0.4 && pip3 install google-cloud-core==1.4.1 && pip3 install google-resumable-media==0.5.2 && pip3 install idna==2.10 && pip3 install PyNaCl==1.4.0 && pip3 install six==1.15.0 && pip3 install twilio==6.64.0 && pip3 install validate-email==2020.10.26 && rm -rf /var/cache/apk/* && apk del gcc musl-dev python3 py3-pip build-base && adduser -D user && mkdir -p /home/user/app && chown -R user:user /home/user/app && mv /app/* /home/user/app/ && rm -rf /app/* && chown -R user:user /home/user/app && mv /home/user/app/* /app/ && rm -rf /home/user/app/* && apk update && apk add --no-cache libc6-compat libstdc++6 zlib libgcc-s.so.1 libssl1.1 libffi-dev openssl-dev python3 py3-pip build-base uwsgi==2.0.19 psutil==5.7.0 requests==2.25.1 httpie==1.0.3 boto3==1.16.48 botocore==1.19.48 cryptography==3.4.7 grpcio==1.34.0 google-api-python-client==1.7.12 google-auth==1.23.0 google-auth-httplib2==0.0