🐋

Dockerの概要と使い方を理解しよう

に公開

🐳Dockerの概要を理解しよう

今回は環境構築を行う際の重要なツールであるDockerについての説明です。
プログラミングを学んだ後、開発を行う際にこのような問題が生じると思いませんか?

この様な環境の違いを無くし、どこでも同じ環境を再現できる技術として注目されたのがDockerです。

Dockerとは何だろう

Dockerとは、コンテナ仮想技術を使った環境を提供するツールです。
この「コンテナ」を使えば、環境の違いを気にせずどこでも同じようにアプリを動かせるのです。

その詳細について、順を追って確認していきましょう。

🚢コンテナについて詳しく知ろう

コンテナを理解する際に引き合いに出されることが多いのが、従来の仮想マシン(VM)です。
この2つはどちらもアプリケーションを分離して実行する技術ですが、大きな違いがあります。

仮想マシン(VM)は、OSごとに仮想化を行います。
これにより完全に分離された環境を作れますが、その分リソース消費が大きくなります。

一方、コンテナはホストOSのカーネルを共有を行います。
これによって軽量かつ高速に起動できるのが特徴です。

✅コンテナの使用にあたって

メリット

  • ホストOSを汚さずに、複数の環境を構築できる
    新たなソフトウェアをインストールすることによる設定変更やバージョン管理による手間を省略。
  • Ias(Infrastructure as Code)の実現
    アプリケーションのインフラ構築がテキストファイルを用いてコードで簡単に出来る。
  • 環境を変えても動作する
    上記で紹介したローカル環境と本番環境の違いによるライブラリの不足やバージョンの違い等の不具合を避けられる。

デメリット

  • 学習コストが必要
    コンテナの作成や実行だけであれば直ぐに出来るようになります!
    しかし複数のコンテナを組み合わせる・本番環境で使いたい等の場合は深い知識が必要です。

⚙コンテナの作り方を理解しよう

DockerDesktopのダウンロード

コンテナ仮想技術であるDockerはLinuxの技術(Linuxカーネルの機能)を利用しているのでLinux上でネイティブに動作します。
そのためWindowsやMacで動かす際にはLinux環境を用意し、その上でDockerを動かす必要があります。
DockerDesktopを使えば、GUIで簡単にセットアップ出来ておすすめです。
CLIのみで操作することも出来ますが、複数のコンテナを管理する際にはDockerDesktopが便利です。

➡ DockerDesktopインストールはこちらから

https://docs.docker.com/get-started/get-docker/

➡ DockerDesktopのセットが分からない方向け


セット出来れば起動した状態でCLI操作をターミナルやコマンドプロンプトから行うことで、
実際にコンテナを作ることが出来ます。
ここからはCLI操作でDockerの全体的な操作をつかんでいきましょう。

💭Docker imageって何だろう

コンテナを作るにあたって大切な要素があります。それがDockerimage(イメージ)です。

イメージとはコンテナに必要なソフトウェア・環境変数・設定などの情報が入った実行環境テンプレートです。
簡単に言えば、コンテナの元となるファイルです。

コンテナで使いたいプログラム言語や環境などをこのイメージに記述し、イメージを起動することによってコンテナを作ります。


イメージは単なるファイルですので、このファイルを他の人に渡す・AWS上のサーバーにアップロードすることで様々な場所で環境がつくれるのです。

✅イメージは自分で作ることも出来ますが、用意されたものをダウンロードして使うことも出来ます。

  • ダウンロードする際にはDockerhub(https://hub.docker.com/)などの、イメージレジストリと呼ばれる様々な種類のイメージが登録されている場所から行います。

  • 一方、自分でカスタマイズしたイメージを作る際にはDockerfileというものを使います。

imageをダウンロードしてコンテナを動かすには?

⚙Imageを動かすコマンド

 docker image pull {イメージ名}   #imageをダウンロード

 docker image ls   #入手したimageの一覧を表示
 
 docker image inspect {イメージ名}   #imageの詳細な情報を取得

 docker image rm {イメージ名}   #imageの削除

上記4つのコマンドを使うと、任意のimageをダウンロード~削除まで一通り行うことができます!

imageをダウンロードする方法を確認できました。
次のステップとしてイメージからコンテナを動かす必要がありますね。


⚙containerを動かすコマンド

containerの作成

docker container run {イメージ名}   #指定したイメージからコンテナを起動

docker container ls   #起動しているコンテナの一覧を表示

コンテナ起動時に指定のイメージをダウンロードしていなかった場合でも、
指定したイメージを探しに行って自動でダウンロードしてくれます。

container lsは起動中のコンテナを一覧表示するコマンドなのですが、例えば hello-world をイメージ名に入れてコンテナを起動した場合、lsコマンドを実行しても出てきません。

これはこの hello-world 自体が、イメージの設定の中で「動後にコンテナを閉じる」という設定で書かれているためです。
イメージによってはコンテナ起動→何らかの処理→コンテナ停止までの一連の動作が入っているので、
そのままコンテナが起動し続けるか起動後に停止するかはイメージ次第ですね。


containerの一覧表示

docker container ls -a   #起動していないコンテナも含めての一覧を表示

このように-aを加えることで、ステータスがUPではない(今現在起動状態ではない)ものも含めた一覧を表示することが出来ます。

コンテナが起動中は元のターミナルでコマンドライン操作が行えません。
そのため起動中のコンテナに何かコマンドライン操作を行いたい場合は、新規ウィンドウを開いてコマンド操作を行いましょう。


containerのその他の動作

docker container stop {コンテナ名}   #起動コンテナを止める

docker container start {コンテナ名}   #停止中のコンテナを再開
docker container restart {コンテナ名}   #コンテナを再起動

docker container rm {コンテナ名}   #コンテナの破棄
docker container run --rm {イメージ名}   #コンテナを実行した後削除

docker container run -it {イメージ名}{実行したいコマンド}#imageからコンテナを新規作成+コマンド実行
docker container exec -it {コンテナ名}{実行したいコマンド}#既存のUPコンテナでコマンド実行

docker container prune   #up以外のコンテナを削除

オプション説明

オプション 説明
-i コンテナに対して標準入力を受け付ける
-t 端末を割り当て、きれいな出力で返す
-it -i-t を組み合わせたもの(対話モードでの使用が一般的)
-d デタッチモード(バックグラウンドで実行)
--name {名前} 実行するコンテナに好きな名前を付ける

ここまででイメージレジストリを使ったコンテナ操作を学びました。
次はカスタムしたイメージを使ったコンテナの作り方について学びましょう。

📘Dockerfileって何だろう?

イメージレジストリのからダウンロードしたイメージには必要最小限の機能しか備わっていません。
イメージをカスタムして欲しい環境を整える必要がありますよね。
そのために必要なのがDockerfileです。

Dockerfileという名前のファイルにカスタムしたイメージを作っておけば、
開発に必要な要素がコンテナ起動と同時に準備されます。

Dockerfileが用意されていれば、ターミナルでdocker image build .を実行することで、
Dockerfileからイメージが作成されます。
コンテナを立てるだけで実務はスタートできますが、せっかくの機会なので中身を確認してみましょう。

↓以下は20.04タグのubuntuをベースにしたDockerfileの例です。

FROM ubuntu:20.04             1 ベースイメージを指定

RUN apt update                2 コマンドを実行
RUN apt install -y curl       3 コマンドを追加

COPY . /app/                  4 コピー

CMD ["ls"]                    5 コマンドを指定

ENV hello="Hello World"       6 環境変数
CMD ["bash"]                  7 コマンドを指定

🛠よく使われるDockerfileコマンド

コマンド 説明 使用例
FROM ベースとなるイメージを指定 FROM ubuntu:latest
RUN コンテナ内でコマンドを実行 RUN apt update
COPY ホストのファイルをコンテナにコピー COPY index.html /usr/share/nginx/html/
ADD COPY に似ているが、圧縮ファイルの展開が可能 ADD myfile.tar.gz /app/
CMD コンテナ実行時にデフォルトで実行するコマンド CMD ["nginx"]
EXPOSE コンテナが使用するポートを指定 EXPOSE 80
ENV 環境変数を設定 ENV APP_ENV=production
WORKDIR 作業ディレクトリを指定 WORKDIR /app

全てを覚える必要はありません。コマンドの意味がなんとなく読み取れるようになれば上出来です!

この表を使って先ほどのDockerfileを読み解くと以下の様になります。

  1. Ubuntu 20.04の環境を使用
  2. apt updateを実行し、パッケージリストを最新の状態に更新
  3. curlコマンドをインストールして使用可能にする
  4. ホストのカレントディレクトリ(.)をコンテナ内のappというフォルダにコピー
  5. コンテナが起動したときにlsコマンドを自動で実行
  6. helloという環境変数を定義し、値として "Hello World" を設定
  7. デフォルトの実行コマンドをbashに変更(ls を上書き)

つまり、「このDockerfileは Ubuntu 20.04環境で必要な設定を行い、最終的に bash を起動するように構成 されている」ということになります!
読み取れたでしょうか?

📚便利なDocker Compose

さて、ここまでで

  • Dockerの概要理解
  • イメージレジストリから取得してコンテナをたてる方法
  • Dockerfileからカスタムしたイメージを作る方法

の順に説明を進めてきました。

最後にDocker Composeという複数のコンテナをまとめて管理するためのツールについて学びましょう。

イメージからコンテナを起動するためのコマンドは
docker container run {イメージ名}でしたよね。

そこで起動したコンテナを使ってwebアプリを作りたいとしましょう。
コンテナは1つだけで足りるでしょうか?答えはNoです。

基本、webアプリはPHPなどの言語を使うだけでは作れないはずです。
言語やフレームワークの他にもデータベースWebサーバーといった要素が必要になります。
お気づきかもしれませんがそれぞれコンテナを用いる場合、全て起動する必要があります。


🛠 必要なコンテナ一覧

コンテナ 役割
アプリケーションコンテナ WebアプリやAPIを動かす(例:PHP、Node.js、Python)
データベースコンテナ データを管理する(例:MySQL、PostgreSQL、MongoDB)
Webサーバーコンテナ(必要に応じて) アプリのリクエストを処理(例:Nginx、Apache)

作りたい物によってコンテナの数は違ってきます。1つのアプリケーションを動かす際に複数コンテナがあると以下の様な問題が生じそうですよね。

  • 多くのDockerコマンドを実行するのは大変
  • 他人に同じ環境を共有するのは困難

これらの難点を解決してくれるのがDockerComposeです!
コンテナをまとめて管理することで、環境構築がより簡単になります。

📃DockerCompose を使う3つのステップ

DockerComposeを使うためには以下の工程が必要です。

  • アプリケーションの環境を Dockerfile ファイルで定義
  • アプリケーションを構成する各サービスを docker-compose.yml ファイルで定義
  • docker compose up を実行

このうちDockerfileの定義はもう学習しましたよね。
docker compose upも、最後にコマンドを実行するだけです。

docker-compose.ymlの中身について、一緒に確認していきましょう。

📖docker-compose.ymlを見てみよう

↓Nginx + PHP + MySQL の環境を構築する場合のdocker-compose.yml例

version: "3.8"

services:
  app:
    image: php:8.0-fpm
    volumes:
      - ./app:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql

  web:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app

volumes:
  db_data:

🛠 docker-compose.yml の設定項目

設定 内容
version Docker Composeのバージョン(3.8を指定)
services 使用するコンテナ(app, db, web
image 使用するDockerイメージ
volumes ローカルのファイルをコンテナにマウント
ports ホストとコンテナのポートを対応付け
depends_on 起動順序の指定(appdb を待つ)
environment 環境変数(MySQLのユーザーやパスワード)=ENV
volumes 永続化するデータ(MySQLのデータを保持)

一例ですので他の要素を記述することも当然ありますが、コンテナを管理するための要素と内容全体をなんとなく把握できれば充分です!

Dockerfileだけでなくdocker-compose.ymlがある場合には、

docker-compose up -d

このコマンドで一発で複数のコンテナが起動し、環境構築が行えます。超便利ですね!!


コマンドまとめ一覧

コマンド 説明
docker-compose up サービスを起動します。-dオプションを使うとバックグラウンドで起動します。
docker-compose start 既存のサービスを再開します。upとは異なり、新たにサービスを作成することはありません。
docker-compose stop 実行中のサービスを停止します。
docker-compose down サービスを停止し、コンテナ、ネットワーク、ボリュームを削除します。--rmi allオプションでイメージも削除可能。
docker-compose restart 実行中のサービスを再起動します。
docker-compose rm 停止中のコンテナを削除します。
docker-compose build サービスのイメージを再ビルドします。--no-cacheオプションでキャッシュを無視してビルド可能。
docker-compose run サービスを一度だけ実行します。対話型で実行する場合は-itオプションを使います。
docker-compose exec 実行中のコンテナ内でコマンドを実行します。
docker-compose logs コンテナのログを表示します。--followオプションでリアルタイムでログを表示できます。
docker-compose ps 現在稼働しているコンテナの状態を表示します。
docker-compose pull サービスのイメージをリモートから取得します。
docker-compose push サービスのイメージをリモートリポジトリにアップロードします。
docker-compose version 現在インストールされているDocker Composeのバージョンを表示します。

💻環境構築のあれこれ

実務で環境構築を行う場合、例として挙げるとGithubからリポジトリをクローンしてきて開発を始める場合、READMEというファイルに環境構築の手順や必要なコマンドが記述されていることが多いです。

また、Makefileというファイルが用意されている場合もあります。
このファイルはターゲット(目標)と、それを達成するために実行するコマンドを記述します。

# ターゲット: コマンド
all:
    echo "Hello, World!"

この例では、makeコマンドを実行すると、Hello, World! と表示されます。

予め環境構築に必要なコマンドをターゲットごとにまとめてMakefileを作っておき、
そのコマンドをREADMEに書いておけば、知識が無くても直ぐに環境構築が出来る!
という仕組みです。他にも、

  • C言語などのソースコードをコンパイルする際の手順を記述する
  • 開発タスク(ビルド、テスト、環境構築など)を自動化する

場合などに使われています。
Makefileを見つけた際には中の記述を確認してみるといいかもしれませんね。

🍀お疲れ様でした

実際に共同開発や、課題とされているアプリを作る場合には、Dockerfileやdocker-compose.ymlが既に準備されている場合がほとんどです。

ぶっちゃけDockerが使える環境で
docker-compose upのコマンドが打てればコンテナの起動は終わりです。
しかし、

  • Dockerがどのような働きをしているの?
  • コンテナをたてるにはどうすれば良いの?

この辺りの知識があれば脳死でコマンドを打つだけでなく、自身で新しい環境を作ることも出来るでしょう。

実際に0から環境を作る際には、Dockerfileやdocker-compose.ymlを準備するだけではありません。

今回は大まかな概要の学習でしたので既存の環境の使い方が中心でしたが、興味があればDockerやその他の環境構築について、ひいては0から環境を作る方法について、学習を継続してみてくださいね🍀

Discussion