1. はじめに
DockerとDockerfileとは?
近年、開発環境の整備やアプリケーションのデプロイを効率化する手段として、Dockerが急速に普及しています。Dockerは、アプリケーションとその依存環境を一つの「コンテナ」としてパッケージ化し、どこでも同じ環境で実行できるという特長を持っています。
このDockerコンテナの構築には、「Dockerfile」という設計図が必要です。Dockerfileは、ベースとなるOSイメージの指定や、インストールするソフトウェア、環境変数の設定などを記述するテキストファイルです。開発者はこのファイルを使って、カスタマイズされた環境を自動的に構築できます。
Ubuntuをベースにする理由
Dockerfileを作成する際には、最初にベースとなるOSイメージを指定する必要があります。その中でも特に人気が高いのが、Ubuntuです。UbuntuはDebianベースのLinuxディストリビューションで、使いやすさと豊富なパッケージによる柔軟な環境構築が可能です。
UbuntuをベースとしたDockerfileは、以下のような利点があります:
- 豊富な公式・コミュニティのドキュメントが存在し、学習コストが低い
- 多くのパッケージやツールがAPTで簡単に導入できる
- 軽量なミニマルイメージ(
ubuntu:20.04
,ubuntu:24.04
など)が公式に提供されている
本記事の目的と対象読者
本記事では、「Dockerfile Ubuntu」というキーワードをテーマに、UbuntuベースのDockerfileの作成方法について、初心者にもわかりやすく解説していきます。
具体的には、Dockerfileの基本的な構造から、実際にUbuntu環境を構築する手順、さらにPythonなどのアプリケーション環境の導入例、そしてよくあるエラーとその対処法までを網羅的に紹介します。
このような方におすすめの内容です:
- はじめてDockerfileを使って環境を構築したい方
- Ubuntuで開発環境を再現性高く作りたい方
- トラブル時の対処法まで含めて知識を深めたい方
2. Dockerfileの基本構成
Dockerfileとは何か?その役割を理解しよう
Dockerfileは、Dockerイメージを作成するためのレシピのようなものです。具体的には、どのベースOSを使い、どのようなソフトウェアをインストールし、どんな設定を行うのかを記述するテキストファイルです。
このファイルをもとに、docker build
コマンドを実行することで、再現性の高い開発環境やアプリケーション実行環境を簡単に構築できます。
Dockerfileを使用するメリット:
- 環境構築の自動化(手作業の再現が不要)
- 複数人での開発時に環境のばらつきがなくなる
- CI/CDパイプラインにも組み込みやすい
Dockerfileでよく使われる基本命令(ディレクティブ)
Dockerfileには複数の命令(ディレクティブ)がありますが、以下が代表的なものです。これらを適切に組み合わせて、UbuntuベースのDockerfileを作っていきます。
命令 | 説明 |
---|---|
FROM | ベースとなるDockerイメージを指定。例:FROM ubuntu:24.04 |
RUN | シェルコマンドを実行。パッケージインストールなどに使用 |
COPY | ローカルのファイルをイメージ内にコピー |
ADD | COPYと似ているが、URLからの取得やアーカイブの展開も可能 |
WORKDIR | 作業ディレクトリを指定 |
ENV | 環境変数を設定 |
CMD | コンテナ起動時に実行されるコマンドを定義(上書き可能) |
ENTRYPOINT | CMDと似ているが、強制的に実行されるコマンドを定義 |
UbuntuベースのDockerfileの最小例
以下は、Ubuntuをベースにしたごく基本的なDockerfileの例です。
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
curl \
vim
CMD ["/bin/bash"]
このDockerfileは、Ubuntu 24.04をベースにして、curl
とvim
という2つのユーティリティをインストールし、最後にbashシェルを起動する構成です。
Ubuntuのタグ選定について
UbuntuのDockerイメージは、Docker Hubの公式リポジトリで公開されています。ubuntu:latest
を指定すると最新のバージョンが使われますが、バージョンを明示的に固定することが推奨されます。
例えば:
ubuntu:22.04
(LTS: 長期サポート版、安定性重視)ubuntu:24.04
(最新のLTS候補、機能重視)
目的に応じて、安定性か新機能のどちらを優先するかを検討しましょう。
3. 実践:UbuntuベースのDockerfile作成
Ubuntu環境に必要なパッケージをインストールする
Dockerfileを使ってUbuntu環境を構築する際、多くの場合は追加のパッケージをインストールする必要があります。例えば、開発環境を整えるには以下のようなユーティリティがよく使用されます:
curl
:ファイル取得やAPI確認用vim
:簡易的なテキストエディタgit
:バージョン管理ツールbuild-essential
:C/C++のビルドに必要な基本ツール群
Dockerfileでこれらをインストールするには、RUN
命令を使います。
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
curl \
vim \
git \
build-essential
apt-get update
を先に実行することで、最新のパッケージリストを取得してからインストールできるようになります。
非対話型インストールの設定
Ubuntuでは、apt-get install
時にユーザー入力が必要になることがありますが、Dockerのビルドプロセスでは対話的な操作ができません。そこで以下のように環境変数を設定し、非対話モードでインストールを行うことが推奨されます。
ENV DEBIAN_FRONTEND=noninteractive
これにより、パッケージの設定時に表示される「地域設定」などの入力をスキップし、スムーズにインストールが進みます。
不要なキャッシュを削除して軽量化する
APTを使用すると、ダウンロードされた一時ファイル(キャッシュ)がイメージ内に残ってしまい、最終的なDockerイメージが重くなります。以下のようにキャッシュを削除することで、イメージサイズを削減できます。
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
このように、複数のコマンドを1つのRUN
文にまとめることで、不要なレイヤーの増加を防ぐこともできます。
ベストプラクティス:Dockerfileの整え方
実際の開発現場では、以下のようなDockerfileの記述に関するベストプラクティスが推奨されています:
RUN
命令は極力まとめて、レイヤー数を減らすENV
で明示的にバージョンや設定を定義する- コメントを使って処理の目的を明記する
- 不要ファイルを残さないように
rm
や--no-install-recommends
を使う
例:
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
このようにすることで、より軽量でメンテナンスしやすいDockerfileを構築できます。
4. Dockerイメージのビルドと確認
DockerfileからDockerイメージをビルドする
Dockerfileを記述したら、次のステップはDockerイメージのビルドです。これは、docker build
コマンドを使用して行います。Dockerfileが存在するディレクトリで、以下のコマンドを実行します。
docker build -t my-ubuntu-image .
-t
オプションはイメージに名前(タグ)を付けるためのものです。例ではmy-ubuntu-image
という名前を付けています。.
はDockerfileが存在するカレントディレクトリを意味します。
このコマンドを実行すると、DockerはDockerfileの命令を順に読み取り、それに従って新しいイメージを構築します。
ビルドしたDockerイメージの確認
イメージの作成が完了したら、次のコマンドで確認できます。
docker images
これにより、ローカルに存在するDockerイメージの一覧が表示され、以下のような情報が確認できます:
- REPOSITORY(イメージ名)
- TAG(タグ)
- IMAGE ID(一意の識別子)
- CREATED(作成日時)
- SIZE(サイズ)
例:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-ubuntu-image latest abcd1234abcd 5 minutes ago 189MB
このように、作成したイメージが正常に登録されていることを確認できます。
Dockerコンテナを起動して動作確認
作成したイメージが正しく機能するかを確認するために、Dockerコンテナを起動してみましょう。以下のようなコマンドを使用します。
docker run -it my-ubuntu-image
-it
オプションを指定することで、インタラクティブモードでターミナルを起動できます。- 正常に起動すれば、コンテナ内のbashプロンプトが表示され、Ubuntu環境にログインしたような状態になります。
コンテナ内部で以下のようなコマンドを実行して、インストールしたツールが正しく動作しているかを確認できます:
curl --version
vim --version
問題なければ、Dockerfileの記述は成功です。
不要になったイメージやコンテナの整理
ビルドや実験を繰り返すと、ローカルに不要なDockerイメージやコンテナが残ってしまうことがあります。定期的に以下のようなコマンドで整理することをおすすめします。
- 停止中のコンテナの削除:
docker container prune
- 未使用イメージの削除:
docker image prune
- すべての未使用データを削除(注意!):
docker system prune
これらの操作により、ディスク容量の節約やトラブル防止につながります。
5. 応用:Python環境の構築
UbuntuベースのDockerfileでPythonを使えるようにする
Dockerfileを使ってUbuntu環境を構築する際、Pythonの実行環境を追加することで、開発・検証・機械学習など幅広い用途に対応できます。UbuntuにはもともとPythonがインストールされていることもありますが、バージョン管理やパッケージ管理の観点から、自分で明示的に構築するのが一般的です。
aptを使ってPythonをインストールする方法
もっともシンプルな方法は、APTパッケージを使ってPythonをインストールすることです。以下はその例です:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
この方法では、システムにインストールされている安定版のPython(通常はPython 3.10や3.12など)が利用できます。加えて、pip
コマンドでPythonパッケージを追加することも可能です。
pyenvでPythonのバージョン管理を行う
特定のPythonバージョンを使用したい場合や、複数バージョンの切り替えを行いたい場合は、pyenvを使うのが便利です。
以下は、Dockerfileでpyenvを使ってPython 3.11.6をインストールする一例です:
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
git \
curl \
make \
build-essential \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
wget \
llvm \
libncurses5-dev \
libncursesw5-dev \
xz-utils \
tk-dev \
libffi-dev \
liblzma-dev \
&& rm -rf /var/lib/apt/lists/*
# pyenvのインストール
RUN git clone https://github.com/pyenv/pyenv.git ~/.pyenv
ENV PYENV_ROOT="$HOME/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"
RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
# 任意のPythonバージョンをインストール
RUN pyenv install 3.11.6 && pyenv global 3.11.6
このようにすることで、より柔軟にPython環境を構築・管理できます。
requirements.txtを使ったパッケージ管理
実際のプロジェクトでは、多くの場合Pythonライブラリが複数必要になります。これを管理するために使われるのがrequirements.txt
です。
まず、プロジェクトのルートディレクトリにrequirements.txt
ファイルを用意します:
flask==2.3.2
requests>=2.25.1
pandas
次にDockerfileで以下のように記述します:
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
これにより、必要なライブラリを一括でインストールすることができ、開発環境の再現性が高まります。
ベストプラクティス
- Pythonを使う場合は、
virtualenv
やvenv
で仮想環境を構築すると、依存関係の衝突を防ぎやすくなります。 - キャッシュ削除(
--no-cache-dir
)を行うことで、Dockerイメージを軽量化できます。 - Pythonパッケージのインストール前に
pip install --upgrade pip
で最新版にしておくとエラーを防げます。
6. よくあるトラブルと対処法
パーミッション(権限)エラー
例:
Permission denied
これは、コピーされたファイルに実行権限がない場合や、スクリプトの所有者・実行ユーザーが適切でない場合に発生します。
対処法:
- ファイルを実行可能にする:
RUN chmod +x script.sh
- 必要に応じて、ユーザーを変更する:
RUN chown root:root /path/to/file
パッケージが見つからない、またはインストールできない
例:
E: Unable to locate package xxx
このエラーは、apt-get update
を実行していない場合や、指定したパッケージ名が間違っている場合に発生します。
対処法:
apt-get update
を必ずinstall
の前に記述する:
RUN apt-get update && apt-get install -y curl
- パッケージ名を確認し、誤字がないかをチェック
ネットワーク関連のエラー
例:
Temporary failure resolving 'deb.debian.org'
このようなエラーは、ビルド中のDNS解決がうまくいかないケースです。
対処法:
- Dockerデーモンの再起動で改善されることがあります:
sudo systemctl restart docker
- DockerのDNS設定を見直す(
/etc/docker/daemon.json
にDNS指定を追加):
{
"dns": ["8.8.8.8", "8.8.4.4"]
}
キャッシュの影響による古い状態のままのビルド
Dockerは高速化のためにレイヤーごとのキャッシュを利用します。その結果、Dockerfileを変更しても意図した通りにビルドされないことがあります。
対処法:
- キャッシュを無効にしてビルドし直す:
docker build --no-cache -t my-image .
コンテナ内での起動コマンドが実行されない・すぐ終了する
原因:
CMD
やENTRYPOINT
で指定したコマンドがエラーになっているCMD
に["/bin/bash"]
などを指定しても、インタラクティブでないとすぐ終了する
対処法:
- コンテナをデバッグ用に起動して確認:
docker run -it my-image /bin/bash
CMD
とENTRYPOINT
の違いを理解し、目的に応じて使い分ける
これらのトラブルを経験することで、Dockerfileの設計力は確実に向上していきます。トラブルに出会ったときは、エラーメッセージを冷静に読み取り、どのレイヤー・どの命令が原因なのかを丁寧に追いかけてみましょう。
7. まとめ
UbuntuベースのDockerfile作成のポイントを再確認
この記事では、Dockerfileを使ってUbuntu環境を構築する方法について、基本から応用まで段階的に解説してきました。ここで改めて、重要なポイントを整理しておきましょう。
- Dockerfileの基本構成を理解することが第一歩
FROM
,RUN
,CMD
,ENV
などの命令を組み合わせて環境構築を自動化できます。 - Ubuntuは安定性・柔軟性の高いベースイメージ
豊富なパッケージ、広いユーザー層、LTSバージョンの存在により、開発環境の基盤として適しています。 - 実践的なパッケージ管理を通じて、必要なツールやライブラリをインストール可能
apt-get
の使い方やキャッシュの削除、非対話型インストールなどが鍵になります。 - Pythonのような実用的な環境構築もDockerfileで可能
pyenv
やpip
、requirements.txt
といったツールで、再現性の高い開発環境を実現できます。 - トラブル対応力が安定した運用に直結する
パーミッションやネットワーク、ビルドキャッシュなど、つまずきやすいポイントを理解しておくことで、開発効率を大幅に向上できます。
Dockerfile学習の次のステップ
Dockerfileを扱えるようになることで、開発だけでなく、テスト・本番環境へのデプロイなど幅広い用途に対応できるようになります。今後の学習として、以下のトピックに進むと良いでしょう。
- Docker Compose を使った複数コンテナ構成の管理
- CI/CDツール(GitHub Actions、GitLab CIなど) との連携
- Kubernetesなどのコンテナオーケストレーションツールとの連動
公式ドキュメント・参考リンク
8. FAQ(よくある質問)
Q1. DockerfileでUbuntuのバージョンはどれを選べばよいですか?
A1. 基本的には、安定性と長期サポートを重視する場合は LTS(Long Term Support)版 を選ぶのが一般的です。たとえば ubuntu:22.04
や ubuntu:20.04
は多くの開発現場で使われており、5年間のサポート期間があるため安心して利用できます。
一方で、最新のパッケージや言語バージョンを使いたい場合は ubuntu:24.04
のような新しいリリースを選ぶことも可能ですが、事前の検証をおすすめします。
Q2. apt-get install
で「パッケージが見つかりません」と出るのはなぜですか?
A2. もっともよくある原因は、apt-get update
を事前に実行していないことです。パッケージリストを更新せずにインストールを試みると、古いリストのままで該当パッケージが見つからずエラーになります。
正しい記述例:
RUN apt-get update && apt-get install -y curl
また、パッケージ名の誤記や、非推奨となったパッケージ名(例:python
ではなくpython3
)にも注意しましょう。
Q3. Dockerfileで環境変数を設定する方法は?
A3. 環境変数は ENV
命令を使って設定します。これはビルド時およびコンテナ実行時に有効な環境変数になります。
例:
ENV DEBIAN_FRONTEND=noninteractive
これは、APTインストール時の対話的プロンプトを抑制するために使われる典型的な設定です。他にも、アプリケーションの設定やAPIキーなどをDockerfile内で設定する際に活用されます。
Q4. DockerfileでCMD
とENTRYPOINT
の違いは何ですか?
A4. どちらもコンテナ起動時に実行されるコマンドを指定するものですが、使い方と挙動に違いがあります。
項目 | CMD | ENTRYPOINT |
---|---|---|
上書き可能性 | docker run のコマンドで上書き可能 | 基本的に上書きされない(引数扱い) |
用途 | デフォルトの実行コマンドを設定 | 常に実行させたいコマンドを定義 |
例:
CMD ["python3", "app.py"]
# vs
ENTRYPOINT ["python3"]
CMD ["app.py"]
後者の場合、docker run my-image another_script.py
という形で CMD
を引数として渡すことができます。
Q5. Dockerfileを編集したのに変更が反映されません。なぜですか?
A5. Dockerはビルド時にキャッシュを使用するため、Dockerfileに小さな変更を加えてもキャッシュされたレイヤーがそのまま使用されてしまうことがあります。
対処法:
docker build --no-cache -t my-image .
これでキャッシュを使わずに新規ビルドされ、すべての変更が反映されます。