LoginSignup
0
0

More than 1 year has passed since last update.

BuildgでDockerfileを対話的にデバッグする方法

Posted at

この記事の内容

Dockerfileのデバッグは非常に面倒です。ビルドの途中でエラーが出たら、Dockerfileを変更して再実行して確認することである程度デバッグできますが、規模の大きいDockerfileになると時間が掛かります。

Buildgはこうした問題を解決するために、Dockerfileのデバッグを対話的に行うことができるツールです。

対象者

  • Dockerの経験がある程度あり、Dockerfileを書いた経験がある人
  • Dockerfileでイメージをビルドするときにデバッグが上手くできずに苦労した経験がある人

検証環境

  • Ubuntu 20.04
  • Docker 23.0.1

Buildgを使わない場合のデバッグ方法の例

Dockerfileでイメージビルドするときにエラーが出たときに、以下の手順でコンテナを調査することができます。

  1. docker ps -aでビルドに失敗したコンテナを見つけ、docker commitしてそのコンテナのイメージを保存する。
  2. 保存したイメージからコンテナを作成して、そのコンテナにログインして中身を調べる。

この方法でもある程度調査できますが、不要なイメージが溜まっていくのが個人的にストレスだったり、地味に手順1が面倒だなあと思っていました。

そこで、見つけたのがBuildgでした。

Buildgとは?

Githubから引用すると、「BuildkitをベースにしたDockerfileをインタラクティブにデバッグするツール」とあります。

buildg is a tool to interactively debug Dockerfile based on BuildKit.

Buildkitについては深入りしませんが、興味がある方はこちらの記事が分かりやすかったです。

Buildgでできることを紹介すると、以下の通りです。

  • ソースレベルの検査
  • ブレークポイントとステップ実行
  • 独自のデバッグ ツールを使用したステップ上の対話型シェル
  • BuildKit ベース (マージされていないパッチあり)
  • ルートレスをサポート

参考:ktock/buildg

個人的に嬉しい機能が、「ブレークポイントとステップ実行」です。Dockerfileの行番号を指定して、その行までビルドするということができます。ブレイクポイントまでビルドした状態でコンテナを起動して中身を確認できます。

Buildgのセットアップ

今回は記事投稿時に最新であるv0.4.1をインストールします。以下のスクリプトを適当な場所に配置して実行すればセットアップできます。今回はバイナリをインストールして利用します。makeを利用してバイナリをビルドすることもできます。インストール手順はこちらで最新の情報を確認してください。

setup.sh
#! /bin/bash

# 実行パス取得
readonly CURRENT=$(cd $(dirname $0);pwd)

# Buildgのバージョン
BUILDG_VERSION="v0.4.1"

# バイナリーのインストール
wget -P ${CURRENT} https://github.com/ktock/buildg/releases/download/${BUILDG_VERSION}/buildg-full-${BUILDG_VERSION}-linux-amd64.tar.gz 

# 解凍
tar -zxvf buildg-full-${BUILDG_VERSION}-linux-amd64.tar.gz

# バイナリをコピー
cp ${CURRENT}/bin/* /usr/local/bin

Buildgのデモ

利用するソース

ファイルの配置は以下を想定しています。

.
├── Dockerfile
├── hello.c
└── world.c
Dockerfile
# hello.cのコンパイル
FROM ubuntu:20.04 AS hello
RUN apt-get update && \
    apt-get install -y gcc

# ソースをホストからコピー
COPY hello.c /

# "hello"という名前の実行ファイルを作成
RUN gcc -o /hello /hello.c

# world.cのコンパイル
FROM ubuntu:20.04 AS world
RUN apt-get update && \
    apt-get install -y gcc

# ソースをホストからコピー
COPY world.c /

# "world"という名前の実行ファイルを作成
RUN gcc -o /world /world.c

FROM ubuntu:20.04
COPY --from=hello /hello /hello
COPY --from=world /world /world
CMD /hello ; /world
hello.c
#include <stdio.h>
int main () {
  printf("Hello");
  return 0;
}
world.c
#include <stdio.h>
int main () {
  printf("World!");
  return 0;
}

デバッグを開始

コマンドリファレンスは以下を参考にしてください。

Dockerfileを配置したディレクトリで以下を実行します。

buildg debug .

Proxy環境下で実行する場合、--build-argで構築時の変数を指定できます。(ただし、DockerfileにProxyを利用する設定の追記が必要。)

buildg debug --build-arg http_proxy="proxy-url" --build-arg no_proxy="no-proxy-list" .

ブレイクポイントの指定

breakでブレイクポイントを指定します。continueでブレイクポイントまでビルドします。

(buildg) break 25
(buildg) continue

ブレイクポイントまでビルドした状態のコンテナに入る

ビルドした部分までの状態でコンテナ内を調べたい場合は、execを実行します。コンテ内でコマンドを実行できることが確認できました。

(buildg) exec
# cat hello.c
#include <stdio.h>
int main () {
  printf("Hello");
  return 0;
}
# ./hello
Hello

コンテナ、およびデバッグから抜ける

コンテナから抜ける場合は、exitを実行し、デバッグを終了したい場合もexitを実行します。

# exit
(buildg) exit
#6 DONE 10.8s

#7 [hello 3/4] COPY hello.c /
#7 DONE 0.0s

#8 [world 3/4] COPY world.c /
#8 DONE 0.0s

#9 [world 4/4] RUN gcc -o /world /world.c
#9 ...

#10 [hello 4/4] RUN gcc -o /hello /hello.c
#10 CANCELED

#9 [world 4/4] RUN gcc -o /world /world.c
#9 CANCELED

まとめ

Buildgを活用することで、Dockerfileのデバッグが対話的に行えることが分かりました。
buildで失敗したときに気軽にコンテナ内を調査できそうですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0