dockerで環境変更を行っていると、コンテナのトラブル発生時に再起動やログ解析を行う機会も多くなると思います。
以下にdockerでコンテナを管理する際によく使用するコマンドやshスクリプトを紹介しておきます。
ご活用ください。
※自サーバ環境のファイル置き場や、コンテナ名などが異なる場合は読み替えてください。
私は以下環境で利用しています。
1)プロジェクト(各コンテナyamlファイル置き場)⇒ ~/projects 配下
2)docker永続化ファイル(volumes)⇒/docker_data 配下
プロジェクトへ移動
各コンテナyamlファイルの置き場
cd ~/projects;ls -l
# vllmの場合
cd ~/projects/vllm
# ollama OpenWebuiの場合
cd ~/projects/ollama_openwebui
# difyの場合
cd ~/projects/dify
環境ファイル編集(yaml)
cp -ax docker-compose.yaml docker-compose.yaml_$(date +%Y%m%d)
vi docker-compose.yaml
docker永続化ファイル(volumes)
コンテナ使用データエリアへ移動
cd /docker_data;ls -l
cd /docker_data/ollama
起動&停止
yaml環境ファイルがあるdirに移動してから実行してください。
停止(コンテナは残す)
docker compose stop
起動
docker compose up -d
再起動(設定反映・一時不調復旧)
docker restart
削除(破棄・作り直し)
docker compose down
強制停止(ハング時の即停止)
docker kill
イメージ更新→再作成(環境変更時)
- docker compose pull
Composeファイル(docker-compose.yml)に定義された各サービスのイメージを“事前に取得(pull)する” コマンドです。コンテナは起動しません。 - docker compose up -d --force-recreate
差分がなくても必ずコンテナを再作成します。
docker compose pull && docker compose up -d --force-recreate
起動確認
# 起動中コンテナ一覧
docker ps
# 起動中+起動はしていなが存在するコンテナ一覧
docker ps -a
## コンテナ名と使用ポートのみ表示
docker ps --format 'table {{.Names}}\t{{.Ports}}'
公開されているホストポートの確認
ホスト側で待ち受けているポート番号"だけ”に絞る(数値だけ欲しい場合)
docker ps --format '{{.Ports}}' \
| awk -F', ' '{
for(i=1;i<=NF;i++){
if($i ~ /->/){
split($i,a,"->");
gsub(/.*:/,"",a[1]); # 最後の ":" より後ろ(ポート)を残す
gsub(/\/.*/,"",a[1]); # /tcp などを除去
print a[1];
}
}
}' | sort -n | uniq
ログ確認
# OpenWebuiの場合
docker logs -f --tail 50 -t open-webui
# ollamaの場合
docker logs -f --tail 50 -t ollama
# vLLMの場合
docker logs -f --tail 50 -t vllm-openai
difyナレッジ(ドキュメント取り込み/分割/埋め込み/インデックス)
## 非同期キュー処理=ナレッジ処理の中核
docker logs -f --tail 50 -t docker-worker-1
## UI/API からの要求受付・ステータス更新・例外返却
docker logs -f --tail 50 -t docker-api-1
difyスタジオ実行(Workflow/アプリ実行時のエラー)
## 実行オーケストレーション・LLM呼び出し・RAG/ツール呼び出しの入口
docker logs -f --tail 50 -t docker-api-1
## バックグラウンド実行・キュー系の処理
docker logs -f --tail 50 -t docker-worker-1
difyその他
# dify 外向きHTTP制御
docker logs -f --tail 50 -t docker-ssrf_proxy-1
# dify プラグイン/ツール
docker logs -f --tail 50 -t docker-plugin_daemon-1
# dify ベクタDB書き込み/検索
docker logs -f --tail 50 -t docker-weaviate-1
サーバ起動時エラー
sudo dmesg -T | egrep -i "oom|killed process" | tail -n 80
エラーメッセージを探す
(vllm-openaiの場合)
docker logs vllm-openai | grep -E "ERROR|CUDA|OOM|Failed"
サーバリソース確認
1) 基本
CPU
top
htop
# 全体
mpstat
# コア別
mpstat -P ALL
# 1秒間隔で5回
mpstat 1 5
GPU
# 1回のみ
nvidia-smi
# 5秒毎表示
watch -n 5 nvidia-smi
2) 5秒毎_GPU使用率、VRAM使用率、CPUロードアベレージ表示
while true; do
t=$(date +%T)
la=$(awk '{print $1","$2","$3}' /proc/loadavg)
echo "----"
echo "TIME $t LOADAVG $la"
nvidia-smi --query-gpu=index,utilization.gpu,memory.used,memory.total \
--format=csv,noheader,nounits \
| awk -F', ' '{printf "GPU%s util=%s%% VRAM=%s/%sMiB\n",$1,$2,$3,$4}'
sleep 5
done
3) 2)+CPU,GPUのTop1プロセスも表示
小窓(ターミナル)1つでCPU,GPU両方のリソースをモニタできてお勧め!
表示パターン1
while true; do
t=$(date +%T)
la=$(awk '{print $1","$2","$3}' /proc/loadavg)
echo "----"
echo "TIME $t LOADAVG $la"
# GPUサマリ(index/使用率/VRAM used/total)
nvidia-smi --query-gpu=index,utilization.gpu,memory.used,memory.total \
--format=csv,noheader,nounits \
| awk -F', ' '{printf "GPU%s util=%s%% VRAM=%s/%sMiB\n",$1,$2,$3,$4}'
# CPU TOPPROC(%CPU 最大 1件)
cpu_top=$(
ps -eo pid,pcpu,pmem,args --sort=-pcpu --no-headers \
| head -n 1 \
| awk '{
pid=$1; cpu=$2; mem=$3;
$1=$2=$3=""; sub(/^ +/,"");
cmd=$0;
if (cmd=="") cmd="(unknown)";
if (length(cmd)>90) cmd=substr(cmd,1,90)"...";
printf "CPU_TOP pid=%s cpu=%s%% mem=%s%% cmd=%s", pid, cpu, mem, cmd
}'
)
[ -n "$cpu_top" ] && echo "$cpu_top" || echo "CPU_TOP (none)"
# GPU TOPPROC(GPU Memory Usage 最大 1件 / Type=G,C を問わず)
gpu_top=$(
nvidia-smi 2>/dev/null | awk '
BEGIN{in_section=0; max=-1}
/^\| Processes:/ {in_section=1; next}
in_section && /No running processes found/ {exit}
in_section && $0 ~ /\|/ && $0 ~ /MiB/ {
line=$0
sub(/^\|[ ]*/, "", line)
sub(/[ ]*\|[ ]*$/, "", line)
gsub(/[ ]+/, " ", line)
n=split(line,a," ")
mem=a[n]; gsub(/MiB/,"",mem)
if (mem !~ /^[0-9]+$/) next
gpu=a[1]; pid=a[4]; type=a[5]
name=""
for(i=6;i<n;i++){name=name (i==6?"":" ") a[i]}
if(mem+0>max){max=mem+0; bgpu=gpu; bpid=pid; btype=type; bname=name}
}
END{
if(max>=0) printf "GPU_TOP GPU%s pid=%s type=%s name=%s vram=%dMiB", bgpu, bpid, btype, bname, max
}'
)
[ -n "$gpu_top" ] && echo "$gpu_top" || echo "GPU_TOP (none)"
sleep 5
done
表示パターン2
while true; do
t=$(date +%T)
la=$(awk '{print $1","$2","$3}' /proc/loadavg)
echo "時間⇒ $t"
echo "CPU⇒ $la"
# GPUサマリ(index/使用率/VRAM used/total)
nvidia-smi --query-gpu=index,utilization.gpu,memory.used,memory.total \
--format=csv,noheader,nounits \
| awk -F', ' '{printf "GPU⇒ %s util=%s%% VRAM=%s/%sMiB\n",$1,$2,$3,$4}'
# CPU TOPPROC(%CPU 最大 1件)
cpu_top=$(
ps -eo pid,pcpu,pmem,args --sort=-pcpu --no-headers \
| head -n 1 \
| awk '{
pid=$1; cpu=$2; mem=$3;
$1=$2=$3=""; sub(/^ +/,"");
cmd=$0;
if (cmd=="") cmd="(unknown)";
if (length(cmd)>90) cmd=substr(cmd,1,90)"...";
printf "CPU_No1⇒ pid=%s cpu=%s%% mem=%s%% cmd=%s", pid, cpu, mem, cmd
}'
)
[ -n "$cpu_top" ] && echo "$cpu_top" || echo "CPU_TOP (none)"
# GPU TOPPROC(GPU Memory Usage 最大 1件 / Type=G,C を問わず)
gpu_top=$(
nvidia-smi 2>/dev/null | awk '
BEGIN{in_section=0; max=-1}
/^\| Processes:/ {in_section=1; next}
in_section && /No running processes found/ {exit}
in_section && $0 ~ /\|/ && $0 ~ /MiB/ {
line=$0
sub(/^\|[ ]*/, "", line)
sub(/[ ]*\|[ ]*$/, "", line)
gsub(/[ ]+/, " ", line)
n=split(line,a," ")
mem=a[n]; gsub(/MiB/,"",mem)
if (mem !~ /^[0-9]+$/) next
gpu=a[1]; pid=a[4]; type=a[5]
name=""
for(i=6;i<n;i++){name=name (i==6?"":" ") a[i]}
if(mem+0>max){max=mem+0; bgpu=gpu; bpid=pid; btype=type; bname=name}
}
END{
if(max>=0) printf "GPU_No1⇒ GPU%s pid=%s type=%s name=%s vram=%dMiB", bgpu, bpid, btype, bname, max
}'
)
[ -n "$gpu_top" ] && echo "$gpu_top" || echo "GPU_TOP (none)"
echo "----"
sleep 5
done
表示パターン3
while true; do
t=$(date +%T)
la=$(awk '{print $1","$2","$3}' /proc/loadavg)
# echo "時間⇒ $t"
echo "CPU⇒ $la"
# GPUサマリ(index/使用率/VRAM used/total)
nvidia-smi --query-gpu=index,utilization.gpu,memory.used,memory.total \
--format=csv,noheader,nounits \
| awk -F', ' '{printf "GPU⇒ %s%% VRAM=%s/%sMiB %s\n",$2,$3,$4,$1}'
# CPU TOPPROC(%CPU 最大 1件)
cpu_top=$(
ps -eo pid,pcpu,pmem,args --sort=-pcpu --no-headers \
| head -n 1 \
| awk '{
pid=$1; cpu=$2; mem=$3;
$1=$2=$3=""; sub(/^ +/,"");
cmd=$0;
if (cmd=="") cmd="(unknown)";
if (length(cmd)>90) cmd=substr(cmd,1,90)"...";
printf "CPU_No1⇒ %s%% mem=%s%% cmd=%s pid=%s", cpu, mem, cmd, pid
}'
)
[ -n "$cpu_top" ] && echo "$cpu_top" || echo "CPU_TOP (none)"
# GPU TOPPROC(GPU Memory Usage 最大 1件 / Type=G,C を問わず)
gpu_top=$(
nvidia-smi 2>/dev/null | awk '
BEGIN{in_section=0; max=-1}
/^\| Processes:/ {in_section=1; next}
in_section && /No running processes found/ {exit}
in_section && $0 ~ /\|/ && $0 ~ /MiB/ {
line=$0
sub(/^\|[ ]*/, "", line)
sub(/[ ]*\|[ ]*$/, "", line)
gsub(/[ ]+/, " ", line)
n=split(line,a," ")
mem=a[n]; gsub(/MiB/,"",mem)
if (mem !~ /^[0-9]+$/) next
gpu=a[1]; pid=a[4]; type=a[5]
name=""
for(i=6;i<n;i++){name=name (i==6?"":" ") a[i]}
if(mem+0>max){max=mem+0; bgpu=gpu; bpid=pid; btype=type; bname=name}
}
END{
if(max>=0) printf "GPU_No1⇒ %dMiB name=%s GPU%s pid=%s type=%s", max, bname, bgpu, bpid, btype
}'
)
[ -n "$gpu_top" ] && echo "$gpu_top" || echo "GPU_TOP (none)"
echo "----"
sleep 5
done
[参考] vllm-openai解析用
docker compose down
docker compose pull
docker compose up -d --force-recreate
cat docker-compose.yaml
docker logs -f --tail 50 -t vllm-openai
nvidia-smi
成功メッセージを探す
docker logs vllm-openai | grep -E "Uvicorn running|Application startup complete"
エラーメッセージを探す
docker logs vllm-openai | grep -E "ERROR|CUDA|OOM|Failed"