コンテナをアクティブに保ち、分離したままにしてstdoutをホストするために、ENTRYPOINT / CMDでエコープロセスを開始しましたか?

コンテナをアクティブに保ち、分離したままにしてstdoutをホストするために、ENTRYPOINT / CMDでエコープロセスを開始しましたか?

dockerを使用してコンテナに接続せずに、jupyterノートブックのログイントークンをホストコンピュータからしっかり印刷しようとしています。このコンテナは、ホストシステムのブラウザでノートブックを実行するためにのみ使用されます。

(追加)インタラクティブモードと擬似端末を使用するdocker run -itと、バックグラウンドでjupyterを起動してトークンを印刷できます。 DockerfileはjupyterをCMD使用または実行し、screen -S session_name -dm jupyter notebook...トークンが返されると& disownbashループを実行します。しかし、これがその中の最後の項目なので、コンテナを終了します。echojupyter server listDockerfile CMD

たとえば、実行で終わるコンテナを引き続き使用できるようにするにはbash。これはコンテナを実行し続けますが、-itホストシェルもコンテナに接続されているためです。

だから分離-dモード、すなわちdocker run -itd。ちなみにホストスタウトでトークンを見ることはできません。そのためには走らなければなりません。docker logs container-name-hereこれは一般的な慣行です。おそらくこれが私が考える最も簡単な解決策でしょう。しかし、可能であれば避けたい!

2つの代替アドインを使用して削除しようとしました-it

まず、拒否されたプロセスに接続し、フラグを追加してdocker runから--privileged --cap-add=SYS_PTRACEdockerfileに追加して、次のようにコンテナを終了します。

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]

次に、dockerfileの前に.をscript /dev/null追加すると、トークンは正常に印刷されますが、コンテナは終了します(最後のCMD)。最後に返品を追加screenscript /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

関連情報