将多个参数传递给 Dockerfile 中的 ENTRYPOINT

Pass multiple arguments to ENTRYPOINT in Dockerfile

这是我的 Dockerfile 中定义的入口点:

ENTRYPOINT ["/bin/bash", "-c" , "useradd -r user_test -u 2001 -g 100 && chown -R 2001:100 /home/user_test && su - user_test && mkdir -p /home/user_test/external_user_id"]

我需要将其参数化如下:

ENTRYPOINT ["/bin/bash", "-c" , "useradd -r user_test -u <user_id> -g 100 && chown -R <user_id>:100 /home/user_test && su - user_test && mkdir -p /home/user_test/<external_user_id>"]

其中 user_idexternal_user_id 通过 DockerSpawner 配置设置:

c.DockerSpawner.extra_host_config = {"user_id": "2001", "external_user_id": "id_1234567890"}

如何编辑 Dockerfile 中的 ENTRYPOINT?

谢谢

我建议在这里更改的第一件事是将其拆分为一个单独的脚本。像这样在单个命令中很难阅读和更新大量内联编写的代码。相反,根据脚本的作用,它可以更容易编辑,如果您需要进行这样的更改,甚至可以 运行 在 Docker 之外进行编辑。

COPY entrypoint.sh . # should be executable on the host

# For this standard use, ENTRYPOINT _must_ be JSON-array form.
# Do not use an explicit "bash" invocation generally.
ENTRYPOINT ["./entrypoint.sh"]

# Specify the actual command to run
CMD ???

当脚本 运行s,it gets passed the CMD as additional arguments,所以你可以在这里使用你喜欢的任何配置机制。如果有点异常,调用 getopt(1) 是可能的;使用环境变量进行这样的简单配置更为常见。

#!/bin/sh
# Do the setup things from the original ENTRYPOINT line:

# Create the user, using the uid from the environment variable, or
# the default from the first line
useradd -r user_test -u "${USER_ID:-2001}" -g 100

# Change directory ownership, using the newly created user name
chown -R user_test:100 /home/user_test

# Do nothing, but proceed to the next line continuing to run as root
su - user_test

# Create another directory
mkdir -p "/home/user_test/${EXTERNAL_USER_ID:-external_user_id}"

# Run the main container CMD
exec "$@"

启动容器时还需要​​传入环境变量:

c.DockerSpawner.extra_host_config = {"user_id": "2001", "external_user_id": "id_1234567890"}
c.DockerSpawner.environment = {"USER_ID": "2001", "EXTERNAL_USER_ID": "id_1234567890"}

我在这里实际要做的是删除所有这些代码。传递那个 user_id 设置应该会导致 Docker 到 运行 与那个数字用户 ID。用户“存在”并不特别需要;在大多数情况下,如果用户 2001 未在容器的 /etc/passwd 文件中列出,则不会发生任何问题。当您按原样尝试 运行 时,您可能还会发现权限问题,因为在入口点脚本启动时您已经不是 root 用户 运行ning.

如果您像此处那样配置用户 ID,并使用适当的权限将主机目录绑定挂载到容器中,则容器无需任何特殊设置即可读取和写入该目录。从上下文来看,我猜你希望目录是从主机绑定挂载的(否则特定的 uid 根本不重要),在这种情况下你可以提前创建输出目录。

在简单的 docker run 语法中,我会写:

docker run \
  --rm                            \ # clean up container when done
  -u $(id -u)                     \ # with the current host uid
  -v "$PWD/id_1234567890:/result" \ # mounting the result directory
  -w /result                      \ # working in that directory
  image-name:tag

如果您查看容器环境(尝试将 idls -l 附加到该 docker run 命令以查看其中的一些详细信息),您会发现您 运行ning 作为主机用户 ID,您应该 read/write 可以访问结果目录,而无需在容器启动时进行设置。