Dockerfile 语法教程

Dockerfile 语法教程

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 用户身份运行进程。可以通过以下方式实现:

  1. 在 Dockerfile 中使用 USER 指令切换到非 root 用户。
  2. 确保应用程序在运行时以非 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. 优化镜像大小

为了减少镜像的大小,我们可以采取以下措施:

  1. 使用多阶段构建。多阶段构建可以将多个构建阶段合并到一个镜像中,从而减少层数和大小。例如:
# multi-stage build example
FROM node:14 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM alpine:latest as production
WORKDIR /app
COPY --from=builder /app/build ./build
CMD ["./build"]
  1. 清理不必要的文件。在构建过程中,可能会生成一些临时文件或缓存文件。可以使用 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
  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早上真好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值