我制作了一个安装了 ssh-server 的 Dockerfile,最初遇到了一个问题,即在启动服务的命令后它立即退出。我找到了一种解决方法,但我不明白保持它打开的部分到底在做什么。
以下是 Dockerfile:
#To make an image from this: docker build -t [image name] .
#On host, ufw allow [some other port than 22]
#Run container: docker run --rm [image_name] -p [other port from above]:22
FROM ubuntu:latest
#add a user
RUN useradd -s /bin/bash [some username]
#give her sudo privileges
RUN adduser [some username] sudo
RUN echo [some username]:[some password] | chpasswd
#install openssh server
RUN apt-get update && apt-get install -y openssh-server
#create needed directory for ssh-server
RUN mkdir -p /var/run/sshd
#start ssh server
CMD exec "$@" && /usr/sbin/ssh -D
# Expose the SSH port
EXPOSE 22
我的问题与 CMD 语句有关,特别是“exec "$@"”。为什么它能让容器保持运行?当它为服务器命令行提供接口时,它到底在做什么,而 ssh 服务器却没有做?
更多信息(不确定这是否相关,但对于那些好奇的人来说,Docker 主机正在运行 Ubuntu 18.04.10 LTS,Docker 是 Docker-ce)
谢谢!
答案1
让我们详细分析一下:
- 您正在使用 Dockerfile
- 您正在使用 CMD 指令
- 首先,让我们阅读https://docs.docker.com/engine/reference/builder/#cmd
- 查看 CMD 的使用格式,docker 将其称为“shell”形式
- “如果您使用 CMD 的 shell 形式,那么将在 /bin/sh -c 中执行”- 它告诉您所提供的任何内容都将由 /bin/sh 2.4 解释。在 linux 中,阅读 sh: 的手册页
$ man sh
并搜索 exec 您会发现:
exec [command arg ...] Unless command is omitted, the shell process is replaced with the specified program (which must be a real program, not a shell
内置或函数)。 exec 命令上的任何重定向均被标记为永久的,这样当 exec 命令完成时,它们不会被撤消。
这里不清楚的是这会如何影响容器。为了帮助解决这个问题,请参阅此问题的答案:https://stackoverflow.com/q/32255814/831750
- 由于您已向 exec 提供了一个参数,例如“$@”,它将被 exec 解释为“命令”部分。那么“$@”是什么
- 简单谷歌搜索“$@”,可能会得到如下结果https://stackoverflow.com/questions/9994295/what-does-mean-in-a-shell-script/9995322其中解释说
$@ 是传递给脚本的所有参数
- 或者从手册页中标题为“特殊参数”的部分下,其中包含 @ 的小节
@ Expands to the positional parameters, starting from one. When the expansion occurs within double-quotes, each positional parameter expands as a separate argument. If there are no positional parameters, the expansion of @ generates zero arguments, even when @ is double-quoted. What this basically means, for example, is if $1 is “abc” and $2 is “def ghi”, then "$@" expands to the two arguments: "abc" "def ghi"
我希望这不仅能给你一个“$@”问题的答案,还能在某种程度上告诉你如何自己分析这样的问题。玩得开心 :-D