【Docker超入門②】イメージ・コンテナ・Dockerfileを完全理解する
はじめに
前回は、Dockerとは何か、仮想マシンとの違いについて学びました。
今回は、Dockerを使う上で最も重要な概念である「イメージ」と「コンテナ」について深掘りしていきます。
実際にコマンドを叩きながら、手を動かして理解していきます!
シリーズ構成:
- 第1弾:Dockerって何がすごいの?
- 第2弾(この記事):イメージ・コンテナ・Dockerfileを完全理解する
- 第3弾:docker-composeでPython + PostgreSQLを連携させる
1. イメージ = 設計図、コンテナ = 実体
イメージとは
作りたい環境をパッと作るための設計書のようなものです。
たとえばPythonで
import anthropic
import matplotlib
とかよく見るじゃないですか。
でもこれらのライブラリって、事前にインストールしておかないと使えないものです。
個々人の環境でライブラリがインストール済みかどうか、なんてわかんないじゃないですか。しかもライブラリのバージョンも違ったりするし。
そこで、開発者と同じ環境を「イメージ」として保存しておくわけです。
配られた側は、このイメージをもとに実際の環境構築を行っていくことになります。
コンテナとは
イメージ(設計図)から実際に作られた実体です。
| 概念 | 例え | 説明 |
|---|---|---|
| イメージ | 設計図・レシピ | 環境の定義。変更不可(読み取り専用) |
| コンテナ | 建物・料理 | イメージから作られた実体。動かせる |
1つのイメージから、複数のコンテナを作ることができます。
2. 基本コマンドを叩いてみる
Dockerには色んなコマンドがあります。代表的なものを叩いてみましょう!
コマンド一覧
| コマンド | 説明 |
|---|---|
docker pull |
Docker Hubからイメージを取得 |
docker run |
イメージからコンテナを作成・起動 |
docker ps |
起動中のコンテナを一覧表示 |
docker stop |
コンテナを停止 |
docker rm |
コンテナを削除 |
Docker Hubとは?
Docker Hubは、いろんな企業や有志が有用なDockerイメージをアップロードしてくれているサイトです。
nginx、Python、PostgreSQL、MySQL、Node.js... なんでもあります!
3. Docker Hubで遊んでみる
3-1. nginxを動かす
まずはWebサーバーのnginxを動かしてみましょう。
docker pull nginx
docker run -d -p 8080:80 nginx
オプションの意味:
-
-d:バックグラウンドで実行(デタッチモード) -
-p 8080:80:ホストの8080番ポートを、コンテナの80番ポートに紐付け
ブラウザで http://localhost:8080 にアクセスしてみると...
Welcome to nginx! と表示されれば成功です!
起動中のコンテナを確認
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxxxxxxxxxxx nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp fervent_archimedes
nginxで表示されてるので、これもOKそう!
(個人情報はかくしました)
名前を指定せずにrunすると、勝手に名前を付けられます。私はなんとかアルキメデスっていう名前つけられてました...
コンテナを停止
docker stop fervent_archimedes
(または docker stop コンテナID でもOK)
ちゃんとコンテナは毎回止めましょうね。
3-2. PostgreSQLを動かす
では、データベースのPostgreSQLもやってみましょう。
docker pull postgres
docker run -d -p 5432:5432 --name my-postgres -e POSTGRES_PASSWORD=password postgres
オプションの意味:
-
--name my-postgres:コンテナに名前をつける -
-e POSTGRES_PASSWORD=password:環境変数を設定(PostgreSQLは起動時にパスワード必須)
コンテナの中に入ってSQLを叩く
docker exec -it my-postgres psql -U postgres
オプションの意味:
-
exec:起動中のコンテナでコマンドを実行 -
-it:インタラクティブモード(対話的に操作できる) -
psql -U postgres:postgresユーザーでpsqlを起動
プロンプトが postgres=# になればOK!
テーブルを作ってみる
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO users (name, email) VALUES
('田中太郎', 'tanaka@example.com'),
('佐藤花子', 'sato@example.com'),
('鈴木一郎', 'suzuki@example.com');
SELECT * FROM users;
id | name | email | created_at
----+------------+--------------------+----------------------------
1 | 田中太郎 | tanaka@example.com | 2024-xx-xx xx:xx:xx.xxxxxx
2 | 佐藤花子 | sato@example.com | 2024-xx-xx xx:xx:xx.xxxxxx
3 | 鈴木一郎 | suzuki@example.com | 2024-xx-xx xx:xx:xx.xxxxxx
SELECT、できてますね!
後始末
\q
docker stop my-postgres
4. 【重要】stopとrmの違い:データは消える?
ここ、結構大事ポイントらしい。。。
stopしただけならデータは残る
docker start my-postgres
docker exec -it my-postgres psql -U postgres
SELECT * FROM users;
さっき入れたデータ、残ってるんですね。
docker stopは中断しているだけなので、コンテナ内のデータは保持されています。
rmするとデータは消える
docker stop my-postgres
docker rm my-postgres
docker run -d -p 5432:5432 --name my-postgres -e POSTGRES_PASSWORD=password postgres
docker exec -it my-postgres psql -U postgres
SELECT * FROM users;
ERROR: relation "users" does not exist
テーブルごと消えてる!
docker rmでコンテナを削除すると、中のデータは全部消えちゃいます!
データを永続化する方法(Volume)は第3弾で解説します。
5. 自分でDockerfileを書いてみる
Docker Hubのイメージを使うだけでなく、自分でイメージを作ることもできます。
そのために必要なのが「Dockerfile」です。
用意するファイル
① hello.py
import pandas as pd
df = pd.DataFrame({
"name": ["田中", "佐藤", "鈴木"],
"age": [25, 30, 28],
"city": ["東京", "大阪", "名古屋"]
})
print("=== Dockerコンテナから実行中 ===")
print(df)
print(f"\n平均年齢: {df['age'].mean()}歳")
print("Docker動いてるよ!")
② requirements.txt
pandas==2.2.2
③ Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "hello.py"]
Dockerfileの各行を解説
| 命令 | 意味 |
|---|---|
FROM python:3.10-slim |
Python 3.10の軽量版イメージをベースにする |
WORKDIR /app |
コンテナ内の作業ディレクトリを /app に設定 |
COPY requirements.txt . |
requirements.txtをコンテナ内にコピー |
RUN pip install ... |
ライブラリをインストール |
COPY . . |
現在のフォルダの全ファイルをコンテナにコピー |
CMD ["python", "hello.py"] |
コンテナ起動時に実行するコマンド |
フォルダ構成
my-app/
├── Dockerfile
├── requirements.txt
└── hello.py
ビルドして実行!
cd my-app
docker build -t my-pandas-app .
-tはタグ(名前)をつけるオプションです。
一番後ろの . は「今いるフォルダのDockerfileを使うよ!」という意味。
.を忘れるとエラーになります。私もやらかしました...
ビルドできたら実行!
docker run my-pandas-app
=== Dockerコンテナから実行中 ===
name age city
0 田中 25 東京
1 佐藤 30 大阪
2 鈴木 28 名古屋
平均年齢: 27.666666666666668歳
Docker動いてるよ!
動いてるって〜!!最高ですね
補足:コンテナが自動終了する
このあとdocker psを打っても何も出てきません。
このイメージだと、printなどの出力が一通り終わった後はお仕事終了ということで、コンテナが終了します。
Webサーバー(nginx)のようにずっと待ち受ける処理がないと、処理が終わり次第コンテナは停止するんですね。
6. ハマりポイント集
私が実際にハマったポイントをまとめておきます。
① docker build で . を忘れる
docker build -t my-app
# エラー: "docker build" requires exactly 1 argument.
正しくは:
docker build -t my-app .
② コンテナが見つからない
docker ps
# 何も表示されない...
docker psは起動中のコンテナのみ表示します。
停止中も含めて全て見るには:
docker ps -a
③ rmしたらデータが消えた
前述の通り、docker rmでコンテナを削除すると中のデータも消えます。
大事なデータはVolumeで永続化しましょう(第3弾で解説)。
④ ポートが既に使われている
Error: Bind for 0.0.0.0:5432 failed: port is already allocated
同じポートで別のコンテナが動いています。
docker ps
docker stop <該当コンテナ>
まとめ
この記事では、以下のことを学びました:
-
イメージとコンテナの違い
- イメージ = 設計図(読み取り専用)
- コンテナ = 実体(動かせる)
-
基本コマンド
-
pull,run,ps,stop,rm
-
-
Docker Hubで遊ぶ
- nginx、PostgreSQLを動かしてみた
-
Dockerfileを書く
- Python + pandasのアプリを自作
-
ハマりポイント
-
.忘れ、rmでデータ消失など
-
次回
次回は、複数のコンテナを連携させる方法を学びます。
- docker-composeとは
- docker-compose.ymlの書き方
- ボリューム:データを永続化する
- ネットワーク:コンテナ間通信の仕組み
- 実践:CSVをPostgreSQLに投入するパイプライン