跳至主要内容

GitHub Actions 的 Dockerfile 支持

在为 Docker 容器操作创建 Dockerfile 时,您应该了解某些 Docker 指令如何与 GitHub Actions 和操作的元数据文件交互。

关于 Dockerfile 指令

一个Dockerfile包含定义 Docker 容器内容和启动行为的指令和参数。有关 Docker 支持的指令的更多信息,请参阅 Docker 文档中的“Dockerfile 参考”。

Dockerfile 指令和覆盖

某些 Docker 指令与 GitHub Actions 交互,并且操作的元数据文件可以覆盖某些 Docker 指令。请确保您熟悉 Dockerfile 如何与 GitHub Actions 交互,以防止出现任何意外行为。

USER

Docker 操作必须由默认的 Docker 用户(root)运行。请勿在您的Dockerfile中使用USER指令,因为您将无法访问GITHUB_WORKSPACE目录。有关更多信息,请参阅“在变量中存储信息”和 Docker 文档中的USER 参考

FROM

Dockerfile中的第一条指令必须是FROM,它选择一个 Docker 基础镜像。有关更多信息,请参阅 Docker 文档中的FROM 参考

以下是设置FROM参数的一些最佳实践

  • 建议使用官方 Docker 镜像。例如,pythonruby
  • 如果存在版本标签,请使用它,最好使用主要版本。例如,使用node:10而不是node:latest
  • 建议使用基于Debian操作系统的 Docker 镜像。

WORKDIR

GitHub 在GITHUB_WORKSPACE环境变量中设置工作目录路径。建议不要在您的Dockerfile中使用WORKDIR指令。在操作执行之前,GitHub 会将GITHUB_WORKSPACE目录挂载到 Docker 镜像中该位置的任何内容之上,并将GITHUB_WORKSPACE设置为工作目录。有关更多信息,请参阅“在变量中存储信息”和 Docker 文档中的WORKDIR 参考

ENTRYPOINT

如果您在操作的元数据文件中定义了entrypoint,它将覆盖Dockerfile中定义的ENTRYPOINT。有关更多信息,请参阅“GitHub Actions 的元数据语法”。

Docker ENTRYPOINT指令具有shell形式和exec形式。Docker ENTRYPOINT文档建议使用ENTRYPOINT指令的exec形式。有关execshell形式的更多信息,请参阅 Docker 文档中的ENTRYPOINT 参考

您不应使用WORKDIR在您的 Dockerfile 中指定您的入口点。相反,您应该使用绝对路径。有关更多信息,请参阅WORKDIR

如果您将容器配置为使用ENTRYPOINT指令的exec形式,则操作的元数据文件中配置的args不会在命令 shell 中运行。如果操作的args包含环境变量,则不会替换该变量。例如,使用以下exec格式将不会打印存储在$GITHUB_SHA中的值,而是打印"$GITHUB_SHA"

ENTRYPOINT ["echo $GITHUB_SHA"]

如果您想要变量替换,则可以使用shell形式或直接执行 shell。例如,使用以下exec格式,您可以执行一个 shell 来打印存储在GITHUB_SHA环境变量中的值。

ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"]

要将操作元数据文件中定义的args提供给使用ENTRYPOINT中的exec形式的 Docker 容器,我们建议创建一个名为entrypoint.sh的 shell 脚本,您可以在ENTRYPOINT指令中调用它。

示例Dockerfile

# Container image that runs your code
FROM debian:9.5-slim

# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh

# Executes `entrypoint.sh` when the Docker container starts up
ENTRYPOINT ["/entrypoint.sh"]

示例entrypoint.sh文件

使用上面的示例 Dockerfile,GitHub 会将操作元数据文件中配置的args作为参数发送到entrypoint.sh。在entrypoint.sh文件的顶部添加#!/bin/shShebang以显式使用系统的POSIX兼容 shell。

#!/bin/sh

# `$#` expands to the number of arguments and `$@` expands to the supplied `args`
printf '%d args:' "$#"
printf " '%s'" "$@"
printf '\n'

您的代码必须是可执行的。在工作流中使用它之前,请确保entrypoint.sh文件具有execute权限。您可以使用此命令从终端修改权限

chmod +x entrypoint.sh

ENTRYPOINT shell 脚本不可执行时,您将收到类似于此的错误

Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/entrypoint.sh\": permission denied": unknown

CMD

如果您在操作的元数据文件中定义了args,则args将覆盖Dockerfile中指定的CMD指令。有关更多信息,请参阅“GitHub Actions 的元数据语法”。

如果您在Dockerfile中使用CMD,请遵循以下准则

  1. 在操作的 README 中记录所需的 arguments,并将其从CMD指令中省略。
  2. 使用允许在不指定任何args的情况下使用操作的默认值。
  3. 如果操作公开了--help标志或类似内容,请使用它使您的操作具有自文档功能。

支持的 Linux 功能

GitHub Actions 支持 Docker 支持的默认 Linux 功能。无法添加或删除功能。有关 Docker 支持的默认 Linux 功能的更多信息,请参阅 Docker 文档中的“Linux 内核功能”。要了解有关 Linux 功能的更多信息,请参阅 Linux 手册页中的“Linux 功能概述”。