ClaudeCode_Docker実践ドリル_Ubuntu_DXエンジニア

-- Views

October 24, 26

スライド概要

profile-image

はじめまして、yukikoと申します。 IT教育支援や、DX推進が可能です。 ◆ スキル LPIC レベル2 AI / Python Splunk BI(データ可視化・分析) ◆ その他 新卒・未経験の学生向けに、エンジニア転職を応援する資料を趣味で作成しています。 もしよろしければご活用ください。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

Claude Code 入門 Ubuntu 編 | DX エンジニア向け Claude Code × Docker 実践ドリル マニアック 応用 応用 基礎・応用・マニアックの90問と、障害対応・開発環境構築・ 調査の実戦シナリオ 基礎 うさうさ研修工房 | うさうさ先生 基礎 基礎

2.

講座の全体像:3レベル × 3シナリオ ドリル(自分の指で打つ) 開発環境構築 基礎 1〜30 状態を見る・動かす・データ・ビルド ・Compose inspect で調べる・ネットワーク・バックアップ ・Compose 応用 61〜90 PID 1 とシグナル・cgroup・名前空間・ケー パビリティ・ストレージ incidents/ わざと壊した7件。ポート・環境変数・localhost・OOM・権限・ヘルス チェック・停止 調査 マニアック devenv/ 注文API+在庫API を compose で。healthcheck と依存関係 障害対応 応用 31〜60 実戦シナリオ(Claude Code と組む) investigate/ 引き継いだ「謎のコンテナ」を読み取り専用で調べ、報告書にする 合計 約4時間。ドリル1セット(10問)ずつ区切って進めるのがおすすめ Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 2

3.

SECTION 0 はじめに なぜ DX エンジニアが Docker を鍛えるのか 0-1 DX の現場と Docker 約3分 0-2 この講座の進め方とルール 約3分 0-3 Claude Code との役割分担 約3分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 3

4.

Lecture 0-1 DX の現場と Docker 1 2 3 環境差をなくす 小さく試す 障害を切り分ける 「自分の PC では動く」をなくす。新メ ンバーも compose up で同じ環境 DB や API をすぐ立てて壊して作り直 せる。PoC の速度が上がる ログ・終了コード・リソースから、アプリ か環境かを見分ける この講座のゴール コマンドを自分の指で覚え、障害・開発環境・調査の場面で、Claude Code と組んで速く正確に動けるようになる Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 4

5.

Lecture 0-2 この講座の進め方とルール 自分の指で打つ 1 結果を一言で 2 コピー&ペーストしない。打ち間違いも学び 3分ルール 3 「何が起きたか」をメモに一言で書く 片付けは自分で 4 3分でヒント列、5分で解答(付録・ノート) prune は他のプロジェクトも消す。df -v で確認してから 教材の配置(~/docker-lab) docker-lab/ basic/ ドリル90問 例 devenv/ 開発環境構築 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 incidents/ 障害7件 investigate/ 調査 claude/ Claude Code の設定 5

6.

Lecture 0-3 Claude Code との役割分担 場面 あなた Claude Code ドリル コマンドを自分で打つ 出力の読み方・エラーの意味を説明 開発環境構築 要件を決める・最後に確認 compose.yaml の下書き・レビュー 障害対応 直すかどうか決める 読み取り専用で調査・原因と案を報告 調査 調べる範囲を決める inspect などを走らせて報告書にまとめる 削除・sudo 人が判断して実行 実行しない(deny で禁止) あなた → Claude Code 「docker ps -a の出力のうち STATUS 列の読み方を、Exited (137) の例も入れて説明して」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 6

7.

SECTION 1 環境構築 Ubuntu に Docker Engine を入れ、Claude Code の権限を決める 1-1 Docker Engine を apt で入れる 約6分 1-2 docker グループと動作確認 約4分 1-3 Claude Code に Docker を触らせる設定 約5分 1-4 ラボ用の CLAUDE.md 約4分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 7

8.
[beta]
Lecture 1-1

Docker Engine を apt で入れる(1)鍵とリポジトリ
1

署名鍵を登録する
sudo apt update && sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

2

リポジトリを登録する(docker.sources)
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

8

9.

Lecture 1-1 Docker Engine を apt で入れる(2)インストール 1 インストールする sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin 2 デーモンが動いているか確認 先に確認すること • Ubuntu 標準の docker.io・podman-docker などが入っていたら、公式の手順で先に削 除 • Docker Desktop は不要(Engine だけで足 りる) • 社内プロキシ環境では、apt と Docker デーモンの両方にプロキシ設定が必要 sudo systemctl status docker --no-pager sudo docker run hello-world Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 9

10.

Lecture 1-2 docker グループと動作確認 1 docker グループに自分を入れる sudo groupadd docker # 既にあればエラーで OK sudo usermod -aG docker $USER newgrp docker # またはログインし直す 2 動作確認 大事な注意 docker グループは root レベルの権限を 与える(公式ドキュメントより) • docker を動かせる=ホストを自由にできる • 共有サーバーでは誰を入れるか管理する • AI に docker を許すときも同じ重さで考える docker run hello-world docker version # Client と Server の両方が出る docker compose version Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 10

11.
[beta]
Lecture 1-3

Claude Code に Docker を触らせる設定
.claude/settings.json(教材 claude/settings.json)
{ "permissions": {
"allow": [
"Bash(docker ps *)", "Bash(docker logs *)",
"Bash(docker inspect *)", "Bash(docker images *)",
"Bash(docker stats --no-stream *)",
"Bash(docker compose ps *)",
"Bash(docker compose logs *)",
"Bash(docker compose config *)" ],
"deny": [
"Bash(docker system prune *)",
"Bash(docker volume rm *)", "Bash(docker volume prune *)",
"Bash(docker compose down -v *)",
"Bash(sudo *)", "Read(./.env)" ]
} }

allow

読むだけ:確認なしで実行

deny

データが消える・管理者権限:禁
止

それ以外

毎回あなたに確認(restart・up な
ど)

* はサブコマンドの後ろに置く。Bash(docker *) と書くと全
部許可されてしまう

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

11

12.

Lecture 1-4 ラボ用の CLAUDE.md CLAUDE.md(教材 claude/CLAUDE.md) # Docker ラボのルール ## 進め方 - 学習が目的。コマンドは受講者が自分で打つ - Claude は説明・原因調査・レビューを担当する - 調査は読み取り専用のコマンドから始める - 直し方の案を出したら、実行前に必ず確認をとる ## 禁止 - prune・volume rm・down -v を自分で実行しない - sudo を使わない - .env やトークンの値を表示しない ## 報告の形 - 症状 → 調べたこと → 原因 → 直し方の案 → 再発防止 2つの設定の違い settings.json できること・できないことの「鍵」。守られる CLAUDE.md 進め方・報告の形の「お願い」。文脈として読 まれる 大事なものは両方に書く Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 12

13.

SECTION 2 基礎ドリル(1〜30) 状態を見る・動かす・作る 2-1 基礎 1〜10:状態を見る 約10分 2-2 基礎 11〜20:動かす・データを持つ 約10分 2-3 基礎 21〜30:作る・まとめて動かす 約10分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 13

14.

Lecture 2-1 レベル:基礎 基礎ドリル 1〜10:状態を見る No お題 ヒント 1 クライアントとサーバーのバージョンを表示 version 2 サーバーのバージョンだけを1行で表示 info --format 3 alpine で hello と表示し、終わったら消す --rm 4 nginx を web という名前で 8080 番に公開 -d --name -p 5 動いているコンテナを一覧する ps 6 終了したコンテナだけを一覧する --filter 7 web のログを最後の20行だけ表示 --tail 8 web のログを流し続けて見る -f 9 web の中でシェルを開く exec -it 10 全コンテナの CPU・メモリを1回だけ表示 stats Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 14

15.

Lecture 2-2 レベル:基礎 基礎ドリル 11〜20:動かす・データを持つ No お題 ヒント 11 環境変数 APP_ENV=dev を渡して env を表示 -e 12 .env ファイルの中身をまとめて渡す --env-file 13 作業ディレクトリを /tmp にして pwd -w 14 lab-data という名前付きボリュームを作る volume create 15 lab-data の /data/a.txt に hi と書く -v 名前:パス 16 別のコンテナから a.txt を読む cat 17 今のフォルダを読み取り専用で 8081 番に公開 -v "$PWD":…:ro 18 web を再起動する restart 19 PC 再起動後も自動で戻る web3 を起動 --restart 20 web3 の再起動ポリシーを確認する inspect -f Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 15

16.

Lecture 2-3 レベル:基礎 基礎ドリル 21〜30:作る・まとめて動かす No お題 ヒント 21 Dockerfile から lab-web:1.0 をビルド build -t 22 lab-web:1.0 を lab として 8082 番で起動 run -p 23 lab-web:1.0 に latest のタグも付ける tag 24 lab-web のタグとサイズを一覧する images 25 compose.yaml のサービスを起動する compose up -d 26 Compose のサービスの状態を見る compose ps 27 app サービスのログを流し続ける compose logs -f 28 app サービスの中でシェルを開く compose exec 29 Compose のサービスを止めて片付ける compose down 30 停止中のコンテナをまとめて削除する container prune Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 16

17.

SECTION 3 応用ドリル(31〜60) 調べる・つなぐ・Compose を使いこなす 3-1 応用 31〜40:調べる 約12分 3-2 応用 41〜50:ネットワークとデータ 約12分 3-3 応用 51〜60:Compose とビルド 約12分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 17

18.

Lecture 3-1 レベル:応用 応用ドリル 31〜40:調べる No お題 ヒント 31 web の状態と終了コードを1行で表示 inspect -f 32 終了コード3で終わる crash を作り、コードを確認 sh -c 'exit 3' 33 web2 のマウント情報を JSON で表示 {{json …}} 34 web の IP アドレスだけを表示 range Networks 35 web のポートの対応を表示 port 36 web の中で動いているプロセスを表示 top 37 名前・CPU・メモリだけを表で表示 --format table 38 web で起動後に変わったファイルを表示 diff 39 過去10分のコンテナのイベントを表示して終える events --until 40 web の過去5分のログを時刻付きで表示 --since -t Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 18

19.

Lecture 3-2 レベル:応用 応用ドリル 41〜50:ネットワークとデータ No お題 ヒント 41 lab-net というネットワークを作る network create 42 lab-net に stock という nginx を起動 --network 43 lab-net から stock の名前を引く getent hosts 44 既定の bridge では名前が引けないことを確かめる --network なし 45 既存の web を lab-net にもつなぐ network connect 46 lab-net につながるコンテナ名を一覧 range .Containers 47 lab-data の実体の場所を表示 volume inspect 48 lab-data を tar.gz でバックアップ -v 2つ + tar 49 web の index.html を手元にコピー cp 50 /cache をメモリ上に置いて容量を見る --tmpfs Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 19

20.

Lecture 3-3 レベル:応用 応用ドリル 51〜60:Compose とビルド No お題 ヒント 51 最終的な Compose の設定を表示 compose config 52 イメージを作り直して起動 --build 53 app で一回だけコマンドを実行して消す compose run --rm 54 app サービスだけ再起動する compose restart 55 app の過去10分のログを時刻付きで --since -t 56 開発用の上書きファイルを重ねた設定を表示 -f を2つ 57 tools プロファイルも含めて起動 --profile 58 build ステージだけをビルド --target 59 キャッシュなし・全ログ表示でビルド --no-cache --progress 60 プロファイル分も含め、ボリュームごと片付け down -v Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 20

21.

SECTION 4 マニアックドリル(61〜90) コンテナの正体=プロセス・名前空間・cgroup に触れる 4-1 マニアック 61〜70:プロセスとシグナル 約12分 4-2 マニアック 71〜80:リソースとカーネル 約12分 4-3 マニアック 81〜90:ストレージ・ビルド・運用 約12分 4-4 解説:PID 1 とシグナル 約6分 4-5 解説:コンテナの正体 約6分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 21

22.

Lecture 4-1 レベル:マニアック マニアックドリル 61〜70:プロセスとシグナル No お題 ヒント 61 sleep を PID 1 で動かし、止めるのに何秒かかるか測る time docker stop 62 sig の終了コードを確認する inspect 63 --init 付きで同じことをして比べる --init 64 web3 を3秒の猶予で止める stop -t 65 終了コード5で終わるジョブを待ち、結果を受け取る wait 66 プロセス数を20に制限してフォーク爆弾を防ぐ --pids-limit 67 web のプロセスを PID・親 PID・コマンドで表示 top + ps オプション 68 コンテナの中では PID 1 から始まることを確かめる ps 69 停止シグナルを SIGINT・猶予5秒で起動 --stop-signal 70 stopsig の停止シグナルと猶予を確認 inspect Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 22

23.

Lecture 4-2 レベル:マニアック マニアックドリル 71〜80:リソースとカーネル No お題 ヒント 71 メモリ32MBで200MBを確保させる --memory 72 oom が OOM で死んだかを確認 OOMKilled 73 CPU を0.5個分に制限して起動し、設定を見る --cpus 74 動いている cpu のメモリ上限を後から変える update 75 web のホスト側 PID を表示 State.Pid 76 web の名前空間の一覧をホストから見る /proc/PID/ns 77 web の UTS 名前空間に入ってホスト名を見る nsenter -u 78 全ケーパビリティを外して chown を試す --cap-drop ALL 79 ルートを読み取り専用にし /tmp だけ書けるようにする --read-only --tmpfs 80 権限昇格を禁止して NoNewPrivs を確認 --security-opt Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 23

24.

Lecture 4-3 レベル:マニアック マニアックドリル 81〜90:ストレージ・ビルド・運用 No お題 ヒント 81 lab-web:1.0 を作った命令を省略せず表示 history --no-trunc 82 lab-web:1.0 の中身を tar で一覧 save | tar -t 83 web のファイルシステムを tar で一覧 export | tar -t 84 web のログファイルの場所を表示 LogPath 85 ログを1MB×3世代でローテーションして起動 --log-opt 86 logrot のログ設定を確認 LogConfig 87 キャッシュマウントの Dockerfile.cache を2回ビルド --mount=type=cache 88 SSH 先の Docker を操作するコンテキストを作る context create 89 過去30分のイベントを JSON で表示 --format json 90 イメージ・コンテナ・ボリュームの使用量を詳しく system df -v Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 24

25.

Lecture 4-4 解説:PID 1 とシグナル(実測) docker stop の流れ 1 SIGTERM を送る(止まってね) 2 10秒待つ(-t で変更可) 3 まだ動いていれば SIGKILL PID 1 の落とし穴 PID 1 は自分でシグナルを処理しないと SIGTERM を無視 する。exec だけでは直らない。--init(tini)か、アプリで SIGTERM を処理する 終了コード:137=SIGKILL(128+9)/143=SIGTERM(128+15) Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 25

26.
[beta]
Lecture 4-5

解説:コンテナの正体
ホストの Linux カーネル(コンテナはここで動く普通のプロセス:docker inspect -f '{{.State.Pid}}')

名前空間

cgroup

ケーパビリティ

見えるものを分ける

使える量を制限する

root の力を削る

pid・net・mnt・uts・ipc など。コンテナの中
では PID 1 から始まり、ホスト名も別

メモリ・CPU・プロセス数。超えると OOM
Kill(137)や fork できない

root の権限を細かく分けたもの。全部外
すと root でも chown できない

ls -l /proc/<PID>/ns
nsenter -t <PID> -u hostname

--memory --cpus
--pids-limit docker update

--cap-drop ALL
--security-opt no-new-privileges

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

26

27.

SECTION 5 開発環境構築シナリオ Claude Code と compose で、チームの開発環境を作る 5-1 作るもの:注文API と在庫API 約5分 5-2 compose.yaml を読み解く 約7分 5-3 Claude Code と作る・レビューする 約7分 5-4 起動して確かめる 約5分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 27

28.

Lecture 5-1 作るもの:注文API と在庫API compose のネットワーク(devenv_default) app(注文API) stock(在庫API) Dockerfile でビルド ポート 8000 を公開 ./app をボリュームでマウント STOCK_URL=http://stock:9000 http://stock:9000 python:3.12-slim をそのまま使う ポートは公開しない(中だけ) healthcheck で /health を確認 healthy になってから ブラウザ・curl → localhost:8000 → app → stock 依存パッケージなし(Python 標準ライブラリだけ)なので、社内プロキシの下でも動かしやすい Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 28

29.

Lecture 5-2 compose.yaml を読み解く services: app: build: . # ① ports: ["8000:8000"] environment: STOCK_URL: http://stock:9000 # ② volumes: ["./app:/app"] # ③ depends_on: stock: condition: service_healthy # ④ stock: image: python:3.12-slim command: ["python3", "/srv/stock.py"] volumes: ["./stock:/srv:ro"] healthcheck: # ④ test: ["CMD", "python3", "-c", "…/health"] interval: 5s retries: 5 build と image ① 自作は build、既製品は image サービス名で接続 ② localhost ではなく stock ソースをマウント ③ 直して再起動するだけで反映 使えるまで待つ ④ Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 healthcheck+service_healthy 29

30.

Lecture 5-3 Claude Code と作る・レビューする あなた → Claude Code 「devenv の要件:app は Dockerfile からビルドし 8000 番を公開、stock は python:3.12-slim で /srv/stock.py を実行、stock が healthy になってから app を起動。compose.yaml の下書きを作って、docker compose config で 確認して」 レビューで出てきやすい指摘の例 • イメージのタグを固定する(latest を避ける) • root ではなく専用ユーザーで動かす(USER) • ログのローテーションを設定する • init: true で停止を速くする • 秘密情報は environment に直接書かない あなた → Claude Code 「この compose.yaml をレビューして。本番に近づけるための改善 点を3つ、理由つきで。まだ直さないで」 AI の指摘は毎回変わる。採用するかは自分で判断 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 30

31.

Lecture 5-4 起動して確かめる 起動(healthy になるまで待つ) cd ~/docker-lab/devenv docker compose up -d --build --wait docker compose ps curl -s localhost:8000/ --wait が便利 healthcheck が通るまで待ってから戻る。CI やセットアップスクリ プトで「起動したつもり」を防げる 実際の結果 Container devenv-stock-1 Healthy Container devenv-app-1 Healthy SERVICE STATUS app Up 5 seconds (healthy) stock Up 11 seconds (healthy) {"shop": "うさうさラーメン店", "stock": {"しょうゆ": 12, "みそ": 8, "しお": 5}} Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 31

32.

SECTION 6 障害対応シナリオ わざと壊した7件を、Claude Code と切り分ける 6-1 障害対応の型 約5分 6-5 障害4:夜間バッチが消える 約6分 6-2 障害1:ポートがぶつかる 約6分 6-6 障害5:ログが書けない 約6分 6-3 障害2:すぐ止まる 約6分 6-7 障害6:いつまでも起動しない 約6分 6-4 障害3:localhost の罠 約6分 6-8 障害7:止めるのに10秒 約6分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 32

33.

Lecture 6-1 障害対応の型 1 2 3 4 5 6 状況把握 ログ 設定と状態 仮説と再現 直す 再発防止 docker compose ps -a docker compose logs docker inspect 1つずつ変えて試す 人が判断して実行 設定 ・README・CLAUDE. md へ 1〜3 は Claude Code に任せてよい(読み取り専用) 4〜6 は人が判断する(Claude は案を出す) 終了コードの早見表 コード 意味 よくある原因 0 1 137 143 正常終了 アプリのエラー SIGKILL(128+9) SIGTERM(128+15) 処理が終わった(常駐のはずなら設定ミス) 例外・設定不足 → logs を見る OOM Kill、または stop の猶予切れ 正しく止められた Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 33

34.

Lecture 6-2 incidents/01-port 障害1:ポートがぶつかる 症状(実際の出力) Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint 01-port-shop-1 (…): Bind for 0.0.0.0:8080 failed: port is already allocated 調べる docker ps --filter publish=8080 sudo ss -ltnp | grep 8080 あなた → Claude Code 「docker compose up でポートのエラーが出た。読み取り専用のコマンドだけ で原因を調べて。直し方は案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 shop と admin が同じホスト側ポート 8080 を使っている。前のドリ ルの web が 8080 を使ったまま残っていることも多い 直し方 # compose.yaml の admin を ports: - "8081:80" 再発防止 ポートの割り当て表を README と CLAUDE.md に書く。ポートは .env の 変数にしておく 34

35.

Lecture 6-3 incidents/02-exit 障害2:起動したのにすぐ止まる 症状(実際の出力) $ docker compose ps -a app Exited (1) 2 seconds ago $ docker compose logs app KeyError: 'STOCK_URL' 調べる docker compose ps -a docker compose logs app あなた → Claude Code 「app がすぐ止まる。読み取り専用のコマンドだけで原因を調べて。直し方は 案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 アプリに必要な環境変数 STOCK_URL が渡されておらず、起動 直後に KeyError で終了(終了コード1) 直し方 environment: STOCK_URL: http://stock:9000 再発防止 ${STOCK_URL:?STOCK_URL を設定して} と書くと、未設定なら compose が起動前に止めてくれる(実測で確認) 35

36.

Lecture 6-4 incidents/03-localhost 障害3:localhost の罠 症状(実際の出力) $ curl localhost:8000/ curl: (52) Empty reply from server $ docker compose logs app urllib.error.URLError: <urlopen error [Errno 111] Connection refused> 調べる docker compose logs app docker compose exec app env | grep STOCK あなた → Claude Code 「app は動いているのに curl で返事がない。読み取り専用のコマンドだけで 原因を調べて。直し方は案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 STOCK_URL が http://localhost:9000。コンテナの中の localhost は自分自身なので、stock には届かない 直し方 environment: STOCK_URL: http://stock:9000 再発防止 コンテナ同士の接続はサービス名で書く。localhost を使うのはホストから 見るときだけ 36

37.

Lecture 6-5 incidents/04-oom 障害4:夜間バッチが途中で消える 症状(実際の出力) $ docker compose up batch-1 | batch: start batch-1 exited with code 137 調べる docker inspect -f '{{.State.OOMKilled}} {{.State.ExitCode}}' \ $(docker compose ps -aq batch) # → true 137 あなた → Claude Code 「batch が start のあと終了コード137で消える。読み取り専用のコマンドだけ で原因を調べて。直し方は案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 mem_limit: 64m の制限に対して、データを全部(約300MB)メモリ に載せようとして OOM Killer に殺された 直し方 # 根本:分割して読む・ストリームで処理する # 応急:実測して上限を見直す mem_limit: 512m memswap_limit: 512m 再発防止 docker stats で実際の使用量を測ってから上限を決める。上限を上げる だけで済ませない 37

38.

Lecture 6-6 incidents/05-perm 障害5:注文ログが書けない 症状(実際の出力) $ docker compose ps -a writer Exited (1) 2 seconds ago PermissionError: [Errno 13] Permission denied: '/data/orders.log' 調べる docker compose run --rm --user root writer \ ls -ldn /data # → 0 0(root 所有) docker compose run --rm writer id # → uid=1000 あなた → Claude Code 「writer が Permission denied で止まる。読み取り専用のコマンドだけで原因 を調べて。直し方は案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 新しく作られた名前付きボリュームは root 所有。アプリは user: "1000:1000" で動くので書き込めない 直し方 docker compose run --rm --user root writer \ chown 1000:1000 /data docker compose up -d 再発防止 自作イメージなら Dockerfile で mkdir と chown をしてから USER を切り 替える(その所有者が新しいボリュームに引き継がれる) 38

39.
[beta]
Lecture 6-7

incidents/06-health

障害6:app がいつまでも起動しない
症状(実際の出力)
dependency failed to start: container
06-health-stock-1 is unhealthy
app
Created
stock Up 9 seconds (unhealthy)

調べる
docker inspect -f '{{json .State.Health}}' \
06-health-stock-1
# → URLError … Connection refused

あなた → Claude Code

「app が起動しない。stock が unhealthy と出る。読み取り専用のコマンドだけ
で原因を調べて。直し方は案だけ出して、まだ直さないで」

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

原因
stock の healthcheck が 9999 番を見ている(実際は 9000 番)。
stock は動いているのに unhealthy 扱いで、app が待ち続ける

直し方
healthcheck:
test: ["CMD", "python3", "-c", "…urlopen(
'http://localhost:9000/health')"]

再発防止
healthcheck のコマンドは docker compose exec で手で実行して確かめ
てから書く

39

40.

Lecture 6-8 incidents/07-stop 障害7:止めるのに毎回10秒かかる 症状(実際の出力) $ docker compose top web PID 1 相当: /bin/sh /srv/start.sh その子: python3 /srv/server.py $ docker compose stop web # 約10.3秒・exit 137 調べる docker compose top web docker inspect -f '{{.State.ExitCode}}' \ $(docker compose ps -aq web) あなた → Claude Code 「docker compose stop に毎回10秒かかる。読み取り専用のコマンドだけで原 因を調べて。直し方は案だけ出して、まだ直さないで」 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 原因 PID 1 の sh が SIGTERM を処理せず、子の python にも渡さな い。10秒後に SIGKILL(137) 直し方 services: web: init: true # 実測 0.3秒・exit 143 再発防止 init: true を標準にする。アプリでも SIGTERM を処理する。exec を付ける だけでは直らなかった(実測) 40

41.

SECTION 7 調査シナリオ 引き継いだ「謎のコンテナ」を、読み取り専用で調べ上げる 7-1 ミッション:謎のコンテナ mystery 約3分 7-2 調査チェックリスト 約8分 7-3 調査結果と報告書 約8分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 41

42.

Lecture 7-1 ミッション:謎のコンテナ mystery cd ~/docker-lab/investigate ./setup.sh # mystery を起動する 報告書で答える質問 1 何のイメージから、どう作られたか 2 何のプロセスが動いているか 3 外に開けているポートは 4 データはどこに保存されているか 5 設定(環境変数・ラベル)は 6 健康状態・再起動ポリシー・リソース制限は 7 止めたら何が困りそうか ミッション ドキュメントのない mystery を引き継いだ。 変更を加えずに調べて、次の質問に答える報告書を作る。 ルール:読み取り専用のコマンドだけ。stop・rm・exec での変更は 禁止 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 42

43.
[beta]
Lecture 7-2

調査チェックリスト
知りたいこと

コマンド

イメージと作り方

docker history --format '{{.CreatedBy}}' mystery:1

動いているプロセス

docker top mystery -eo pid,cmd

公開ポート

docker port mystery

データの場所

docker inspect -f '{{range .Mounts}}{{.Type}} {{.Destination}}{{println}}{{end}}' mystery

環境変数

docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' mystery

ラベル

docker inspect -f '{{json .Config.Labels}}' mystery

健康・再起動・メモリ

docker inspect -f '{{.State.Health.Status}} {{.HostConfig.RestartPolicy.Name}} {{.HostConfig.Memory}}' mystery

最近のログ

docker logs --tail 5 -t mystery

起動後に変わったファイル

docker diff mystery

中身を見る

docker exec mystery ls -la /opt/sync

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

43

44.
[beta]
Lecture 7-3

調査結果と報告書
実際の調査結果(抜粋)
image=mystery:1 restart=unless-stopped
mem=268435456 health=healthy
{"app":"order-sync","owner":"[email protected]"}
SYNC_INTERVAL=5
API_TOKEN=dummy-token-for-training
volume 88d0afb0… -> /var/lib/sync
7000/tcp -> 0.0.0.0:7000
… sync: 42 orders synced (interval=5s)
A /tmp/cache.json

あなた → Claude Code

「mystery を読み取り専用のコマンドだけで調べて、7つの
質問に答える調査報告書を Markdown で report.md に
作って。トークンの値は伏せて」

報告書の見出し例
概要/構成/データ/公開ポート/設定/リスク(トークン
平文・匿名ボリューム)/止める前の確認事項

気づき:トークンが環境変数に平文。inspect できる人には丸見え → シークレッ
トの管理を見直す

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

44

45.

SECTION 8 安全とまとめ AI に Docker を任せるときのルールと、次の一歩 8-1 AI に Docker を任せるときの5つのルール 約5分 8-2 振り返りと次の一歩 約3分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 45

46.

Lecture 8-1 AI に Docker を任せるときの5つのルール 1 docker = root と同じ docker グループ・ソケットは管理者権 限。AI に許す範囲も同じ重さで考える 4 2 ps・logs・inspect は allow。prune・volume rm・sudo は deny シークレットを守る トークンを環境変数に平文で置かない。会話にも貼らない Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 3 読むだけ任せる 5 本番につながない docker context の切り替えに注意。AI の作業は開発環境だけで 直す判断は人 Claude は原因と案まで。実行・再発防止の決定は人が行う 46

47.

Lecture 8-2 振り返りと次の一歩 到達チェック 次の一歩 チームの環境を compose に 基礎30問を見ずに打てる 1 README の手順書を compose.yaml に置き換える inspect -f で欲しい値を抜き出せる 型と CLAUDE.md を共有 終了コード 1・137・143 の違いを説明できる 2 障害対応の型・報告の形をチームの標準に healthcheck と depends_on で起動順を作れる Dev Containers と CI 障害対応の型で、7件の原因を切り分けられる 3 VS Code の開発コンテナ、CI でのテスト実行へ 読み取り専用で調査し、報告書にまとめられる Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 47

48.

おつかれさまでした 質問は Q&A へ。現場で役立ったエピソードも聞かせてください。 面白きこともなき世を面白く うさうさ研修工房 | うさうさ先生

49.

APPENDIX 付録:ドリル解答(1〜90) すべてこの講座の環境(Docker Engine 29・Compose v5・Ubuntu 24.04)で実行して確認済み Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 49

50.

解答 1〜10:基礎・状態を見る No コマンド ポイント 1 docker version Server が出なければデーモン未起動 2 docker info --format '{{.ServerVersion}}' --format で欲しい値だけ抜く 3 docker run --rm alpine:3.20 echo hello 使い捨てコンテナの基本形 4 docker run -d --name web -p 8080:80 nginx:alpine ホスト:コンテナ の順 5 docker ps STATUS と PORTS を読む 6 docker ps -a --filter status=exited 障害調査の最初の一歩 7 docker logs --tail 20 web 長いログはまず末尾から 8 docker logs -f web Ctrl+C で抜ける 9 docker exec -it web sh exit してもコンテナは止まらない 10 docker stats --no-stream --no-stream が無いと流れ続ける Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 50

51.
[beta]
解答 11〜20:基礎・動かす・データを持つ
No

コマンド

ポイント

11

docker run --rm -e APP_ENV=dev alpine:3.20 env

設定はイメージに焼かず外から渡す

12

docker run --rm --env-file .env alpine:3.20 env

.env は Git に入れない

13

docker run --rm -w /tmp alpine:3.20 pwd

/tmp と出れば正解

14

docker volume create lab-data

データをコンテナの外に置く

15

docker run --rm -v lab-data:/data alpine:3.20 sh -c 'echo hi > /data/a.txt'

コンテナが消えても残る

16

docker run --rm -v lab-data:/data alpine:3.20 cat /data/a.txt

hi が出れば永続化できている

17

docker run -d --name web2 -p 8081:80 -v "$PWD":/usr/share/nginx/html:ro nginx:alpine

開発中のファイルをそのまま配信

18

docker restart web

設定を読み直させたいとき

19

docker run -d --name web3 --restart unless-stopped nginx:alpine

手で止めたものは戻らない

20

docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' web3

unless-stopped と出る

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

51

52.

解答 21〜30:基礎・作る・まとめて動かす No コマンド ポイント 21 docker build -t lab-web:1.0 . 最後の . はビルドの材料フォルダ 22 docker run -d --name lab -p 8082:80 lab-web:1.0 localhost:8082 で確認 23 docker tag lab-web:1.0 lab-web:latest 同じ IMAGE ID=コピーではない 24 docker images lab-web マルチステージで小さく保つ 25 docker compose up -d ビルドも自動で行われる 26 docker compose ps このフォルダのものだけ表示 27 docker compose logs -f app Ctrl+C で抜ける 28 docker compose exec app sh サービス名で入れる 29 docker compose down ネットワークも消える。ボリュームは残る 30 docker container prune -f -f は確認なし。本番では慎重に Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 52

53.
[beta]
解答 31〜40:応用・調べる
No

コマンド

ポイント

31

docker inspect -f '{{.State.Status}} {{.State.ExitCode}}' web

running 0 なら正常

32

docker run --name crash alpine:3.20 sh -c 'exit 3'; docker inspect -f '{{.State.ExitCode}}' crash

アプリの失敗はコードに出る

33

docker inspect -f '{{json .Mounts}}' web2

どこがホストとつながっているか

34

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

ネットワークごとに IP がある

35

docker port web

80/tcp -> 0.0.0.0:8080

36

docker top web

ホストから見た PID が出る

37

docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'

報告書に貼りやすい形に

38

docker diff web

A 追加・C 変更・D 削除

39

docker events --since 10m --until 0s --filter type=container

--until が無いと待ち続ける

40

docker logs --since 5m -t web

障害の時刻と突き合わせる

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

53

54.
[beta]
解答 41〜50:応用・ネットワークとデータ
No

コマンド

ポイント

41

docker network create lab-net

自作ネットワークは名前で引ける

42

docker run -d --name stock --network lab-net nginx:alpine

ポートを公開しなくてよい

43

docker run --rm --network lab-net alpine:3.20 getent hosts stock

IP が返れば DNS が効いている

44

docker run --rm alpine:3.20 getent hosts stock

何も出ない(終了コード2)

45

docker network connect lab-net web

1つのコンテナに複数ネットワーク

46

docker network inspect -f '{{range .Containers}}{{.Name}} {{end}}' lab-net

誰と誰が同じ網か

47

docker volume inspect -f '{{.Mountpoint}}' lab-data

/var/lib/docker/volumes/…

48

docker run --rm -v lab-data:/data -v "$PWD":/backup alpine:3.20 tar czf /backup/lab-data.tgz -C /data .

ボリュームの定番バックアップ

49

docker cp web:/usr/share/nginx/html/index.html ./from-web.html

止まったコンテナからも取れる

50

docker run --rm --tmpfs /cache alpine:3.20 df -h /cache

止めると消える一時領域

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

54

55.

解答 51〜60:応用・Compose とビルド No コマンド ポイント 51 docker compose config YAML の書き間違いが見つかる 52 docker compose up -d --build Dockerfile を直したら 53 docker compose run --rm app ls /usr/share/nginx/html 使い捨てでメンテ作業 54 docker compose restart app 他のサービスは止まらない 55 docker compose logs --since 10m -t app サービス単位で時刻を追う 56 docker compose -f compose.yaml -f compose.override.dev.yaml config 後に書いた方が勝つ 57 docker compose --profile tools up -d ふだんは起動しない道具箱 58 docker build --target build -t lab-web:build . マルチステージの途中を確認 59 docker build --no-cache --progress=plain -t lab-web:1.0 . ビルド失敗の調査に 60 docker compose --profile tools down -v --remove-orphans -v でボリュームも消える Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 55

56.
[beta]
解答 61〜70:マニアック・プロセスとシグナル
No

コマンド

ポイント

61

docker run -d --name sig alpine:3.20 sleep 300; time docker stop sig

PID 1 は SIGTERM を無視しがち→10秒後に強制終
了

62

docker inspect -f '{{.State.ExitCode}}' sig

137=SIGKILL で殺された

63

docker run -d --init --name sig2 alpine:3.20 sleep 300; time docker stop sig2

tini が PID 1 になりすぐ止まる

64

docker stop -t 3 web3

猶予を過ぎると SIGKILL

65

docker run -d --name job alpine:3.20 sh -c 'sleep 2; exit 5'; docker wait job

スクリプトで完了を待つ

66

docker run --rm --pids-limit 20 alpine:3.20 sh -c 'i=0; while [ $i -lt 50 ]; do sleep 30 & i=$((i+1)); done; wait'

can't fork が出れば制限が効いている

67

docker top web -eo pid,ppid,cmd

docker top は ps のオプションを受け取る

68

docker run --rm alpine:3.20 ps

PID 名前空間で分かれている

69

docker run -d --name stopsig --stop-signal SIGINT --stop-timeout 5 nginx:alpine

アプリに合わせて止め方を決める

70

docker inspect -f '{{.Config.StopSignal}} {{.Config.StopTimeout}}' stopsig

SIGINT 5 と出る

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

56

57.
[beta]
解答 71〜80:マニアック・リソースとカーネル
No

コマンド

ポイント

71

docker run --name oom --memory 32m --memory-swap 32m python:3.12-slim python3 -c 'b = bytearray(200*1024*1024)'

OOM Killer に殺される

72

docker inspect -f '{{.State.OOMKilled}} {{.State.ExitCode}}' oom

true 137 なら OOM

73

docker run -d --name cpu --cpus 0.5 alpine:3.20 sleep 300; docker inspect -f '{{.HostConfig.NanoCpus}}'
cpu

500000000(ナノ単位)

74

docker update --memory 256m --memory-swap 256m cpu

再作成せずに変更できる

75

docker inspect -f '{{.State.Pid}}' web

コンテナもホストのプロセス

76

sudo ls -l /proc/$(docker inspect -f '{{.State.Pid}}' web)/ns

net・pid・uts…が分かれている

77

sudo nsenter -t $(docker inspect -f '{{.State.Pid}}' web) -u hostname

コンテナ ID がホスト名になっている

78

docker run --rm --cap-drop ALL alpine:3.20 chown 65534 /tmp

Operation not permitted=root でも権限なし

79

docker run --rm --read-only --tmpfs /tmp alpine:3.20 sh -c 'touch /a; touch /tmp/b && echo tmp-ok'

/a は Read-only、/tmp は書ける

80

docker run --rm --security-opt no-new-privileges alpine:3.20 grep NoNewPrivs /proc/self/status

NoNewPrivs: 1

Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房

57

58.

解答 81〜90:マニアック・ストレージ・ビルド・運用 No コマンド ポイント 81 docker history --no-trunc --format '{{.CreatedBy}}' lab-web:1.0 イメージの作り方を逆算 82 docker save lab-web:1.0 | tar -t | head レイヤーとマニフェストが見える 83 docker export web | tar -t | head コンテナの今の中身を丸ごと 84 docker inspect -f '{{.LogPath}}' web json-file ドライバーの実体 85 docker run -d --name logrot --log-opt max-size=1m --log-opt max-file=3 nginx:alpine 放置するとディスクを食う 86 docker inspect -f '{{json .HostConfig.LogConfig}}' logrot max-size と max-file を確認 87 docker build -f Dockerfile.cache --progress=plain --build-arg BUST=$(date +%s) -t lab-cache . 2回目は builds so far が増える=キャッシュが残る 88 docker context create lab-remote --docker host=ssh://user@server docker --context lab-remote ps で操作 89 docker events --since 30m --until 0s --format '{{json .}}' jq で集計できる 90 docker system df -v 片付けの前に必ず見る Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 58

59.

付録:講座で使うプロンプト集 ドリル docker ps -a の出力のうち STATUS 列の読み方を、Exited (137) の例も入れて説明して 構築 この compose.yaml をレビューして。本番に近づけるための改善点を3つ、理由つきで。まだ直さないで 障害 〈症状〉。読み取り専用のコマンドだけで原因を調べて。直し方は案だけ出して、まだ直さないで 障害 原因と直し方を、症状 → 調べたこと → 原因 → 直し方 → 再発防止 の順で incident.md にまとめて 調査 mystery を読み取り専用のコマンドだけで調べて、7つの質問に答える調査報告書を report.md に作って。トークンの値は伏せて マニアック docker stop が10秒かかる理由を、PID 1 とシグナルの観点で初心者向けに説明して Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 59

60.

講師用:レクチャー一覧 No レクチャー 0-1 DX の現場と Docker 0-2 分 No レクチャー 分 3 5-1 作るもの:注文API と在庫API 5 この講座の進め方とルール 3 5-2 compose.yaml を読み解く 7 0-3 Claude Code との役割分担 3 5-3 Claude Code と作る・レビューする 7 1-1 Docker Engine を apt で入れる 6 5-4 起動して確かめる 5 1-2 docker グループと動作確認 4 6-1 障害対応の型 5 1-3 Claude Code に Docker を触らせる設定 5 6-2 障害1:ポートがぶつかる 6 1-4 ラボ用の CLAUDE.md 4 6-3 障害2:すぐ止まる 6 2-1 基礎 1〜10:状態を見る 10 6-4 障害3:localhost の罠 6 2-2 基礎 11〜20:動かす・データを持つ 10 6-5 障害4:夜間バッチが消える 6 2-3 基礎 21〜30:作る・まとめて動かす 10 6-6 障害5:ログが書けない 6 3-1 応用 31〜40:調べる 12 6-7 障害6:いつまでも起動しない 6 3-2 応用 41〜50:ネットワークとデータ 12 6-8 障害7:止めるのに10秒 6 3-3 応用 51〜60:Compose とビルド 12 7-1 ミッション:謎のコンテナ mystery 3 4-1 マニアック 61〜70:プロセスとシグナル 12 7-2 調査チェックリスト 8 4-2 マニアック 71〜80:リソースとカーネル 12 7-3 調査結果と報告書 8 4-3 マニアック 81〜90:ストレージ・ビルド・運用 12 8-1 AI に Docker を任せるときの5つのルール 5 4-4 解説:PID 1 とシグナル 6 8-2 振り返りと次の一歩 3 4-5 解説:コンテナの正体 6 合計 35 レクチャー・約 4 時間 0 分 Claude Code × Docker 実践ドリル(Ubuntu編)| うさうさ研修工房 60