🐳

Dockerの基本をまとめてみた

2022/10/17に公開約10,800字

仕事でDockerを使用することになり、この機会に基本的なことをまとめてみました。

Dockerコンテナとは?

名前の由来は貨物輸送用の「コンテナ」のようです。
このようなコンテナをヒントにしているらしい。
↓こんなやつですね。写真でみるとイメージができて分かりやすかったです。

Dockerコンテナとは、実行環境を他のプロセスから隔離して、その中でアプリケーションを動作させる技術

Dockerとは?

Docker(ドッカー)とは、「コンテナ仮想化」と呼ばれる仮想環境を構築するソフトウェア。
OS内部に独立したアプリケーションのコンテナを生成することができる。

  • コンテナを管理するツール
  • インフラのコード化ができる
  • 存在する場所はメモリ上
  • データは一時的

コンテナの仕組み

  • コンテナはOS(ホストOS)にインストールされた、Dockerなどのソフトウェア上に作成される。
  • 動作させたいアプリをコンテナ上に載せることによって、隔離された仮想サーバーを簡単に作成することが可能。
  • Webサーバーとデータベースを組み合わせる場合は、WebサーバーとWebサーバー上で動作させるプログラムを載せるコンテナと、データペースを載せるコンテナで分けて、2つのコンテナ間で通信をさせることも可能。

コンテナのメリット・デメリット

メリット

  • コンテナは隔離されたプログラムのため、ホストOSを汚さない。
  • 迅速な環境構築が可能
  • どのような環境でも同じように動く
  • 開発からリリースまでが早くスムーズに行える
  • ロールバックが素早くできる
  • laC(Infrastructure as Code)を実現する。(インフラ構築をコードで定義すること。)
  • どんなコンテナを作成するかの手順をまとめたテキストファイルをもとにコンテナを作成できるので、他の人が別のマシンで簡単にコンテナを作ることができる。
  • 可燃性がある。
  • コンテナは、アプリの動作に必要なライブラリや依存関係を含めてパッケージされているので、環境差異による不具合をさけることができる。

デメリット

  • 学習コストが必要
  • コンテナの管理を行うオーケストレーションツールの知識が必要。
  • コンテナはホストOSのカーネルを共有しているため、ホストOSのバージョン差異や互換性の有無によっては、他の環境で動作しない場合もある。

コンテナイメージとは?

  • レイヤー構造になっていて、1番下のベースレイヤーはLinuxOSになっている。
  • コンテナはイメージから作成されるので、コンテナの前段階はイメージになる。
  • 基本的なアプリやソフトウェアに加えて、コンテナを動かすのに必要なファイルシステムや、実行コマンド、メタ情報などが含まれている。
  • コンテナはプロセスなので他の環境に配布することができないが、イメージはファイルの集合体のため、配布が可能。
  • イメージを他の環境に配置すれば同じコンテナを作成できる。
  • コンテナは一つのイメージから複数作成できる。

Docker Hub

レジストリという、イメージが集められた場所がある。
Dockerの場合は、Docker Hub(ドッカーハブ)という公式レジストリが提供されている。

  • レジストリからイメージを取得することを、プル(pull)
  • レジストリにイメージを登録することを、プッシュ(push)

イメージのバージョンはタグ(イメージのバージョンを指定しているもの)から確認できるので、構成や環境に合わせて最適なイメージを選択をする。

イメージをプルするコマンド

docker image pull
タグを指定したい場合(タグ名を指定しない場合は、最新版のイメージがプルされる)
docker image pull イメージ名:タグ名

コンテナのライフサイクル

コンテナの状態をdockerコマンドを使用して変化させていくときの状態の移り変わりを、コンテナのライフサイクルと呼ぶ。

  • 作成
    イメージからコンテナを作成した状態。
  • 実行
    コンテナを動作させた状態
  • 停止
    実行していたコンテナを停止させた状態。
  • 削除
    コンテナを削除した状態。
    再び実行するときは、コンテナを再度作成する必要がある。

コンテナは簡単に削除したり、作成し直すことが可能なため、作成したら削除するのが基本。

Docker Desktopインストール

インストールは公式サイトからできます。
https://www.docker.com/products/docker-desktop/

コンテナの作成

Apacheのコンテナを作成してみる。

docker container runコマンドは、イメージがダウンロードされていない場合、イメージをプルしてからコンテナを作成・実行する。

docker container run --name apache-test -p 8080:80 -d httpd
  • --name
    コンテナに名前を付けるオプション
  • apache-test
    コンテナの名前
  • -p
    ポート番号のオプション
  • 8080:80
    ポート番号
  • httpd
    イメージ名(パラメータ)

ブラウザでhttp://localhost:8080/にアクセスをして、初期画面が表示されれば完了。

作成されたコンテナは、Docker Desktopからも確認することができる。

コンテナの停止

コンテナを停止するときは、docker container stop コンテナ名を使用する。

docker container stop apache-test

コマンド実行後、http://localhost:8080/にアクセスできなくなっていることが確認できます。

コンテナの削除

コンテナを削除するときは、docker container rm コンテナ名を使用する。

docker container rm apache-test

Docker Desctopからコンテナが削除されていることが確認できます。

Docker Compose

複数のコンテナを作成する場合に「docker container」を使用すると、作成したいコンテナの個数分コマンドを実行したり、オプションなども含めると記述が長くなってしまう。
そのため、Docker Compose(ドッカーコンポーズ)というソフトウェアを使用して、コマンドやオプションをファイルにまとめて、コンテナを作成する方法が使われている。

  • Docker Composeとは、一度に複数のコンテナを作成・実行できるソフトウェア。
  • Docker Desktopにデフォルトで同梱されている。
  • Docker Composeの場合のコマンドは、「docker compose」コマンド

Docker Composeは設定ファイル(YAML)が必要

  • どんなコンテナを作成するのかを定義したYAML形式のファイルが必要。
    YAMLファイルにオプションをまとめて記述するので、コマンド実行の際に何度も長いオプションを書く必要がなくなる
  • 複数コンテナの作成だけでなく、ネットワークなどコンテナの動作に必要な機能も一度に作成できる。

Apacheコンテナを作成する場合の記述

compose.yaml
services: # コンテナの定義
  web:  # コンテナの名前
    image: httpd:2.4 # 使用するイメージの名前
    ports: # ポート番号
      - "8080:80"

Docker Composeのバージョン

バージョンはV1V2がある。

V1

  • コマンド:「docker-compose」
  • YAMLファイル名:「docker-compose.yaml」「docker-compose.yml」
    (V2でも利用できるが、「compose.yaml」が推奨されている)

V2

  • コマンド:「docker compose」
  • YAMLファイル名:「compose.yaml」

「compose.yaml」と「docker-compose.yaml」が存在していた場合は、「compose.yaml」が優先される。
Docker Desktopをインストールして「docker compose」コマンドを使用すれば、自動的にV2の利用になる。

Docker Composeでコンテナを作成する

Apacheコンテナを例に進めていきます。

使用するイメージ:httpd(バージョン2.4)
ポート番号:8080:80

Docker Composeファイルを作成する

compose.yamlを作成して、フォルダに設置する。
デフォルトではフォルダ名が、Docker Composeのプロジェクト名に使われる。
プロジェクト名によって、個々の環境が分離されるため、何のコンテナ・環境なのかが分かりやすい名前をつけておく。
ここでは、「apache/compose.yaml」

apache/compose.yaml
services: # コンテナの定義
  web: # コンテナの名前
    image: httpd:2.4 # 使用するイメージの名前
    ports: # ポート番号
      - "8080:80"

コンテナの作成と実行

「docker compose up」コマンドを使用することで、コンテナの実行と作成を行います。
ローカルに対象のイメージが存在しない場合は、イメージをプルしてから、コンテナを作成・実行する。
「-d」はコンテナをバックグラウンドで実行させるオプション。
(コンテナのログが画面上に出力されないようにできる)

コマンドは、compose.yamlを配置した階層で実行する

docker compose up -d

実行中のコンテナを一覧表示で確認する

docker container ls

停止しているコンテナも含めて、すべてのコンテナを一覧表示

docker container ls -a

「STATUS」が「UP」になっていれば、コンテナが実行されている。

コンテナ一覧ではなく、Docker Composeのプロジェクトを一覧表示したい場合は、
「docker compose ls」コマンド

http://localhost:8080/にアクセスをして、初期ページが確認できれば完了です。

コンテナを停止する

docker compose stopコマンドを使う

docker compose stop

コンテナが停止したかどうかをDocker Desktopから確認できる。

コンテナの起動

docker compose start

コンテナが起動したかどうかをDocker Desktopから確認できる。
作成済みのコンテナを起動するだけで、コンテナの作成は行なわない。
(複数のコンテナがある場合は、まとめて起動する)

イメージのビルドやコンテナの作成をあわせて実施したい場合は以下のコマンドを実行する。

docker compose up -d

コンテナ内へファイルをコピーする

docker compose cpコマンドを使用する。

Docker Composeでは、1つのプロジェクトで複数のコンテナが管理されているため、どのコンテナのファイルをコピーするかは、コンテナ名で指定する。

コンテナへファイルをコピー

docker compose ホストのファイルパス コンテナ名:コンテナ内のファイルパス

Dockerホストへファイルをコピーする。

docker compose cp コンテナ名:コンテナ内のファイルパス ホストのファイルパス

Apacheコンテナとファイルをやりとりしてみる

Apacheコンテナの中にある、「/usr/local/apache2/htdocs/index.html」をDockerホストにコピーしてみる。

以下のコマンドを、「apache/compose.yaml」の階層で実行。
「.」はカレントフォルダを表している。

docker compose cp web:/usr/local/apache2/htdocs/index.html .

index.htmlがDockerホストにコピーされたことが確認できました。

Dockerホストにコピーされた「index.html」に「It works!」と記述されていることが確認できる。

ファイルの中身タイトルを「Hello」に編集してみる。

apache/index.html
<html>

<body>
  <h1>Hello</h1>
</body>

</html>

コンテナ内にコピーしてみる。

docker compose cp index.html web:/usr/local/apache2/htdocs/index.html

ブラウザで初期ページの文言が変更されていることが確認できる。

コンテナを削除する

Docker Composeを使用して作成したコンテナを削除するには、「docker compose down」コマンドを使用する。

  • コンテナが実行中であっても使用可能。
  • 紐づくネットワークも自動で削除される。
docker compose down

コンテナを削除にはdocker compose rmコマンドもある。

  • 紐づくネットワークの削除はできない。
  • 実行中のコンテナに対しては使用できない。
  • 一つづつ確認しながら削除したいときには適している。
  • コンテナの停止と削除を同時に行なうには、「-s」オプションを使用する。
docker compose rm

コンテナとネットワークを一度に削除したい場合は、「docker compose down」コマンドが適している。

削除されたことを確認する

docker container ls

プロジェクトが削除されたことを確認する

docker compose ls

イメージも合わせて削除する

docker compose down --rmi all

イメージの一覧を表示して確認する

docker image ls

WordPress + MySQLコンテナを構築

wordpress/compose.yaml
services: # サービス
  mysql: # 任意の文字列
    image: mysql:5.7 #dockerイメージの指定
    platform: linux/x86_64 #M1 Macの場合、mysqlの定義にプラットフォームを指定
    environment: # 環境変数の指定
      MYSQL_ROOT_PASSWORD: root # (任意の文字列) mysqlのルートパスワード
      MYSQL_USER: user # (任意の文字列) mysqlへログインする際のユーザー名
      MYSQL_DATABASE: wordpress # (任意の文字列) mysql内のデータベース名
      MYSQL_PASSWORD: root # (任意の文字列) mysqlへログインする際のパスワード

  wordpress: # サービスの名称
    depends_on: # サービス間の依存関係を指定
      - mysql # 先にMySQLを起動してくれる(wordpressの起動には、先にMySQLの起動が必要)
    image: wordpress:latest #dockerイメージの指定
    ports: # 公開用のポートの指定
      - "8000:80"
    volumes: # 作業フォルダの同期(コンテナ側ディレクトリをホスト側へマウント)
      - "./html/:/var/www/html/"
    environment: # 環境変数の指定
      WORDPRESS_DB_HOST: mysql:3306 #接続先のコンテナ名。
      WORDPRESS_DB_USER: root #接続先データベースのユーザー名
      WORDPRESS_DB_PASSWORD: passwd #接続先データベースのパスワード

コンテナの作成

対象のパスに移動して以下を実行

docker compose up -d

[http://localhost:8000/]にアクセスしてWordpressトップページの表示が確認できれば成功。

コンテナ内でコマンドを実行する

コンテナ内でコマンドを実行する方法1

起動中のコンテナ内で任意のコマンドを実行するには、「docker compose exec」コマンドを使用する

docker compose exec コンテナ名 コンテナで実行したいコマンド

Dockerホストではなく、コンテナ内にあるMariaDBのバージョンを確認する
(コマンドが、ローカルではなくコンテナ内で実行される)

docker compose exec db mariadb --version

コンテナ内でコマンドを実行する方法2

コンテナ内で複数の操作を行いたい場合は、毎回「docker compose exec」コマンドを入力するのは面倒。
また、「docker compose exec」コマンドを用いた方法だと、初期設定が必要なコマンドを実行できない可能性もある。
そういうときには、コンテナ内でシェルを立ち上げる。(そのシェルを介してコマンドを実行する)
このような操作を、コンテナの中に入ると表現される。

作成済みのMySQLコンテナ内でシェルを立ち上げる

docker compose exec mysql /bin/bash

シェルが起動するので、バージョンを確認する

mysql --version

ルートユーザーとしてMySQLにログインする

  • テーブルの作成やSQLの発行が行える。
  • 起動するには、データベースのログインが必要。

Docker Composeファイルで設定した、データベース名やユーザー名、パスワードを入力する。

mysql -u user -D wordpress -proot

「exit」で、MySQLの対話モードとDockerコンテンナから抜けることができる。

exit

さまざまな機能を一つのコンテナに詰め込まない

  • コンテナは、さまざまな機能を一つのコンテナに持たせることも可能だが、推奨されていない。
  • コンテナの再利用性を損ない、メンテナンスのコストを増加させてしまうため。
  • コンテナは機能ごとに分ける

コンテナ内のデータを残す

  • コンテナを削除すると、コンテナ内のデータも合わせて削除されてしまうため、コンテナ内のデータを残すには永続化が必要になる。
  • データベースのコンテナを削除した場合に、データベースに登録したテーブルやデータが毎回すべて削除されると困るので、そのような場合にデータの永続化を行う。
  • Dockerには、データの永続化を行う、ボリュームバインドマウントいう機能がある。

ボリューム

  • ボリュームは、Dockerが管理する記憶領域にデータを永続化する仕組み。
  • バインドマウントよりデータの移行やバックアップが容易。
  • Dockerが管理する記憶領域にデータが保存されるので、データを変更する際は、データベースのデータなどを直接操作するのことがないデータに向いている。
  • 「docker compose down」コマンドでコンテナを削除するときに、デフォルトでは、ボリュームは削除されない。
  • コンテナを削除しても、ボリュームに残しておけば、再度コンテナを作成した際にそのボリュームをマウントすれば、
    データを利用できる。
  • 「volumes」に記憶したボリューム名を、「services」下の「volumes」に記載すると、対象のコンテナのデータがボリュームで永続化される。
services:
  コンテナ名:
    image: 使用するイメージ名
    volumes:
      - 「volumes」に定義したボリューム名:コンテナ内のパス
volumes:
  ボリューム名

バインドマウント

  • バインドマウントは、ホストOSのフォルダーやファイルをマウントする仕組み。
  • データを変更するときには、ホストOSのファイルを直接変更することで、コンテナ内にも自動で反映される。
  • 変更の頻度が高いデータに向いている。
  • ホストマシンによってフォルダー構成は異なる可能性があるので、汎用的ではないところがデメリット。
  • ボリュームの場合は、ホストやフォルダー構成を意識する必要がないことがメリット。
  • バインドマウントの場合は、ホストOSのフォルダーを記載する。
services:
  コンテナ名:
    image: 使用するイメージ名
    volumes:
      - ホストOSフォルダー:コンテナ内のパス
  • バインドマウントでは、あくまでホストOSのフォルダーをマウントするため、ホストOSにデータが存在している必要がある。
  • ホストOSのデータを削除すれば、コンテナ内のデータも合わせて削除される。

DockerFileとは

  • Dockerイメージをコード化したもの
  • ファイルを読むだけで構成がわかる
  • DockerFileを配置しておくと、dockerコマンドやdocker composeコマンドでイメージのビルドを行う際に、DockerFileに従ったイメージを作ることが可能。

DockerFileとDocker Composeの違い

  • DockerFileはあくまで、イメージを作成するためのファイル。
  • Docker Composeは、複数コンテナの作成を行うソフトウェア。

参考文献

https://libroworks.co.jp/?p=6532
https://qiita.com/tomokei5634/items/75d2501cfb968d0cfab5

Discussion

ログインするとコメントできます