• 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 
    # 镜像操作指令
    RUN apt-get update && apt-get install -y python3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注释的使用

    在 Dockerfile 中,可以使用 # 来添加注释。单行注释以 # 开头,直到该行的结束。多行注释使用 /**/ 包围起来。

    # 这是一个单行注释
    RUN echo "Hello, World!" > /tmp/hello.txt # 这是一行注释内容
    
    /*
    这是一个多行注释
    可以跨越多行
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    指令的格式

    Dockerfile 的每一行都是一个指令,格式为 instruction argument。例如,RUN 指令用于执行命令,CMD 指令用于指定容器启动时要运行的命令。

    RUN apt-get update && apt-get install -y python3 # 更新并安装 Python3
    CMD ["python3", "app.py"] # 运行 app.py 脚本
    
    • 1
    • 2

    指令的执行顺序

    Dockerfile 中的指令按照从上到下的顺序执行。用户可以通过 docker build 命令来构建镜像,这个过程中,Docker会按照 Dockerfile 中指令的顺序来执行。

    Dockerfile 常用指令

    Dockerfile 是用于构建 Docker 镜像的文本文件,它包含了一系列的指令和参数。以下是一些常用的 Dockerfile 指令:

    FROM 指令

    FROM 指令用于指定基础镜像。例如,如果我们想要基于 ubuntu:18.04 镜像来构建我们的应用,我们可以这样写:

    FROM ubuntu:18.04
    
    • 1

    RUN 指令

    RUN 指令用于在镜像中执行命令。例如,我们可以使用 RUN 指令来安装一些必要的软件包:

    RUN apt-get update && apt-get install -y curl
    
    • 1

    CMD 指令

    CMD 指令用于指定容器启动时默认执行的命令。例如,我们可以使用 CMD 指令来启动一个 web 服务器:

    CMD ["service", "nginx", "start"]
    
    • 1

    ENTRYPOINT 指令

    ENTRYPOINT 指令用于指定容器启动时的入口点。与 CMD 不同的是,ENTRYPOINT 指定的命令不会被 docker run 命令后面的参数所覆盖。例如,我们可以使用 ENTRYPOINT 指令来启动一个 web 服务器:

    ENTRYPOINT ["service", "nginx", "start"]
    
    • 1

    ENV 指令

    ENV 指令用于设置环境变量。例如,我们可以使用 ENV 指令来设置数据库连接字符串:

    ENV DB_CONNECTION_STRING="server=db;user id=myuser;password=mypassword;database=mydb"
    
    • 1

    ARG 指令

    ARG 指令用于定义可以在构建过程中使用的变量。例如,我们可以使用 ARG 指令来定义版本号:

    ARG VERSION=1.0.0
    
    • 1

    构建镜像

    使用 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"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    .dockerignore 文件的使用

    .dockerignore 文件用于排除不需要的文件和目录。以下是一个 .dockerignore 文件的示例:

    # 忽略所有 .pyc 文件和文件夹
    *.pyc
    __pycache__/
    
    # 忽略所有 .log 文件和文件夹
    *.log
    logs/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    多阶段构建

    多阶段构建允许你将构建过程分为多个阶段,每个阶段都有自己的输出。以下是一个多阶段构建的示例:

    # 第一阶段:获取依赖项并编译源代码
    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;"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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
    
    • 1
    • 2
    • 3
    • 4

    在其他 Dockerfile 中,我们可以这样继承 base Dockerfile:

    # app Dockerfile
    FROM base
    COPY . /app
    RUN make build
    CMD ["./app"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 避免使用 root 用户

    在容器中以 root 用户身份运行进程可能会导致安全风险。因此,建议在容器中以非 root 用户身份运行进程。可以通过以下方式实现:

    1. 在 Dockerfile 中使用 USER 指令切换到非 root 用户。
    2. 确保应用程序在运行时以非 root 用户身份运行。

    例如,我们可以在 base Dockerfile 中添加以下内容:

    USER nobody
    
    • 1

    然后,在需要使用非 root 用户的应用程序的 Dockerfile 中,确保应用程序以非 root 用户身份运行。例如:

    # app Dockerfile
    FROM base
    COPY . /app
    RUN chown -R nobody:nobody /app && make build
    USER nobody
    CMD ["./app"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    封装自己的本地缓存类(单例模式、适配器模式应用)
    MATLAB平台学习(13)一些感悟
    个人课设---玩家血条(包括攻击掉血,复活重生功能)
    农业温室智能监控系统方案,实现农业自动化的最后一步
    Docker-compose安装mysql
    [分类讨论]Bit Transmission 2022牛客多校第5场 C
    Python - Word转TXT文本,或TXT文本转Word
    小黑leetcode之旅:86. 分隔链表
    HTML+CSS+JS大作业:生态环境网站设计——环境保护主题
    深度学习实战01-卷积神经网络(CNN)实现Mnist手写体识别
  • 原文地址:https://blog.csdn.net/raw_inputhello/article/details/136291530