![echo 进程在 ENTRYPOINT/CMD 中启动以托管标准输出,同时保持容器处于活动状态并分离?](https://linux22.com/image/230255/echo%20%E8%BF%9B%E7%A8%8B%E5%9C%A8%20ENTRYPOINT%2FCMD%20%E4%B8%AD%E5%90%AF%E5%8A%A8%E4%BB%A5%E6%89%98%E7%AE%A1%E6%A0%87%E5%87%86%E8%BE%93%E5%87%BA%EF%BC%8C%E5%90%8C%E6%97%B6%E4%BF%9D%E6%8C%81%E5%AE%B9%E5%99%A8%E5%A4%84%E4%BA%8E%E6%B4%BB%E5%8A%A8%E7%8A%B6%E6%80%81%E5%B9%B6%E5%88%86%E7%A6%BB%EF%BC%9F.png)
使用 docker,我尝试打印 jupyter 笔记本的登录令牌,以在我的主机上坚固,而不附加到容器。该容器仅用于在主机上的浏览器中运行笔记本。
通过(附加的)交互模式和伪终端docker run -it
,我可以在后台启动 jupyter 并打印令牌。 DockerfileCMD
使用screen -S session_name -dm jupyter notebook...
或运行 jupyter,然后在返回令牌时& disown
执行 bash 循环。但是,因为这是其中的最后一个项目,所以它会终止容器。echo
jupyter server list
Dockerfile
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