🎨
Docker
  • Docker入门
  • Docker overview
    • 隔离与限制
    • copy-on-write(CoW: 写时复制)
    • docker中的联合文件系统
    • Docker存储
      • tmpfs mounts
      • volume
      • bind mounts
    • Docker网络
      • host模式
      • bridge模式
        • default bridge模式
        • User-defined bridge模式
      • none模式
      • container模式
  • 容器监控方式
    • prometheus + grafana+cAdvisor监控容器
  • Dockerfile指令
    • Usage
    • BuildKit
    • Format
    • Parser directives
      • syntax
      • escape
    • Environment replacement
    • FROM
      • 了解ARG和FROM之间的交互方式
    • .dockerignore file
    • RUN
    • CMD
    • COPY
    • ADD
    • ENV
    • WORKDIR
    • ARG
      • Impact on build caching(对构建缓存的影响)
      • Default(默认值)
      • Scope(作用域)
      • Using ARG Variables(使用ARG变量)
      • Predefined ARGS(预先定义好的ARG变量)
      • Automatic platform ARGs in the global scope(全局作用域中自动化平台的ARGS)
    • STOPSIGNAL
    • HEALTHCHECK
    • SHELL
    • ONBUILD
    • Dockerfile示例
    • LABEL
    • MAINTAINER (deprecated)
    • EXPOSE
    • ENTRYPOINT
      • Shell形式的ENTRYPOINT示例
      • 理解CMD和ENTRYPOINT是如何交互的
    • VOLUME
    • USER
  • docker-compose.yaml文件中常用指令
    • compose文件结构和示例
    • 服务配置参考
      • build
        • dockerfile
        • context
        • shm_size
        • network
        • labels
        • cache_from
        • args
        • target
      • cap_add, cap_drop
      • cgroup_parent
      • command
      • configs
        • 短语法形式
        • 长语法形式
      • container_name
      • credential_spec
        • EXAMPLE GMSA CONFIGURATION
      • depends_on
      • deploy
        • endpoint_mode
        • labels
        • mode
        • placement
        • max_replicas_per_node
        • replicas
        • resource
        • restart_policy
        • rollback_config
        • Update_config
        • Not supported for docker stack deploy
      • devices
      • dns
      • dns_search
      • entrypoint
      • env_file
      • environment
      • expose
      • external_links
      • extra_hosts
      • healthcheck
      • image
      • init
      • isolation
      • labels
      • links
      • logging
      • network_mode
      • networks
        • alias
        • IPV4_ADDRESS, IPV6_ADDRESS
      • pid
      • ports
        • 长语法
        • 短语法
      • profiles
      • restart
      • secrets
        • 长语法
        • 短语法
      • security_opt
      • stop_grace_period
      • stop_signal
      • sysctls
      • tmpfs
      • ulimits
      • userns_mode
      • volumes
        • 长语法
        • 短语法
        • VOLUMES FOR SERVICES, SWARMS, AND STACK FILES
      • domainname, hostname, ipc, mac_address, privileged, read_only, shm_size, stdin_open, tty, user, work
      • Specifying durations
      • Specifying byte values
      • Volume configuration reference
        • driver
        • driver_opts
        • external
        • labels
        • name
      • Network configuration reference
        • name
        • external
        • labels
        • internal
        • ipam
        • enable_ipv6
        • driver
          • overlay
          • bridge
          • host或者none
        • driver_opts
        • attachable
      • configs configuration reference
      • secrets configuration reference
      • Variable substitution
      • Extension fields
  • docker-compose示例
    • WordPress
    • PostgreSQL
    • Django和PostgreSQL
    • Rails和PostgreSQL
  • Dockerfile最佳实践
Powered by GitBook
On this page

Was this helpful?

  1. Dockerfile指令

RUN

RUN有2种形式:

  • RUN (shell形式,该命令在shell中运行,在Linux上默认为/bin/sh -c,在Windows上默认为cmd /S/C)

  • RUN ["executable", "param1", "param2"](exec 形式)

RUN指令在当前镜像顶部的新层(new layer)中执行任何命令,并提交结果。生成的提交的(committed)镜像将用于Dockerfile构建过程中的下一步。

分层运行RUN指令并生成提交(committed)符合Docker的核心概念,在Docker中,提交(committed)很廉价,并且可以从镜像历史记录的任何位置创建容器,特别像源代码控制。

exec形式可以避免破坏shell字符串,并使用不包含指定shell executable的基本镜像运行RUN命令。

可以使用SHELL命令更改shell形式的默认shell。

在shell形式中,可以使用\(反斜杠)将一条RUN指令继续到下一行。例如,考虑以下两行:

RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'

它们在一起等价于以下这一行:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'

要使用/bin/sh以外的其他shell,请使用exec形式传入所需的shell。例如:

RUN ["/bin/bash", "-c", "echo hello"]

NOTE:

exec形式的指令被解析为JSON数组,这意味着对于单词,我们必须使用双引号包围,而不是单引号。

与shell形式不同,exec形式不会调用命令行shell。这意味着正常的shell处理不会发生。例如,RUN ["echo","$HOME"]不会对$HOME进行变量替换。如果要进行shell处理,可以使用shell形式或直接执行shell,例如:RUN ["sh","-c","echo $HOME"]。当使用exec形式并直接执行shell时(例如在shell形式中),是由shell进行环境变量扩展,而不是docker。

Dockerfile:

# Dockerfile
ARG NAME="TonyYang"

FROM centos:7

ARG NAME

RUN /bin/echo Hello $NAME.

RUN ["echo", "Hello $NAME."]

RUN ["/bin/sh", "-c", "echo Hello $NAME."]

示例一:shell形式

Step 4/6 : RUN /bin/echo Hello $NAME.
 ---> Running in 3bca82f1ce9c
Hello TonyYang. # 执行了变量替换

示例二: exec形式

Step 5/6 : RUN ["echo", "Hello $NAME."]
 ---> Running in 956d8accc7b7
Hello $NAME. # 未执行变量替换

示例三:直接执行shell

Step 6/6 : RUN ["/bin/sh", "-c", "echo Hello $NAME."]
 ---> Running in 5839161cf465
Hello TonyYang. # 执行了变量替换

上面我直接将三种形式放在了一个Dockerfile中,便于比较。

NOTE:

在JSON形式中,必须转义反斜杠。这在Windows中特别有用,在Windows中反斜杠是路径分隔符。由于无效的JSON,以下几行将被视为shell形式,并以意外的方式执行失败:

RUN ["c:\windows\system32\tasklist.exe"]

正确的语法示例:

RUN ["c:\\windows\\system32\\tasklist.exe"]

在下一次构建中,RUN指令的缓存不会自动失效。诸如RUN apt-get dist-upgrade -y之类的指令的缓存将在下一次构建中重用。可以使用--no-cache使RUN指令的缓存无效,例如docker build --no-cache。

可以通过ADD和COPY指令使RUN指令的缓存无效。

Previous.dockerignore fileNextCMD

Last updated 4 years ago

Was this helpful?