546
701

Dockerによる開発環境構築のための概念理解と方法解説

Last updated at Posted at 2023-12-09

この記事はNuco Advent Calendar 2023の9日目の記事です。

はじめに

この記事ではDockerで開発環境を行うために理解してほしい概念と実際の開発環境の構築手順について解説を行います。大きく分けて、

・Dockerの概念理解
・開発環境の構築

これらの章により構成されています。この記事を読むことで、Dockerファイル、イメージ、コンテナ、Docker compose、compose.ymlを理解できるようになることを目指しています。Dockerに触れてみたい、Dockerの理解があやふやという方は参考にしてみてください!

弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています!興味をお持ちいただける方は、こちらまで。

Dockerとは

01-primary-blue-docker-logo.png

まず、Dockerに対する理解をしていきましょう。

Dockerとは「コンテナ型の仮想環境を作成、共有、実行するためのプラットフォーム」です。クジラのようなアイコンが特徴的です。

私が最初に勉強をした時に、

「コンテナ型の仮想環境ってなんだ?」 

と思ったので、これを解決するために、仮想環境とコンテナについて解説したいと思います。

仮想環境

仮想環境とは、仮想的に構築された環境のことを指します。仮想的という言葉は擬似的という言葉に置き換えられます。例えば仮想環境では、WindowsPC上でLinuxOSを動作させることができます。これは、仮想環境により、LinuxOSが擬似的に再現されているということになります。

スクリーンショット 2023-11-27 13.16.02.png

コンテナ

コンテナはその名の通り、物流で使用されるコンテナをイメージしてもらって大丈夫です。コンテナという箱の中にアプリケーションに必要なものが詰まっています。

スクリーンショット 2023-11-27 13.44.47.png

Dockerでは、コンテナ技術を利用して仮想環境を構築しています(コンテナ利用した仮想環境構築の方法で一番広まっているのがDockerです)。このコンテナ技術を利用すると何が嬉しいのか次のDockerのメリットで解説します。

Dockerのメリット

軽量に起動できる

Dockerは従来の仮想環境に比べて軽量に起動することができます。それはコンテナ技術を利用することで実現されています。

スクリーンショット 2023-11-27 14.21.31.png

図の左側は従来の仮想環境ソフトウェアを用いた場合になります。従来の仮想技術では、仮想化ソフトウェアによりゲストOSが構成され、その上にミドルウェアやアプリケーションが構築されています。そのため、起動するたびにゲストOSを起動する必要がありました。一方Dockerでは、コンテナエンジンを用いて、ゲストOSがあるかのように環境を構築しています。

従来の仮想マシン:仮想化ソフトウェア→ゲストOS→ミドルウェア等
Docker:コンテナエンジン→ミドルウェア等

このようにDockerではゲストOSを起動させる分の処理が簡略化されているため、従来の仮想技術よりも軽量に起動することができます。これにより、従来の仮想技術に比べてハードウェアのリソース削減を行うことができています。

共有のしやすさ

後述しますが、DockerではDockerイメージと呼ばれる、テンプレートのようなものを使用して、コンテナ(実行環境)を構築します。Docker HubなどからDockerイメージをダウンロードすれば、誰でも同じ環境を簡単に構築することができます。

スクリーンショット 2023-11-27 173728.png

開発の一貫性

開発の現場において、プログラミングなどのソースコードはGithubを用いれば簡単に行うことができます。しかし、プログラミングコードを実行するために、実行環境を整える必要があります。Dockerでは、アプリケーションとその依存関係をまとめ、ほかの環境でも同じように動作するように保証します。つまり開発環境と本番環境で同じコンテナを用いれば動作が保証されるため、開発チームと運用チームで発生する環境のずれにより発生する問題を最小限に抑えることが可能です。

簡単なバージョン管理

Dockerイメージはバージョン管理が容易で、変更履歴を確認し、特定のバージョンに戻すことができます。これにより、アプリケーションのアップデートやロールバックが簡単に行えます。

セキュリティの向上

Dockerはセキュリティスキャンツールと統合しやすく、コンテナイメージが脆弱性を含んでいないかを簡単に確認できます。これにより、セキュリティの問題を素早く検知して対処できます。

迅速な展開とスケーリング

Dockerは従来の仮想技術よりも軽量に起動可能です。これにより、新しいコンテナを迅速にデプロイし、必要に応じスケールアウトをすることができます。

Dockerの基本概念

これまでにDockerの全体的構成について解説しました。次により細かく、Dockerを構成する基本概念について解説したいと思います。ここでは特に、イメージ、コンテナ、レジストリ、Dockerfileについて解説します。Dockerfileは環境構築を行う上で重要なものであるため抑えましょう。

Dockerイメージ

Dockerイメージはコンテナを起動するための設定ファイルをまとめたものとなっています。Dockerイメージを起動することで、コンテナが作成されます。Dockerではこのイメージを共有することで、異なるマシン(PC)上で同じ実行環境(コンテナ)を構築することができます。

より、Dockerイメージの理解を深めるためにDockerイメージの構造について説明します。

Dockerイメージは複数のイメージレイヤと呼ばれる"層"によって構成されています。1つの層に対して1つのミドルウェアが対応します。これらの層は読み取り専用で編集はできません。イメージからコンテナを生成し、コンテナ内でミドルウェアをインストールした場合には、新しい層が追加されることになります。この新しい層は編集可能です。また、コンテナで追加した層を含めて、新たにイメージを作成することもできます。

スクリーンショット 2023-11-28 013411.jpg

Dockerコンテナ

今まで説明を行いましたが、コンテナは実際のアプリケーションの動作環境になります。コンテナはイメージを起動することで動かすことができます。私たちはこのコンテナ内で作業を行い、アプリケーションやシステムの開発を行います。

スクリーンショット 2023-11-27 231722.jpg

レジストリとは

Dockerレジストリとは、Dockerイメージを保存する場所になります。Docker Hubなどがレジストリに該当します。レジストリにDockerイメージを保存することで、他の人と共有を行ったりすることができます。Docker Hubの利用方法については、こちらの章で解説します。

Dockerfile

DockerfileとはDockerイメージを構築するための設計図のようなものです。つまり、Dockerfileを編集することで、環境構築ができるようになります。

スクリーンショット 2023-11-27 222811.jpg

Dockerfileの構文

Dockerfileは命令と引数により構成されます。一行につき一つの命令が与えられ実行する際に1行目から順番で実行されます。

{命令} {引数}

こちらが命令の一例です。

命令 使用用途
FROM ベースイメージを指定する
RUN コマンドを実行する
CMD コンテナの実行コマンド
ENV 環境変数の指定
COPY ファイルコピー
FROM

FROMではベースイメージの指定を行います。ベースイメージとは、さきほどのDockerイメージの際に説明したイメージレイヤの最初のレイヤに該当します。つまりイメージはベースイメージから積み上げる形で構成されていきます。ベースイメージには、ベースとなるDockerイメージが入ります。最初の内はベースイメージにはUbuntuやCentOSなどが入るという認識でも大丈夫です。

例えば、ベースイメージにUbuntuにした場合次のように書かれます。

FROM ubuntu:22.04
RUN

RUNでは、対応するディストリビューション(Ubuntu、CentOS、debianなど)の実行コマンドを入力して必要なライブラリなどのインストールを行います。

RUN apt-get update && apt-get install -y
COPY

ファイルのコピーを行います。{src}はコピー元のファイルまたはディレクトリであり、{dest}はコピー先のパスです。

COPY {src} {dest}
WORKDIR

作業ディレクトリを指定することができます。

WORKDIR /app

この場合コンテナ起動時にappディレクトリがカレントディレクトリとなっています。

CMD

CMDでは"コンテナの"実行コマンドを指定できます。CMDを編集することで、実行コマンドの省略を行えます。

全体

Dockerfileの中身をこちらを用いて確認していきましょう。

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

# 作業ディレクトリを/appに設定
WORKDIR /app

# 環境変数を表示するスクリプトをコピー
COPY print_env.sh .

# スクリプトを実行するコマンド
CMD ["./print_env.sh"]

このコンテナを実行するとprit_env.shが実行されて環境変数が表示されます(print_env.shは別途用意する必要があります)。

一連の流れ

スクリーンショット 2023-11-27 231944.jpg

こちらがDockerにおける環境構築の基本的な流れとなっています。まず、Dockerfileを私たちが編集することで、イメージの設計書を作成します。設計書を元に、イメージを作成し、イメージを起動することで、コンテナ(実行環境)を構築します。これがDockerで行われる基本的な流れとなっています。

スクリーンショット 2023-11-27 235844.jpg

また、Dockerfileを編集しなくとも、Docker Hubからイメージをダウンロードすることでコンテナを起動することもできます。

Dockerの基本コマンド

イメージ

・Docker Hubからイメージを取得

docker image pull example_image

・Dockerのイメージ一覧の取得

Docker image ls -a

-aはオプションですべてのイメージが表示されます。

・DockerfileからDockerイメージの作成

docker image build -t example_image:1.0 {Dockerfileのパス}

-tのオプションを与えることで、イメージの名前とタグを設定します。タグはバージョンを示したりするのに用います。

・Dockerイメージの削除

docker image rm example_image

rmでDockerイメージの削除を行います。

コンテナ

・コンテナの一覧を表示

docker container ls -a

・コンテナの起動

docker container run -- name example_container

・コンテナの停止

docker container stop example_container

・停止中のコンテナの起動

docker container start example_container

・起動中のコンテナの再起動

docker container restart example_container

・コンテナの削除

docker container rm example_container

基本となるコマンドの一例を紹介しましたが、コマンドはオプションを含め、たくさんあるのでこちらを参考に調べてみてください。

ボリュームと永続性

データ永続性の確保

コンテナ内で管理されているデータはコンテナを削除したときに、消えてしまいます。データを消さないためにも、データの永続性の確保が必要となります。そこで必要となるのがマウントとボリュームです。

マウントとは

コンテナの外にあるデータを、コンテナ内で利用できるようにすることをマウントと呼びます。Dcokerにおいてマウントは3種類あります。

・ボリューム
・バインドマウント
・一時ファイルシステムマウント

この3種類となります。
今回はDockerで推奨されるボリュームに焦点を当てて解説します。

ボリューム(volume)とは

ボリュームはデータを永続する場所のことを指します(USBなどの外付け記憶装置のようなイメージです)。そのため、ボリュームをコンテナに結び付ける(マウント)ことでデータの永続化を行います。またボリュームは複数のコンテナに接続することもできます。

Docker Composeの基本

Dcoker Composeの役割

Dockerを利用した開発では複数のコンテナを起動して、コンテナ間の通信を行う必要があります。例えば、Dockerを利用して、WordPressを実行する場合には、PHPにより構成されたコンテナとデータベースのコンテナを利用する必要があります。いちいち、手動でDockerイメージからコンテナの起動などを行うのは連携するコンテナが増えると面倒になってきます。その手間を解消するために必要となるのが、Docker Composeです。

スクリーンショット 2023-11-28 220644.jpg

Docker Composeでは、compose.ymlと呼ばれるDockerに対する指示書を作成します。Dockerはこの指示書に基づいて複数のコンテナを同時に起動します。

YAMLファイルの構文

こちらがWordPressを実現するためのcompose.ymlとなっています。構文の細かな解説は省略しますが、コメントでざっくりと説明を付け加えとくので参考にしてみてください!

version: '3' #Docker-composeのバージョンを指定します

services: #起動するコンテナごとに一つのサービスを定義します。
   db: #dbという名前をつけてサービスを定義します
     image: mysql:5.7 #イメージの指定
     volumes: #パスをボリュームとしてマウントします(ホスト側:コンテナ側のように記載します)
       - db_data:/var/lib/mysql
     restart: always #再起動ポリシーの設定(alwaysだとコンテナが停止すると常に再起動します)
     environment: #環境変数の設定を行います。
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on: #サービス間の依存関係を指定します(起動するときはdb→wordpress、停止のときは逆順となります)
       - db
     image: wordpress:latest
     ports: #ポートを公開します(ホスト:コンテナで記載します.コンテナのみを指定した場合はホストはランダムに設定されます)
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes: #ボリュームの設定db_dataという名前のボリュームが定義されます。
    db_data:

こちらがリファレンスになるので、他のサービス設定を確認したい方は参考にしてみてください。

Docker Composeの基本コマンド

Docker Composeの基本コマンドを紹介します。

・copose.ymlで記載された各イメージをまとめてビルド

docker-compose build 

・コンテナを一括で起動

docker-compose up -d 

・コンテナの停止

docker compose stop

・コンテナの再起動

docker compose start

・コンテナをまとめて削除

docker compose down

より、詳細なコマンドはこちらを参考にしてみてください。

開発環境構築の具体的な手順

ここまで長々と説明しましたが、実際に開発環境を構築してみましょう。

すでにあるイメージを使用する場合

DockerHubにはDockerイメージが公開されているため、自分でDockerfileをいじらなくてもイメージを引っ張ってきてコンテナを作成することができます。まずはその方法を紹介します(コマンドをぽちぽちしていけば構築できます)

・Docker Hubからイメージの取得

docker image pull ubuntu

イメージがあることを確認します。

$ docker image ls

・イメージからコンテナの起動

$ docker container run -it -d --name ubuntu-qiita ubuntu

-itはコンテナを対話的なモードで実行するためのオプションです。-dではコンテナがバックグラウンドで実行されるようにします。--nameでコンテナの名前を指定します。

コンテナが作成されていることを確認します。

$ docker container ls
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
3b35a6bedeb5   ubuntu    "/bin/bash"   9 minutes ago   Up 9 minutes

次のコマンドで起動されたコンテナ内に入ることができます。

$ docker exec -it ubuntu-qiita bash

コンテナ内はこのようになっています。

スクリーンショット 2023-11-30 18.47.37.png

これでUbuntuの環境構築が完了しました。

コンテナから出る時はexitでコンテナから出ることができます。

スクリーンショット 2023-11-30 20.07.33.png

exitでコンテナから出てもコンテナ自体は起動したままなので、コンテナを停止させます。

$ docker container stop ubuntu-qiita

このコマンドでコンテナが停止します。

$ docker container rm ubuntu-qiita

このコマンドで停止したコンテナを削除することができます。

Dockerfileから作成

続いて、Dockerfileからイメージを作成して動作させてみましょう。Pythonを実行できるように環境構築を行います。

Docker-Python
└ dockerfile
# ベースイメージを指定
FROM python

RUN apt-get update
RUN pip install --upgrade pip

WORKDIR /Qiita

短いDockerfileになりますが、これだけでPython環境を構築できます。Dockerfileをもとにイメージを作成します。

$ docker build -t python-qiita:latest .

実際にイメージが生成されました。

スクリーンショット 2023-11-30 22.59.29.png

あとは、先ほどと同様にコンテナを起動してコンテナ内に入れば作業ができます。今回はWORKDIRにQiitaを設定しているため、Qiitaディレクトリがカレントディレクトリとなります。

スクリーンショット 2023-11-30 23.21.18.png

実際にPythonを実行することができました。

スクリーンショット 2023-11-30 23.28.20.png

スクリーンショット 2023-11-30 23.29.39.png

Docker Composeを利用した複数のコンテナ管理

Docker composeを利用して、WordPressの環境を構築してみましょう。

以下のようなディレクトリ構成にします。

Docker-WordPress
└ compose.yml
version: '3'

services:
   db:
     platform: linux/x86_64 #M1チップマックの場合はこの行を追加してください
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

.ymlファイルがあるディレクトリで以下のコマンドを実行します。

docker-compose up -d

そうすると、compose.ymlをもとにコンテナを作成、起動します。実際にコンテナが起動していることを確認します。dockerfileがなくとも自動でイメージを引っ張ってきてコンテナを起動してくれます。

$ docker container ls

コンテナが起動している状態でhttp://localhost:8000にアクセスするとWordPressを使用することができます。

スクリーンショット 2023-11-30 19.35.18.png スクリーンショット 2023-11-30 19.37.08.png

コンテナの停止と削除を行ってみましょう。

$ docker compose stop
[+] Stopping 2/2
 ✔ Container docker-wordpress-wordpress-1  Stopped                                                                                1.3s 
 ✔ Container docker-wordpress-db-1         Stopped 
$ docker compose down
[+] Running 3/3
 ✔ Container docker-wordpress-wordpress-1  Removed                                                                                0.0s 
 ✔ Container docker-wordpress-db-1         Removed                                                                                0.0s 
 ✔ Network docker-wordpress_default        Removed

これで、作成したコンテナの削除が完了しました。(イメージは残っているため、イメージまで削除したい場合は--rmi allをオプションとして選択してください。)

Docker Hubとイメージの共有

これまでに散々紹介してきたDocker Hubの利用方法について最後に簡単に説明します。

Docker Hubの利用方法

Docker Hubにアクセスして、アカウントを作成しましょう。Googleアカウント、GitHubアカウントを使用してアカウントを作成することができます。

このようにDocker Hub上には様々なイメージが保存されています。興味のあるものを引っ張って遊んでみてください。

スクリーンショット 2023-11-30 21.30.45.png

イメージのビルドと共有

Dockerfileで自分でオリジナルのイメージを作成した場合、そのイメージをDocker Hub上に共有することができます。

Docker Hub上にpushするためには、リポジトリの作成、Docker Hubへのログイン、イメージのタグ付け、Docker Hubへのプッシュのステップとなります。

まず、Docker Hub上でリポジトリの作成を行います。今回はubuntuというリポジトリを作成します。この時通常イメージ名をリポジトリ名とします。

スクリーンショット 2023-11-30 21.57.01.png
スクリーンショット 2023-11-30 22.07.20.png

次にこちらのコマンドでdockerにログインします。

docker login

ユーザー名とパスワードを要求されます。ログインが完了すると、「Login Succeeded」と表示されます。

次にpushしたいイメージに次のように名前を変更します。

docker tag <前のイメージ名>:タグ <ユーザー名>/<リポジトリの名>:タグ
docker tag ubuntu user_name/ubuntu:latest

pushする際にユーザー名とリポジトリの指定が必要となるため、イメージ名がわかりにくくならないようにリポジトリ名にはイメージ名を設定します(イメージ名と関係のない名前を設定すると何のイメージが入っているのかわかりにくくなる)。

最後にDocker Hubに名前を変更したイメージをプッシュします。

docker image push <ユーザー名>/<リポジトリ名>:タグ
docker image push user_name/ubuntu:latest

よりDockerの理解を深めるために、、、

Dockerチュートリアル

こちらのサイトではDockerを使用するためのチュートリアルが公開されています。チュートリアルを実際に行うことで、Dockerの理解をより深めましょう。

@Michinosukeさんが公開しているDockerチュートリアル和訳された記事も公開されているので参考にしてみてください。

書籍

今回できる限り盛り込んで説明を行いましたが、もちろんこの記事がDockerのすべてではありません。より体系的に学びたい場合は書籍から勉強することをおすすめします。

仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん

Docker/Kubenetes 実践コンテナ開発入門

おわりに

いかがでしたでしょうか。今回はdockerの開発環境の構築という点に焦点を当てて解説しました。1人でも多くの人の参考になればと思います。

弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています!興味をお持ちいただける方は、こちらまで。

546
701
4

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
546
701