0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ちょっとわかった!Docker

Posted at

はじめに

Docker の面白さ・便利さに気づき始めたので、他の人にも伝えるべく記事を書きます。

(2025/03/30 追記)
↓ 超勉強になった本。Docker のホストマシン上での動きが基礎から解説されています。まずこれを読みましょう。
実践 Docker - ソフトウェアエンジニアの「Docker よくわからない」を終わりにする本

docker 単体系コマンド(compose じゃないやつ)

一覧コマンド
# イメージ一覧
docker images
# コンテナ一覧
docker ps
docker ps -a
# 内部一覧
docker image inspect <イメージ名>
docker container inspect <コンテナ名>
docker volume inspect <ボリューム名>
お掃除コマンド
# コンテナ全停止
docker stop $(docker ps -aq)
# イメージ・コンテナ・ボリューム一括全削除(ただし使用中のものは消せない)
docker system prune -a
# イメージ・コンテナ・ボリュームそれぞれ全削除
docker image rm $(docker image ls -aq)
docker container rm $(docker container ls -aq)
docker volume rm $(docker volume ls -q)
# 状態確認
docker system df
コンテナ操作系
# Docker Hub からイメージを持ってくる
docker pull <イメージ名>
docker pull ubuntu:20.04

# 自分でイメージを作成する(Dockerfile と同階層でコマンドを実行)
docker build -t <任意のイメージ名> .
docker build -t my_image .

# イメージのレイヤー(構成要素)を確認
docker history <イメージID>

# イメージからコンテナを起動する(create + start)
docker run <イメージ名>
# ↓ これはすぐ停止状態になる(下のメモ参照)
docker run ubuntu:20.04
# ↓ これは起動状態を維持する
docker run -it ubuntu:20.04 bash
# ↓ これも維持
docker run --name <任意のコンテナ名> -p <任意のホスト側ポート番号>:<任意のコンテナ側ポート番号> <イメージ名>
docker run --name docker-getting-started -p 80:80 docker/getting-started

# コンテナを作るだけ(start待ち)
docker create <イメージ名>
docker create --name my_ubuntu_container ubuntu:20.04

# コンテナを一時停止・再開する
docker stop/start <コンテナ名>
docker start my_ubuntu_container

# 起動状態のコンテナの中に入る
# bash がダメなら sh など試す
docker exec -it <コンテナ名> bash

コンテナが run した瞬間停止状態になる理由
大事なコンテナ原則
・コンテナはメインプロセスを実行するために起動する
・メインプロセスが終了したコンテナは自動で停止する
実践 Docker - ソフトウェアエンジニアの「Docker よくわからない」を終わりにする本より)

具体例として、「docker run ubuntu:20.04」でコンテナ作成&起動はされるが、メインプロセスを指定していないので終了扱いですぐ停止される。
一方「docker run -it ubuntu:20.04 bash」はメインプロセスとして「bash」を指定しているので、私たちがコンテナ内で bash 操作している間は停止しない。bash から exit したらメインプロセス終了で停止される。

nginx イメージとか、ものによってはデフォルトでメインプロセスが指定されているものもあり、そういうのは起動した瞬間停止されることがない。

オプション例
オプション 説明
-d --detach。デタッチモード。コンテナがバックグラウンド実行され、ターミナルはブロックされない
-p --publish。-p 5000:5001なら、ホストの5000番はコンテナ内の5001につながっている
-f --force。起動中のコンテナを、停止を経由せずいきなり消すときに使う
--rm コンテナが停止されたとき自動的にコンテナを削除する
-e 環境変数(例:-e PASSWORD=password)
-v ボリュームの設定(例:-v my-volume:/my-data)
-it --interactive と --tty。コンテナに入るときによく使う
--network 使用ネットワーク指定(例:--network networkname)

Dockerfile と compose.yaml を動かしてみる

全体像はこちらのリポジトリを git clone して、docker compose build と docker compose up をしてご確認ください。

Dockerfile の内容

Dockerfile
# FROM <イメージ名>
FROM node:17-alpine

RUN npm install -g nodemon

# これ以降コンテナ内では /app で作業する
WORKDIR /app

# ローカルの package.json を /app にコピー
COPY package*.json .

# /app で package*.json を参考にパッケージをインストール
RUN npm install

# ローカルのファイルを /app にコピー
COPY . .

# 使うポートを指定(任意)
EXPOSE 4000

# CMD で指定したコマンドは、上記のインストールなどが終わってから実行される
# RUN で指定するとインストール完了を待たずに実行されてしまう
CMD ["npm", "run", "dev"]

compose.yaml の内容

compose.yaml
services:

  backend:
    # .yml ファイルから見て ./api にある Dockerfile をイメージとしてビルド
    build: ./backend
    # コンテナ名
    container_name: backend_c
    # ローカルポート:コンテナポート
    # localhost:4000でコンテナの4000が見られる
    ports:
      - 4000:4000
    volumes:
      # ローカルファイル:コンテナファイル
      # バインドマウントなのでこの2つは連動する
      - ./backend/src:/app/src
    environment:
      # 環境変数は ./backend/src/db.js 内で使っている
      ENV: env_value
      POSTGRES_USER: p_username
      POSTGRES_PASSWORD: p_password
      POSTGRES_DB: p_database
    depends_on:
      # db のコンテナが起動してから backend が起動する
      - db
    links:
      # depends_on とセット?(なくても動くような…)
      - db
  
  frontend:
    build: ./frontend
    container_name: frontend_c
    ports:
      - 3000:3000
    volumes:
      - ./frontend/src:/app/src
    # --interactive
    stdin_open: true
    # --tty
    tty: true
  
  db:
    # Dockerfile からビルドせずイメージ名を直接指定
    image: postgres:latest
    container_name: db_c
    environment:
      POSTGRES_USER: p_username
      POSTGRES_PASSWORD: p_password
      POSTGRES_DB: p_database
    ports:
      - 5432:5432
    volumes:
      # バインドマウント
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
      # ボリュームマウント
      - db_data:/var/lib/postgresql/data
    # コンテナが常に再起動する(なくても動くような…)unless-stopped もある
    restart: always

volumes:
  db_data:

compose.yaml 起動系コマンド

ターミナル
# compose.yaml 起動系コマンド

# 起動準備をする
docker compose build
# 起動する
docker compose up
# 止める
docker compose stop
# 再開する
docker compose start
# 消す
docker compose down

# ファイル名指定(stop/start/down 時もファイル名を指定する)
docker compose -f docker-compose-one.yaml up

Dockerfile その他にできること紹介

Dockerfile その他にできること紹介
RUN apt-get update && \
    apt-get install -y curl && \
    curl -sL https://deb.nodesource.com/setup_18.x | bash - && \
    apt-get upgrade -y && \
    apt-get install -y nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
# ↓ と同じ意味だが、横長で見づらいので「\」で改行する
RUN apt-get update && apt-get install -y curl && curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get upgrade -y && apt-get install -y nodejs && apt-get clean && rm -rf /var/lib/apt/lists/*
# RUN RUN RUN とするとレイヤー数が増えてイメージが大きくなるので && でつないでまとめる
# まとめておくと、2回目以降キャッシュで一部 RUN されない由来のエラーも回避できる

# インストールも「\」で改行できる
RUN apt-get update && apt-get install -y \
  build-essential \
  libpq-dev \
  nodejs \
  postgresql-client \
  yarn

# app ユーザに /app の権限を付与し、root ユーザではなく app ユーザで作業する
RUN addgroup app && adduser -S -G app app
RUN chown -R app:app .
USER app
# root ユーザにも戻せる
USER root

# どちらの書き方でもいい
CMD ["npm", "run", "dev"]
CMD npm run dev

# CMD とどう違うのかわからない…
ENTRYPOINT [ "node", "main.js" ]

# ディレクトリ作成
RUN mkdir -p /home/app

# 環境変数設定
ENV FLASK_APP=app.py \
	FLASK_RUN_HOST=0.0.0.0 \
	FLASK_RUN_PORT=8000

compose.yaml その他にできること紹介

compose.yaml その他にできること紹介
services:  

  service-1:
    # Dockerfile の場所と名前を指定する
    build:
      context: service-1
      dockerfile: Dockerfile.env
      
    # コンテナ内で実行されているサービスが正常に動作しているか定期的に確認
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080"]
      interval: 5s
      retries: 5
      start_period: 15s
      timeout: 5s
    
    # docker compose watch すると指定のファイルに変更があった時 rebuild する
    # 単純に down と up すればいいのでは感も
    develop:
      watch:
        - path: ./service-1/package.json
          action: rebuild
    
    # Dockerfile の CMD や ENTRYPOINT の上書き
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    entrypoint: "/bin/sh -c 'npm install && npm run start'"

    # 使用する .env を指定
    env_file:
      - ./service-1/dev.env

    # 使うネットワークを指定
    networks:
      - coffee

# 使うネットワークを指定
# 普通に build と up すれば自動でネットワーク作成されるので、あえて指定するケースは少ないかも
networks:
  coffee:
    ipam:
      driver: default
      config:
        - subnet: "192.168.92.0/24"

関連:その他の compose.yaml オプション

オプション名 内容
configs:、secrets:、extends: ファイルを指定し、ファイル内の環境変数?を使えるようにする
sync、rebuild、sync+restartなど 調べきれていない
profiles: 調べきれていない

関連:compose.yaml

  • composerizeで docker run コマンドから compose.yaml を作成できる
  • ボリュームマウントのファイルの保存場所は \wsl.localhost のdocker-desctop-data 配下にある(気になる方はこちらのYoutubeを参照)
    Screenshot (244).png

おわりに

Docker に関する知識を整理できてよかったです。
知らないオプション設定がたくさんあるのでまた必要に応じて勉強したい。

参考にさせていただいた記事

0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?