💻

Dockerまとめ

に公開

Dockerについてまとめ。

Docker


何が嬉しいのか?

  1. 環境構築が圧倒的に簡単になる
  • Dockerfile や docker-compose を使えば、数行の設定だけで環境構築完了。
  • 開発環境・本番環境で「動く・動かない」の差異が激減。
  • 他の人が同じ環境を数秒で再現可能。

例:pythonのバージョン違いで動かない…→ Dockerなら FROM python:3.10 でバージョン固定できる

  1. アプリケーションを「パッケージ化」できる
  • アプリ+ライブラリ+設定ファイルをまとめて「コンテナ」として管理。
  • 再現性が高く、再利用が簡単。
  1. どこでも同じように動く(移植性)
  • Mac、Windows、Linux のどこでも、同じコンテナが動く。
  • クラウド(AWS, GCP, Azure)でも同様に動かせる。
  1. 不要になったらすぐ捨てられる(使い捨て環境)
  • docker run → 実験 → docker rm でクリーンな環境がすぐ作れる。
  • 環境を壊してもすぐやり直せる。
  1. チーム開発がスムーズになる
  • 「環境差異が原因のバグ」が激減。
  • 誰かが作った Dockerfile を共有するだけで、全員が同じ環境で開発可能
  1. 本番運用・CI/CDにも強い
  • DevOps、CI/CD(継続的インテグレーション)の自動化で多用されている。
  • Kubernetes(K8s)との連携で本格的なスケール運用も可能。
  1. 複数バージョンや構成の検証が容易
    複数のコンテナを同時実行できる。
    例: 「Python 3.8 と 3.10 で挙動が違う」→ Dockerで両方の環境を即構築。

Dockerのメリットまとめ

項目 説明
環境構築の簡略化 数行で完了、他人と共有も簡単
再現性・移植性 どこでも同じように動く
パッケージ化 アプリ+環境をまとめられる
クリーンな実験環境 すぐに作って壊せる
チーム開発に最適 環境のばらつきが減る
CI/CDや本番対応 DevOpsに強い、Kubernetes対応

構造

MacOS, Windows, Linuxなど異なるOSにも同じ実行環境を用意できる。

Dockerの「本来の動作環境」がLinuxなので、現在は裏側で自動的にLinux仮想マシンが使われている。
チャーハンで例えた解説。

用語

  • コンテナ:アプリケーションとその実行に必要な環境をまとめて「軽量に隔離」して動かす仕組み(=「アプリの実行パッケージ」)
  • イメージ:コンテナに必要なソフトウェア・環境変数・設定などが入っているコンテナの型になるもの。イメージを持ち運び、起動することで、どこでも同じコンテナ環境が構築できる。
  • TAG:イメージのバージョンを表す。

ライフサイクル

1. イメージの入手

  • Docker fileからイメージを作成。
  • イメージレジストリ(Docker Hubなど)からダウンロードする。

のいずれかによってイメージを入手する。

2. イメージの実行

イメージを使ってコンテナを作成する。
ここで作られるコンテナ上で実行することでによってOSに関わらず共通の環境で作業ができる。
コンテナは作成後はcreatedという状態。その後起動をするとupという状態になり、実行したいコマンドが終了するとexitという状態になり、再度upすることや破棄することが可能。
例えば、hello-worldを実行すると、commandの/helloが実行される。

コマンド

イメージの入手

  • Docker fileからイメージを作成することでイメージを入手する方法。
    プロジェクトでは、Githubに置いておいたDockerfileを使う。
操作 内容
docker image build {ディレクトリパス} Dockerfileからイメージを作成するコマンド。基本的にはDockerfileが保存されているディレクトリを指定。
docker image build -t {リポジトリ命名}:{Tag命名} {ディレクトリパス} イメージの名前とTag名をつけられる。
  • イメージレジストリからダウンロードすることでイメージを入手する方法。
操作 内容
docker image pull {イメージ名} イメージをダウンロードするコマンド

基本操作

操作 内容
docker image ls ローカルマシンに存在するイメージ一覧を表示するコマンド
docker image rm {イメージ名} ローカルマシンに存在するイメージを削除するコマンド
docker container run {イメージ名} イメージからコンテナを作成し、起動するコマンド
docker container ls ローカルマシンに存在するコンテナ一覧を表示するコマンド(-aをつけると起動していないものも表示される。)
docker ps -a 全コンテナ確認
docker container stop {コンテナ名} 起動中のコンテナを止めるコマンド
docker container restart {コンテナ名} コンテナを再起動する(upにする)コマンド
docker container rm {コンテナ名} コンテナを破棄するコマンド※
docker image inspect {イメージ名} イメージの詳細情報を表示するコマンド
docker container run {イメージ名} {実行したいコマンド名} コンテナを起動して任意のコマンドを実行させるコマンド
docker container exec {コンテナ名} {実行したいコマンド名} Up中のコンテナに任意のコマンドを実行させるコマンド
docker container prune 停止中のコンテナを全て削除するコマンド

※実行中のコンテナは破棄することができないからストップしてから行う。
-it:-i, -tを合わせたもの。-iにより標準入力がターミナルに対してオープンになる。-tにより実行結果を綺麗に表示する。
--name:コンテナに名前をつけることができる。
--rm:実行されたら直ちにコンテナを削除する。
-f:Upになっているコンテナも強制的に削除する。
-d:detatchedモード。バックグラウンドで実行されている状態になる。処理を常駐させたい場合などに用いる。docker container attatch {コンテナ名}によって再びアクセスできる。

Dockerfile

例:

# ベースイメージ
FROM python:3.11-slim
# 作業ディレクトリの作成
WORKDIR /app
# 依存ファイルをコピーしてインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# コードをコピー
COPY . .
# 起動コマンド(uvicornでAPI起動)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

.dockerignoreファイルによってCOPYしないファイルを指定できる。
隠しファイルはls -laで確認できる。

操作 内容
CMD ["実行ファイル", "パラメータ1", "パラメータ2"] コンテナ実行時のデフォルトコマンド。Dockerfileで一度しか使えない
COPY {追加元(ホスト上)}{追加先(コンテナ内)} 好きなファイルをイメージに配置するコマンド
ENV {キー1}={値1} {キー2}={値2} 環境変数を設定する
ARG {キー1}={デフォルト値} イメージ作成時のみに利用する変数を渡す
WORKDIR {ディレクトリパス} RUNやCMDなどの作業ディレクトリを指定する(未設定時は、"/"が作業ディレクトリになっている)

docker image build --build-arg message="Hello Message"

Docker Compose

各コンテナは、元になっているイメージに記述された動作を実行する。
プロジェクトを進める上で、大抵webやappなど機能によってそれぞれコンテナを用意する。それら複数のコンテナを同時実行することで競合することなくスムーズに全体を動作させることができる。
各コンテナを統括して実行することができるのが、docker-composeである。
複数のコンテナの機能の実行を一つのファイルdocker-compose.ymlに記述することで、一括で実行することができる。
docker compose upで実行。
--buildによって更新。
docker compose downで終了。

全体の構成例


手順のおさらい

✅ Step 1: Docker をインストールする

■ Macの場合

  1. 公式サイトにアクセス
  2. 「Docker Desktop for Mac」をダウンロード
  3. .dmg ファイルを開いてインストール
  4. 初回起動後、Apple ID認証や設定許可を求められる場合あり

■ Windowsの場合

  1. 同じく公式サイトで「Docker Desktop for Windows」をダウンロード
  2. .exe を実行してインストール
  3. WSL 2 が必要(自動で案内あり)

■ Linuxの場合(Ubuntu 例)

sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker

補足: sudo usermod -aG docker $USER を実行すると、再ログイン後 sudo なしで使えるようになる。


✅ Step 2: Docker が動くか確認する

docker --version
docker run hello-world

Hello from Docker! が表示されれば成功。


✅ Step 3: 基本コマンドを覚える

コマンド例 内容
イメージ取得 docker pull ubuntu
コンテナ起動 docker run -it ubuntu bash
起動中の確認 docker ps
全コンテナ確認 docker ps -a
停止 docker stop <container_id>
削除 docker rm <container_id>

✅ Step 4: Dockerfile を使って独自環境を作る

例: Dockerfile

# ベースイメージ
FROM python:3.11-slim
# 作業ディレクトリの作成
WORKDIR /app
# 依存ファイルをコピーしてインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# アプリコードをコピー
COPY . .
# 起動コマンド(uvicornでAPI起動)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

ビルドと実行:

docker build -t my-python-app .
docker run my-python-app

✅ Step 5: docker-compose(複数サービスの定義)で全体を統括

docker-compose.yml 例(Web+DB):

version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: example

実行:

docker-compose up



---↑一旦ここまででいいはず!---




マルチステージビルド

マルチステージビルドを使うと、一つのDockerファイルでステージごとの環境を分離し、必要なイメージだけを作れる。
また、開発環境と本番環境をイメージで分けることができる。

実行例

FROM gcc:12.2.0 AS compiler
WORKDIR /app
COPY ./hello.c .
RUN gcc hello.c

FROM ubuntu:20.04
WORKDIR /app
COPY --from=compiler /app/a.out . # ↑0番目のFROMからCOPYする指示
CDM ["./a.out"]

本番環境を分ける。
docker image build --target development .で実行。

FROM ubuntu:20.04 AS base # 共通処理
RUN apt update
CMD ["sh", "-c", "echo My name is $my_name"]

FROM base AS development
ENV my_name=TEST # Dev -> TEST

FROM base AS production
ENV my_name=Bob # Prod -> Bob

Dockerとストレージ

コンテナのデータを永続化する方法は2種類

  • ボリューム
  • バインドマウント

ボリューム領域

Dockerが管理しているデータ領域。各コンテナから接続することができる。複数のコンテナから同時に接続することも可能。

操作 内容
docker volume create {ボリューム名} 新しいボリューム領域を作成する
docker volume ls ボリューム領域一覧を表示する
docker volume inspect {ボリューム名} 指定したボリューム領域の詳細情報を表示する
docker volume rm {ボリューム名} 指定したボリューム領域を削除する
docker container run -v {ボリューム名}:{コンテナ内絶対パス}{イメージ} ボリュームに接続しながらコンテナを起動する
docker container run --mount type=volume src={ボリューム名}, dst={コンテナ内絶対パス}{イメージ} ボリュームに接続しながらコンテナを起動する

ただし、Dockerが管理するボリューム領域にホストから直接アクセスすることはできない。

バインドマウント

ローカルマシン側の任意のディレクトリとコンテナ側の任意のディレクトリを同期させる方法。

操作 内容
docker container run -v {ホスト絶対パス}:{コンテナ内絶対パス}{イメージ} バインドマウントしながらコンテナを起動する
docker container run --mount type=bind src={ホスト絶対パス}, dst={コンテナ内絶対パス}{イメージ} バインドマウントしながらコンテナを起動する

コンテナの接続

ホストとコンテナのポートを紐づける

操作 内容
docker container run -p {ホスト側のポート}:{コンテナ側のポート}{イメージ} -pによっって、ホストマシンのポートをコンテナのポートに紐づける
docker container run -p {ホスト側のポート}:{コンテナ側のポート}{イメージ} -pによっって、ホストマシンのポートをコンテナのポートに紐づける

http://localhost:3000:ホストマシンが自分自身に対してアクセスするときに使われる。

Dockerネットワーク

コンテナ同士の通信を簡単にしたり、不要なコンテナ同士の通信を防ぐために隔離したりできる。

操作 内容
docker network ls ネットワークの一覧を表示する
docker network inspect {ネットワーク} ネットワークの詳細情報を表示する
docker network create {ネットワーク} 新しいネットワークを作成する
docker container run --network {ネットワーク} {イメージ} 指定したネットワークに接続したコンテナを起動する
docker network rm {ネットワーク} ネットワークを削除する

ブリッジネットワーク:複数のコンテナ同士の通信を橋渡しする。何も指定しなければbridgeというブリッジネットワークに新規作成したコンテナが入る。
ブリッジネットワーク内での通信に関しては、コンテナ名とIPアドレスを紐づけてくれるため、名前解決ができる。

ソフトウェアの開発の流れ

-開発環境構築->開発->コミット->|ビルド->テスト->|デプロイ
実装開発|CI(Continuous Integration)|CD(Continuous Deploy)
コミット以外ではDockerを使う。
VS Code, Github, Github actions(CI, CD), AWS

Dev Container

Dev Containers:VS Codeから直接Docker Composerで立ち上げたコンテナに入ってそのコードの編集ができる。
Remote Developmemt:いくつかの拡張機能がパックになったもの。コンテナに接続して、その環境でVSCodeを使った開発を可能にするツール。各コンテナごとにVSCodeをインストールして分離して管理できる。
コンテナを作るディレクトリの中で(例:API)、.devcontainerというフォルダを作る。その中にdevcontainer.jsonを作る。

{
  "name": "api-container", # 名前
  "service": "api", # Docker-composefileで指定したサービス名
  "workspaceFolder": "/workspace", # コンテナの方のワークスペースフォルダ
  "dockerComposeFile": "../../docker-compose.yml", # このcomposeを作るためのファイルは何か
  "customizations": { # 拡張機能をコンテナごとに管理
    "vscode": {
      "extensions": [
        "vscjava.vscode-spring-initializr",
        "pivotal.vscode-spring-boot",
        "pivotal.vscode-boot-dev-pack",
        "vscjava.vscode-spring-boot-dashboard",
        "vscjava.vscode-java-pack"
      ]
    }
  }
}

開く

拡張機能でDockerをインストール。Dockerfileの編集に便利。
Remote Developmemtもインストール。

  1. VSCodeの左下><からOpen Folder in Containerをクリック。
  2. コンテナフォルダ(例:api, web)を開く。
  3. 作業

開発環境と本番環境

WebディレクトリのDockerfileにて

FROM node:18 AS base
CDM ["bash"]

# Build
FROM base AS build
COPY . /workspace
WORKDIR /workspace
ARG REACT_APP_API_SERVER
RUN npm ci && npm run build

# Hostingg in nginx
FROM nginx:latest AS production
COPY --from=build /workspace/build /var/www
COPY nginx.comf /etc/nginx/conf.d/default.comf

AWS

AWS IAM(Identity and Access Management):AWS(Amazon Web Services)上のユーザーやサービスに対して「誰が」「どのリソースに」「どのような操作を許可するか」を管理するためのサービス。
AWS ECR(Elastic Container Registry):Dockerコンテナイメージを安全に保存・管理・配布するためのフルマネージドなコンテナレジストリサービス。
AWS ECS(Elastic Container Service):コンテナを実行・管理するためのフルマネージドサービス。

Github actions

CICDを実行するためのサービス。
ディレクトリで.githubというフォルダを作る。その中にさらにworkflowsというフォルダを作りその中にmain.ymlというファイルを置き、そこに記述していく。

name: Deploy Sinple CI/CD

on:
  push:
    branches: ["main"]

env:
  AWS_REGION: us-west-2
  ECS_SERVICE: simple-cicd-service
  ECS_CLUSTER: simple-cicd-cluster
  ECS_TASK_DEFINITION: .aws/task-definition.json

permission:
  contents: read

jobs:
  Web Container Build/Test

Discussion