echo 进程在 ENTRYPOINT/CMD 中启动以托管标准输出,同时保持容器处于活动状态并分离?

echo 进程在 ENTRYPOINT/CMD 中启动以托管标准输出,同时保持容器处于活动状态并分离?

使用 docker,我尝试打印 jupyter 笔记本的登录令牌,以在我的主机上坚固,而不附加到容器。该容器仅用于在主机上的浏览器中运行笔记本。

通过(附加的)交互模式和伪终端docker run -it,我可以在后台启动 jupyter 并打印令牌。 DockerfileCMD使用screen -S session_name -dm jupyter notebook...或运行 jupyter,然后在返回令牌时& disown执行 bash 循环。但是,因为这是其中的最后一个项目,所以它会终止容器。echojupyter server listDockerfile CMD

为了能够继续我玩过的容器,以运行结束,例如bash。这让容器继续运行,但因为-it主机 shell 也附加到它。

因此,我添加了分离-d模式 ie docker run -itd。但后来我在主机 stout 上看不到令牌了。为此我需要去跑步docker logs container-name-here这是常见的做法。也许这是我认为最简单的解决方案。但如果可能的话我想避免它!

我尝试过-it用两种替代添加来删除。

首先,尝试附加到被拒绝的进程,添加标志docker run--privileged --cap-add=SYS_PTRACE添加到 dockerfile,如下所示终止容器

echo 0 > /proc/sys/kernel/yama/ptrace_scope`
gdb -p PID

...
Quit anyway? (y or n) [answered Y; input not from terminal]
Detaching from program: /usr/local/bin/python3.12, process 8
[Inferior 1 (process 8) detached]

其次,通过在 dockerfilescript /dev/null之前添加screen.令牌已成功打印,但容器终止(是最后一个 CMD)。script /dev/null; screen -r session_name最后添加返回

Script started, output log file is '/dev/null'.
# 
Script done.
Must be connected to a terminal.

有解决方法的想法吗?

答案1

正如评论中所述,这并不是我要求的解决方案,但由于没有更好的选择,我选择的解决方案是:

#!/bin/bash

# docker build+run -d or compose up -d ...

dock_jcontainer="$(docker container ls | awk '{if(NR>1) print $NF}' | grep py)" # I looked for a python container

while true; do
    if docker logs $dock_jcontainer 2>&1 | grep -q "To access the server"; then # Jupyter Notebook log outputs this string
        dock_jlogs=$(docker logs $dock_jcontainer 2>&1)
        break
    fi
done

...

您可能不想docker logs $dock_jcontainer 2>&1通过将其转换为 $()​​ 或 {} 来重复。

答案2

尝试这个:

#!/bin/bash

# Container name
dock_jcontainer="$(docker container ls | awk '{if(NR>1) print $NF}' | grep py)"

# Blocking wait until log's grep result is not empty, runs every 2 seconds.
while [ -z "$(docker logs "${dock_jcontainer}" 2>&1 | grep -q 'To access the server')" ]; do
    sleep 2;
done;

# Prints the line you are looking for
printf "$(docker logs "${dock_jcontainer}" 2>&1 | grep -q 'To access the server')\n"

# Functionalize it if you'd like
function grepLogs() {
    docker logs "${dock_jcontainer}" 2>&1 | grep -q 'To access the server'
}; export -f grepLogs

相关内容