Docker超入門〜通常レベルまで Part4

1. 本記事について

本記事では、docker composeを用いて、複数のコンテナ作成を行なっていきます。

2. Docker composeとは

docker composeを聞いたことがない方向けに、docker composeは何なのかを説明します。

docker composeとは、複数のコンテナを効率的に管理するためのツールです。

通常のdockerとは、何が違うのか。違うという人もいるかもしれませんが、結局のところ同じようなことをしています。

他にも、docker composeを用いることで、volumesやネットワークの設定など様々な操作もまとめて管理することができます。

3. Docker Composeを書いてみよう

さて、ここまで、やってきた知識をフル活用して、書いて覚えていきましょう。

大事なのは、docker composeやDockerの書き方ではなく

開発者(記事を見ているあなたが)何をしたくて、そのために何が必要であるかを言語化して、適切なものを選ぶ力なので、この記事では、そこを鍛えて欲しく、たくさんの環境構築パターンを紹介しています。もちろん、その上の応用力として、必要なものがなかったら原理を元に作る、設定の部分からいじることで応用するなどのスキルは重要です。

いくつか、言語ごと、サービスごとに環境を作ってみましょう。いきなり複数コンテナに触れるのは、大変なので、1つのコンテナを作成していきます。

Docker composeは、コンテナを複数管理するためのツールであり、今まで学んできたDockerの概念から外れるものではありません。むしろ、それらを使って、操作するツールです。

3.1. Goの環境を作ってみよう

Docker composeでGoの環境を作ってみましょう。

Dockerfileを用いて、Goの環境を作ることを頭に入れてみてください。

 

ディレクトリ構成
├── Dockerfile
└── main.go
Dockerfileとmain.goファイル

 

# golangイメージを使う
FROM golang

# 作業ディレクトリを指定
WORKDIR /src

# PCのカレントディレクトリを、コンテナのカレントディレクトリ(workdirで指定した階層/src)へコピー
COPY . .

# コンテナ起動時に実行するコマンド
# go run main.goというコマンドが、コンテナ内の/srcで実行されます。
CMD ["go", "run", "main.go"]

 

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}
実行
docker build -t go-stage .

docker run go-stage
実行結果
Hello World!

docker-composeを使ってみよう

├── Dockerfile
├── compose.yml
└── main.go

先ほどと同じ階層に、compose.ymlファイルを作成してください。

services:
  go:
    build:
      dockerfile: ./Dockerfile
      context: .

完了したら、以下のコマンドを実行してみてください。実行結果は、resultを見てください。

Hello World!が表示されていることがわかると思います。

docker compose up --build                                                                                                                                                         
[+] Building 2.5s (9/9) FINISHED                                                                                                                                                                                                            
 => [internal] load build definition from Dockerfile   
 => => transferring dockerfile: 446B
/* 省略 */
 => => naming to docker.io/library/go-go   

[+] Running 2/2
 ✔ Network go_default  Created                                                                                                                                                                                                         0.0s 
 ✔ Container go-go-1   Created                                                                                                                                                                                                         0.0s 
Attaching to go-go-1
go-go-1  | Hello World!
go-go-1 exited with code 0

compose.ymlについて説明します。

buildは、今までやってきたように、Dockerfileから、docker imageを作成するために、dockerfileと、contextを指定することができます。

このコードでは、dockerfileが、./Dockerfileで、context. となっています。

ただし、注意して欲しいのは、あくまで、渡しているディレクトリは、contextで指定しているので、その中にDockerfileがなければいけません。

3.2. GoのフレームワークGinの環境を作ってみよう

.
├── Dockerfile
├── compose.yml
├── go.mod
├── go.sum
└── main.go

まずは、このようなディレクトリを作成してください。

それぞれのファイルについては以下のとおりです。

書き方については、公式ドキュメントを参考にしてください。

https://docs.docker.jp/compose/toc.html

# golangイメージを使う
FROM golang

# 作業ディレクトリを指定
WORKDIR /src

# コピー
COPY go.mod go.sum ./

# 実行するコマンド
RUN apt-get update \
    && apt-get install -y git \
    && go get -u github.com/gin-gonic/gin

# コンテナ起動時に実行される。compose.ymlかこれかどちらかを実行できればいい。
# CMD ["go", "run", "main.go"]

 

services:
  go:
    build:
      dockerfile: ./Dockerfile
      context: .
    tty: true
    volumes:
      - .:/src
    ports:
      - "3001:3001"
    command: ["go", "run", "/src/main.go"] 

次にgoとginの設定を行います。

main.goを以下のようにしてください。

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

    router.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "Hello World",
        })
    })

    router.Run(":3001")
}

https://gin-gonic.com/ja/docs/quickstart/

このコードは、ginの公式ドキュメントを参考にしました。

ここで、dockerコンテナを起動したいところですが、goのモジュール関係についてまだ何もしていません。なのでインストールする必要があります。以下の2つのコマンドを実行してください。

go mod init gin
go mod tidy

モジュールを使用する際に必要になります。以下の公式ドキュメントを参考にしてみたください。

https://go.dev/doc/tutorial/create-module

また、今のコマンド実行時に、go.modとgo.sumファイルが作成されているはずです。

docker compose up --build

http://localhost:3001へアクセスすると以下の画面のように表示されていたら、環境構築完了です。

3.3. PHPの環境を作ってみよう

次にPHPの環境を構築してみましょう。

ほとんど、Goと変わらないため、説明は省きます。

├── Dockerfile
└── index.phpind
FROM php:7.2-apache
<?php
    echo phpinfo();
services:
  php:
    build:
      dockerfile: ./Dockerfile
      context: .
    volumes:
      - ./:/var/www/html
    ports:
      - "3002:80"

compose.ymlのコンテナ側のポート番号80は、apacheのデフォルトなので80を設定しています。

それでは、以下のコマンドを実行して、起動してみましょう。

docker compose up --build

http://localhost:3002へアクセスすると以下の画面のように表示されていたら、環境構築完了です。

3.4. MySQLの環境を作ってみよう

services:
  db:
    build:
      dockerfile: ./Dockerfile
      context: .
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mysql-start
      MYSQL_USER: user
    ports:
      - "3306:3306"

volumes:
  db-data:
FROM mysql

起動しましょう。

docker compose up --build

起動後、コンテナ内で、mysql環境が作られているのか確認してもいいですが、わかりにくいため、DBのツールを使いましょう。何でもいいのですが、初めての方は以下のTable Plusがおすすめです。

https://tableplus.com/

こちらのダウンロード、インストールが完了したら以下の手順で接続してみてください

  • 1. アプリを開くと以下のような画面が表示されます。プラスボタンを押下してください。

  •  2. MySQLを選択してください。その後、Createを押下してください。

  • 3. 以下の画面に接続情報を入力します。

3.5. MySQLとPHPの環境を同時に作ってみよう

簡単です。少し修正は必要ですが、コードを合体させるだけでほとんどの作業は終了です。

まず、ディレクトリ構成を以下のようにしてください。

.
├── compose.yml
├── mysql
│   └── Dockerfile
└── php
    ├── Dockerfile
    └── index.php

お!Dockerfileが、2つになりました。ここで、違和感出てくる方もいらっしゃるかもしれないですね。

でも、これは当たり前なんです。Dockerfile1つで、1コンテナなので、PHP用のコンテナとMySQL用のコンテナが2つ作られると考えれば、2つあることは自然です。

また、これに、フロントエンドのコンテナも追加したい。となったときは、フロントエンド用のディレクトリを作成して、その中にDockerfileを作成すればいいのです。

まずは、mysqlディレクトリから説明します。

FROM mysql

先ほどの3.4.のMysql環境構築と変化がありませんね。当たり前です。docker imageを作成するDokcerfileに変更があることはありません。

次に、PHPのフォルダも見てみましょう。

<?php
    echo phpinfo();
FROM php:7.2-apache

これも、変化はありません。

変化があるのは、compose.ymlです。理由は2つ。階層の変化と2つのコンテナの操作があるためです。

services:
  php:
    build:
      dockerfile: ./php/Dockerfile  # 階層変化により変更
      context: .
    volumes:
      - ./php:/var/www/html  # 階層が変化するため .を./phpへ変更
    ports:
      - "3002:80"
    depends_on:    # 今回は触れないが、phpのアプリケーションがDBに接続するための依存関係を示している。
      - db

  db:
    build:
      dockerfile: ./mysql/Dockerfile  # 階層変化により変更
      context: .
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mysql-start
      MYSQL_USER: user
    ports:
      - "3306:3306"

volumes:
  db-data:

compose.ymlの行数は、増えているが、内容はディレクトリの変化によるパスの変更が主な変更点である。なので、1つ1つのコンテナをしっかり起動させることができれば、複数の環境を作ることはさほど難しくない。

アプリケーション(PHP)とDBへの接続については触れないが、理由は、Dockerの話ではなく、アプリケーションの話だからである。しかし、dockerによる環境構築を学んだ方なら、あとは自力で接続して、サービス開発をやっていってほしい。

4. 最後に

Docker超入門〜通常レベルまで Part4お疲れ様でした。

これで、Docker超入門〜通常レベルまでシリーズは、終了となります。

この内容をしっかりと理解できれば、自身で応用していって、フレームワークやこの記事で触れていない言語の環境構築も1人でできると思います。

快適なDocker生活を楽しんでいきましょう。

また、レベルアップした方向けに、AWSを使ったDockerの実務編。ここでは、応用編となるような記事を書いていく予定です。その時もぜひよろしくお願いします。☺️

 

何か、わからないことがあれば、コメントなどをしていただけると対応します。

コメントを送信

You May Have Missed