「イメージとコンテナって何が違うの?」で止まっている方へ。Dockerを"最低限動かす"ところまでを実務目線で整理しました。用語の地図から、既存イメージの起動、自作アプリのイメージ化、docker compose、AWS ECRへのpushまで、コピペで試せる断片と早見表を用意しています。

01なぜコンテナ? — 「どこでも同じに動く」を軽量に

「自分の PC では動くのに、サーバに載せたら動かない」。原因の多くは、OS・ライブラリ・言語のバージョンといった環境の差です。コンテナは、アプリと「それが動くのに必要なもの一式(依存関係)」をまとめて箱に詰め、どの環境でも同じ状態で動かす仕組みです。

よく比較されるのが仮想マシン(VM)です。VM は App ごとに OS(Guest OS)を丸ごと積むため重く、起動も分単位。コンテナはホスト OS のカーネルを共有し、その上でプロセスを隔離して動かすため軽く、起動は秒単位です。

仮想マシン(VM) コンテナ App App App Guest OS Guest OS Guest OS ハイパーバイザ ホスト OS 物理サーバ / インフラ App App App コンテナランタイム(Docker Engine) ホスト OS(共有) 物理サーバ / インフラ OS を丸ごと抱える → 重い・起動は分単位 OS を共有し薄い層だけ → 軽い・起動は秒単位
VM は App ごとに Guest OS を積むのに対し、コンテナはホスト OS を共有して「アプリ+依存関係」だけを包む。だから軽く、速く、同じように動く。
現場のコツ:コンテナは万能ではありません。GUI アプリや、カーネルを直接いじる用途、状態を持つ重いデータベースを無理にコンテナ化するより、マネージドサービスに任せた方が楽なこともあります。「何でもコンテナ」ではなく「向いているものから」で十分です。基礎から固めたい方はクラウドエンジニアの教科書もあわせてどうぞ。

02用語の地図 — まずこの7語だけ

最初のつまずきは、だいたい用語です。細かい定義は後回しで、次の対応関係だけ押さえれば読み書きできます。

用語これは何かひとことで
イメージ (image)アプリ+依存関係を固めた「設計図・ひな形」。読み取り専用料理のレシピ
コンテナ (container)イメージから起動した「実行中の実体」。何個でも作れるレシピで作った料理
レジストリ (registry)イメージを保管・共有する場所。Docker Hub や Amazon ECRレシピの本棚
Dockerfileイメージの作り方を書いたテキストの手順書レシピの書き方
レイヤ (layer)イメージを構成する差分の積み重ね。命令ごとにできてキャッシュされるミルフィーユ
ボリューム (volume)コンテナを消しても残る永続データの置き場外付け倉庫
ネットワーク (network)コンテナ同士を繋ぐ仮想ネットワーク。名前で解決できる内線電話
イメージとコンテナの違いが最重要です。「1つのイメージ(レシピ)から、コンテナ(料理)は何個でも作れる」。この一文がしっくり来れば、この記事の8割は理解できています。

03最小操作 — 8個のコマンドで一巡する

Docker Desktop などをインストールすれば、次のコマンドだけで「起動→確認→中に入る→止める→消す」が一巡します。まずは丸ごとコピペで手を動かしてみてください。

docker run -d --name web -p 8080:80 nginx   # イメージからコンテナを起動(-d=バックグラウンド)
docker ps                                    # 起動中のコンテナ一覧(-a を付けると停止中も表示)
docker images                                # ローカルにあるイメージ一覧
docker logs -f web                           # ログを追いかける(-f=follow、Ctrl+C で抜ける)
docker exec -it web sh                        # 動いているコンテナの中に入る(対話シェル)
docker stop web                              # コンテナを止める
docker rm web                                # 止めたコンテナを削除する
docker pull nginx:1.27                        # イメージだけ取得しておく(起動はしない)
現場のコツ:迷ったら docker ps -a で「今どんなコンテナが居るか」を確認する癖を付けると、状態を見失いません。

04ユースケース1:既存イメージをそのまま動かす

一番多い使い方が「公開されているイメージをそのまま動かす」です。Web サーバやデータベースは、自分で作らずに公式イメージを使うのが基本です。

# nginx を 8080 番で公開する(-p ホスト側:コンテナ側)
docker run -d -p 8080:80 --name web nginx
# → ブラウザで http://localhost:8080 が開けば成功

# 環境変数を渡し(-e)、データを永続化する(-v):PostgreSQL の例
docker run -d --name db \
  -e POSTGRES_PASSWORD=YOUR_PASSWORD \
  -e POSTGRES_DB=appdb \
  -p 5432:5432 \
  -v pgdata:/var/lib/postgresql/data \
  postgres:16
現場のコツ:-e POSTGRES_PASSWORD=... に本物のパスワードを直書きしたコマンドは、シェル履歴やログに残ります。実運用では .env ファイルやシークレット管理(AWS なら Secrets Manager/SSM パラメータストア)を使い、リポジトリには絶対にコミットしないでください。

05ユースケース2:自分のアプリをイメージ化する

自作アプリを配れる形にするには、Dockerfile に「作り方」を書いてイメージ化します。命令は上から順にレイヤとして積まれます。

# Dockerfile(Node アプリの例)
FROM node:20-slim          # 1) 土台にするベースイメージ
WORKDIR /app               # 2) 作業ディレクトリ(無ければ作られる)
COPY package*.json ./      # 3) 依存定義だけ先にコピー(キャッシュを効かせる)
RUN npm ci --omit=dev      # 4) 依存をインストール(ビルド時に実行)
COPY . .                   # 5) 残りのソースをコピー
EXPOSE 3000                # 6) 使うポートの明示(ドキュメント目的)
CMD ["node", "server.js"]  # 7) 起動時に実行する既定コマンド

ビルドして動かします。-t は名前とタグ、末尾の . は「今のディレクトリをビルド文脈にする」意味です。

docker build -t app:1.0 .        # イメージを app:1.0 として作る
docker run -d -p 3000:3000 app:1.0

イメージに入れる必要のないものは .dockerignore で除外します。これだけでビルドは速く、イメージは小さく、事故も減ります。

# .dockerignore(イメージに含めないもの)
node_modules
.git
.env
*.log
現場のコツ:COPY package*.jsonRUN npm ciCOPY . . の順番がポイントです。依存が変わらなければ 3〜4行目のレイヤはキャッシュが再利用され、ソースを直すたびに毎回インストールが走るのを防げます。

06ユースケース3:複数コンテナを compose でまとめる

「web と db を毎回2回 docker run する」のは面倒です。compose.yaml に構成を書けば、一発で立ち上げ・停止できます。ローカル開発環境の定番です。

# compose.yaml(web + db の最小構成)
services:
  web:
    build: .                 # 同じ場所の Dockerfile からビルド
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://app:YOUR_PASSWORD@db:5432/appdb
    depends_on:
      - db                   # db を先に起動
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: YOUR_PASSWORD
      POSTGRES_DB: appdb
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:                    # 名前付きボリュームの宣言
docker compose up -d       # 定義したサービスをまとめて起動
docker compose logs -f     # 全サービスのログをまとめて追う
docker compose down        # まとめて停止・削除(-v を付けるとボリュームも消える)

07ユースケース4:AWS へ — ECR に push して動かす

作ったイメージを AWS で動かすには、まず Amazon ECR(AWS のプライベートなイメージ置き場)に push します。手順は「ログイン → タグ付け → push」の3ステップです。

# 0) 変数(自分の値に置き換え。ACCOUNT は12桁のAWSアカウントID)
ACCOUNT=123456789012
REGION=ap-northeast-1
REPO=myapp
REGISTRY=$ACCOUNT.dkr.ecr.$REGION.amazonaws.com

# 1) ECR にログイン(発行されるトークンは12時間有効)
aws ecr get-login-password --region $REGION \
  | docker login --username AWS --password-stdin $REGISTRY

# 2) リポジトリを作成(初回のみ)
aws ecr create-repository --repository-name $REPO --region $REGION

# 3) ローカルイメージに ECR 用のタグを付ける
docker tag app:1.0 $REGISTRY/$REPO:1.0

# 4) push する
docker push $REGISTRY/$REPO:1.0

レジストリの URL は必ず <aws_account_id>.dkr.ecr.<region>.amazonaws.com の形です(例:123456789012.dkr.ecr.ap-northeast-1.amazonaws.com)。ここがタグと1文字でもずれると push は通りません。

push したイメージを実際に動かす受け皿は、用途で選びます。

サービス位置づけ向いている場面
Amazon ECSコンテナのオーケストレーション。「どこで・何個・どう配置するか」を管理する複数コンテナを本番で継続運用したいとき
AWS Fargateサーバ(EC2)を管理せずコンテナを動かす実行基盤。ECS/EKS と組み合わせて使うサーバの面倒を見たくない・素早く始めたいとき
AWS App Runnerソースやイメージから直接 Web アプリを公開できるマネージド。2026年時点で新規顧客の受付は終了(既存顧客のみ継続利用可)新規は ECS + Fargate を軸に検討
まず試すなら ECS on Fargate が扱いやすい選択肢です。サーバの管理が要らず、タスク定義に「どのイメージを・どれくらいのCPU/メモリで動かすか」を書くだけで起動できます。AWS CLI での操作(プロファイル設定や ECR コマンド)はAWS CLI 実践リファレンスに、各サービスのオンプレ/他クラウド対応はAWS・Azure・GCP・オンプレ対応表にまとめています。

08つまずきポイントと事故らないコツ

# root を避ける:専用ユーザーを作って切り替える
RUN useradd -m appuser
USER appuser

# ビルド時にプラットフォームを固定する(Apple Silicon → x86 本番向け)
docker build --platform linux/amd64 -t app:1.0 .
現場のコツ:秘密情報は「イメージに入れない」が鉄則です。実行時に環境変数や AWS の Secrets Manager/SSM パラメータストアから渡し、認証情報・鍵・.env は Git にもイメージにもコミットしないこと。うっかり COPY . ..env ごと入ってしまう事故は .dockerignore で防げます。

09早見表 — コマンド逆引き+Dockerfile命令

やりたいことからコマンドを引く逆引き表です。まずはここだけブックマークすれば十分に戦えます。

やりたいことコマンド
イメージから起動するdocker run -d -p 8080:80 nginx
動いている一覧を見るdocker ps-a で停止中も)
ログを見るdocker logs -f <名前>
コンテナの中に入るdocker exec -it <名前> sh
止める / 消すdocker stop <名前>docker rm <名前>
イメージを作るdocker build -t app:1.0 .
不要物を掃除するdocker system prune(未使用を一括削除)
複数まとめて起動docker compose up -d
まとめて停止・削除docker compose down
ECR にログインaws ecr get-login-password ... | docker login ...

Dockerfile の主な命令もまとめておきます。この9個で大半のイメージは書けます。

命令役割
FROM土台にするベースイメージを指定FROM python:3.12-slim
WORKDIR作業ディレクトリを設定(無ければ作成)WORKDIR /app
COPYホストからイメージへファイルをコピーCOPY . .
RUNビルド時にコマンドを実行(レイヤになる)RUN pip install -r requirements.txt
CMD起動時に実行する既定コマンドCMD ["python","app.py"]
ENTRYPOINT常に実行する固定コマンドENTRYPOINT ["/entry.sh"]
EXPOSE使うポートの明示(ドキュメント目的)EXPOSE 8000
ENV環境変数を設定ENV TZ=Asia/Tokyo
USER実行ユーザーを切り替えUSER appuser
シリーズ内の関連記事AWS CLI 実践リファレンス(ECR やプロファイル操作)/jq 実践リファレンスdocker inspect の JSON 整形)/curl 実践リファレンス(コンテナの疎通確認)。基礎はクラウドエンジニアの教科書へ。
現場のコツ:未経験からクラウドやコンテナを学びたい方へ。EMW(札幌)は「基礎を積む姿勢」を大切にする仲間を募集しています。採用情報・カジュアル面談はこちら

10よくある質問(FAQ)

docker と docker compose の使い分けは?

単発のコンテナは docker run、web+db のように複数コンテナを毎回まとめて起動したいときは compose.yaml に書いて docker compose up が基本です。compose はローカル開発環境の再現に向いています。本番のオーケストレーションは Amazon ECS などに任せる、という住み分けが一般的です。

latest タグを使ってはいけないのですか?

とりあえず動かすだけなら便利ですが、latest は「その時点の最新」を指すため中身が知らないうちに変わり、「昨日は動いたのに」が起きやすくなります。本番や共有環境では 1.0 や Git のコミットハッシュなど固定タグを付け、再現性を確保するのがおすすめです。

イメージが大きくなりすぎます。どう小さくしますか?

定石は4つです。(1) slimalpine 系の軽いベースイメージを使う、(2) .dockerignorenode_modules.git を除外する、(3) RUN をまとめてレイヤ数を減らす、(4) マルチステージビルドでビルド用の道具を捨て、成果物だけ最終イメージに残す、です。

ECR に push できません(denied と出ます)。

多くは認証切れです。ログイントークンは12時間で失効するので、aws ecr get-login-password ... | docker login ... をやり直してください。加えて、リージョン・アカウントID・リポジトリ名がタグ(<acct>.dkr.ecr.<region>.amazonaws.com/<repo>)と一致しているか、対象リポジトリへの IAM 権限があるかも確認します。

Dockerからコンテナ運用、ECS/FargateでのAWS本番展開まで、EMWは札幌から伴走しています。「基礎からコンテナを学びたい」「自社の構成をどう載せ替えるか相談したい」——そんな方はお気軽にどうぞ。

相談する
← ブログ一覧へ戻る