【前編】絶対に失敗しないDockerでLaravel + Vue.jsの開発環境(LEMP環境)を構築する方法〜MacOS Intel Chip対応〜

ゆーたろー

こんにちは、ゆーたろーです。

大阪のHRTechベンチャーのエンジニアです。
TypeScript/Vue.js(Nuxt.js)/Laravelを使っています。

・プログラミングスクール講師
・月1で勉強会運営
・Twitter(フォロワー4700人以上)で情報発信

など色々やっている1児のパパです。

Dockerで環境構築したいけどdocker-compose.ymlやDockerfile等の設定ファイルってどんな風に書けば良いの?

と疑問をお持ちの方のお悩みを解決できる記事になっています!

この記事は『【MacOS Intel Chip】絶対に失敗しないDockerでLaravel + Vue.jsの開発環境(LEMP環境)を構築する方法〜導入編〜』の続きです。

  • 使用ツール、アプリケーションのバージョン
  • 構築するDocker環境(LEMP環境)の概要説明

は導入編で解説しています。

まだ導入編を読み終わってない方は先にご覧ください。

この環境構築は

  • 導入編
  • 前編
  • 後編

に分けていますが、今回は『前編』です。

導入編ではDockerDocker Composeのインストールをしたり、構築に必要なディレクトリを作成しました。

前編では実際にDocker環境用の設定ファイルを作成していきます。

というわけで、Dockerを使ったLaravel+Vue.jsの開発環境の構築方法の前編を解説しますね!

目次

全体の手順

全体の手順はこちらです。

  • DockerとDocker Composeを使えるようにする ← 導入編はここまで
  • docker-compose.ymlを作成する
  • 環境変数を設定する
  • 各コンテナのDockerfileを作成する
  • 各ミドルウェアの設定ファイルを作成する
  • イメージの構築(buid)
  • コンテナの起動(up)
  • Laravelをインストールする
  • Vue.jsをインストール

この前編ではDocker環境を構築するために必要な設定ファイルを作成していきます。

docker-compose.ymlを作成する

各種ミドルウェアのコンテナの設定をしていきます。

複数のミドルウェア(今回だとNginxMySQLPHP)のコンテナを作成・管理する場合はDocker Composeを使います。

Docker Composeを使って複数のコンテナを一元管理するために設定ファイルであるdocker-compose.ymlを作成します。

docker-laravel-vueディレクトリ配下にdocker-compose.ymlを作成してください。

このディレクトリ構造になっていたらOKです。

docker-laravel-vue
├─ docker
│    ├─ php
│    ├─ nginx
│    └─ mysql
└─ docker-compose.yml ← コレ作成

docker-compose.ymlの完成形

まず始めに今回作成するファイルの全体のコードです。

version: '3.8'

volumes:
  mysql-volume:

services:
  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes:
      - ./src/:/var/www/html
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

  web:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    ports:
      - ${WEB_PORT}:80
    depends_on:
      - app
    volumes:
      - ./src/:/var/www/html

  db:
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    ports:
      - ${DB_PORT}:3306
    environment:
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      TZ: 'Asia/Tokyo'
    volumes:
      - mysql-volume:/var/lib/mysql

ここからこのdocker-compose.ymlに書いてあるコードの解説をしていきますね!

docker-compopse.ymlのバージョン

まずはこちらのコードです。

version: '3.8'

現在、docker-compose.ymlファイルを作成する場合はversion: '3.8'と書いておけばOKです。

versionはComposeファイルのバージョンでありDocker Compose自体のバージョンとは異なることに注意です。

公式サイトを確認いただけるとわかりますが、2021/5時点での最新バージョンが3.8です。
(3.9以降が出ている可能性もありますので公式サイトをご確認ください)

Webサーバー(Nginx)コンテナの設定について

WebサーバーにはNginxを使います。

Nginxコンテナの設定部分はこちらです。
(先程ご紹介したファイルにはappから記載しておりますが、先にwebから解説します)

services:
  
  (略)

  web:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    ports:
      - ${WEB_PORT}:80
    depends_on:
      - app
    volumes:
      - ./src/:/var/www/html

サービス名

  web:

services:直下にサービス名を設定します。

サービス名はwebとしました。
サービス名には命名の制約はないので自由に決めて良いですが、webnginxweb_serverがわかりやすく無難だと思います。

※サービス名はコンテナ名とは異なります。
(コンテナ名の設定は必須ではありませんので今回は設定しません)

ビルドするDockerfileの指定

    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile

buildオプションはコンテナの元となるイメージの設計書であるDockerfile(後ほど解説します)に関する設定を行います。

context、dockerfileオプションにはそれぞれ以下の内容を設定します。

  • context:ビルドコンテキスト(こちらの記事を参考にしてください)の設定
  • dockerfile:buildするDockerfileまでのパス

ローカルのdocker/nginxディレクトリにあるDockerfileを使ってDockerイメージを構築するという設定です。

ちなみにビルドコンテキストは公式サイトにはこのように記載されています。

docker buildコマンドを実行したときの、カレントなワーキングディレクトリのことを ビルドコンテキスト(build context)と呼びます。 デフォルトで Dockerfile は、カレントなワーキングディレクトリにあるものとみなされます。 ただしファイルフラグ(-f)を使って別のディレクトリとすることもできます。 Dockerfileが実際にどこにあったとしても、カレントディレクトリ配下にあるファイルやディレクトリの内容がすべて、ビルドコンテキストとして Docker デーモンに送られることになります。

https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/dockerfile_best-practices/#%E3%83%93%E3%83%AB%E3%83%89%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E7%90%86%E8%A7%A3

ここまでに何度か登場しているDockerfileについては後ほど解説します。

ports

portsローカル(お使いのPC)とDockerコンテナ間のポート番号の対応付けを設定するオプションです。

    ports:
      - ${WEB_PORT}:80

portsオプションは

{ローカルのポート番号}:{Dockerコンテナのポート番号}

の形で書くので、ローカルの80番ポート(${WEB_PORT}になっていますが後ほど80を設定します)とNginxコンテナの80番ポート(80はNginxのデフォルトポート番号)を対応させています。

この設定でNginxコンテナが起動している状態でローカルのlocalhost:80にアクセスするとNginxの80番ポートにアクセスすることができます。

※既に他にDocker環境等でlocalhost:80を使って開発している場合は、ローカルのポート番号を適宜変更してください。コンテナ側(:の右側)は80から変えなくてOKです。

depends_on

depends_onコンテナ間の依存関係を設定するオプションです。

    depends_on:
      - app

appはPHP(アプリケーション)コンテナです。

NginxはPHPを実行するため、PHP→Nginxの順にコンテナを起動するように設定しています。

depends_on:
– 先に起動するコンテナのサービス名

初めて環境構築する方はちょっと難しいなと感じるかもしれませんがここはあまり深く考えずに進んでもOKです。

volumes

volumesローカルとDockerコンテナ間のディレクトリ・ファイル等のリソースを対応つける設定するオプションです。

    volumes:
      - ./src/:/var/www/html

ローカルの./srcとDockerコンテナの/var/www/htmlを対応つけています。
.はカレントディレクトリを表します)

volumesオプションはローカルのリソースとDockerコンテナ内のリソースを:で対応させます。

volumes:
– (ローカルのリソース):(Dockerコンテナのリソース)

この設定によりDockerコンテナ内の/var/www/htmlにいる場合にローカルの./src以下のディレクトリ、ファイルがそこにあるように(実際にはない)共有することができます。
(上手く説明するのが難しいのでわかりづらかったらすみません…)

ここはDocker環境を構築する上でもしっかり理解しておくべき内容だと思います。

これでNginxコンテナの設定は終わりです。

アプリケーション(PHP)コンテナの設定について

Laravelの開発環境を構築するのでアプリケーションはPHPです。

PHPコンテナの設定部分はこちらです。

services:
  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes:
      - ./src/:/var/www/html
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

サービス名

サービス名はappにしてます。Nginxコンテナ同様任意ですが、他にはphpphp_serverが無難かと思います。

ビルドするDockerfileの指定

    build:
      context: .
      dockerfile: ./docker/php/Dockerfile

ローカルのdocker/phpディレクトリにあるDockerfileを使ってDockerイメージを構築するという設定です。

volumes

    volumes:
      - ./src/:/var/www/html

Nginxコンテナの設定でも/var/www/htmlが出ましたがこれは覚えておいて良いと思います。

もう少し深く理解したい方は以下の記事を読んでみてください。

environment

environmentは『環境』という文字通りですが、環境変数を設定するオプションです。

environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

PHPコンテナでの環境変数の設定はLaravel側で行う方法(Laravelプロジェクトに.envに設定します)でも問題ないのでDocker環境を構築する上では必須ではありませんので、この設定は丸々なくても問題ありません。

今回はDockerコンテナを起動する際に設定しておく方法なので記載しています。

ここでも${DB_NAME}${DB_USER}${DB_PASSWORD}が登場していますが、詳細については後ほど解説します。
(これも環境変数です)

説明はかなりざっくりですが、これでPHPコンテナの設定は終わりです。

DBサーバー(MySQL)コンテナの設定について

DBは多くのWebアプリーションで使用されているMySQLを使います。

MySQLコンテナの設定部分はこちらです。

services:

  (略)
  
  db:
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    ports:
      - ${DB_PORT}:3306
    environment:
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      TZ: 'Asia/Tokyo'
    volumes:
      - mysql-volume:/var/lib/mysql

サービス名

サービス名はdbにしてます。ここも任意ですが、他にはmysqldb_serverが無難かと思います。

ビルドするDockerfileの指定

    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile

ローカルのdocker/mysqlディレクトリにあるDockerfileを使ってDockerイメージを構築するという設定です。

ports

    ports:
      - ${DB_PORT}:3306

ローカルの3306番ポート(${DB_PORT}になっていますが後ほど3306を設定します)とMySQLコンテナの3306番ポート(3306はMySQLのデフォルトポート番号)を対応させています。

Nginxコンテナと同様に、既に他にDocker環境等でローカルの3306番ポート使用している場合は、ローカルのポート番号を適宜変更してください。

コンテナ側(:の右側)は3306から変えなくてOKです。

environment 

MySQLの環境変数を設定します。

    environment:
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      TZ: 'Asia/Tokyo'
  • MYSQL_DATABASE:DBの名前(好きな名前でOK)
  • MYSQL_USER:MySQLのユーザー名(好きな名前でOK)
  • MYSQL_PASSWORD:MySQLのパスワード(好きな名前でOK)
  • MYSQL_ROOT_PASSWORD:ルート権限のパスワード(好きな名前でOK)
  • TZ:時間設定(Time Zone)

ここでも${***}が登場していますが、解説はもう少し待ってくださいね。

volumes

volumesは先ほどまでと同じ考え方ですが、データベースの場合はDocker VolumeというDockerのオプションを使用します。

    volumes:
      - mysql-volume:/var/lib/mysql

Docker Volumeとはデータを永続的に保存できるようにする仕組みのことで、保存場所のことvolume(ボリューム)と呼びます。

「なぜデータベースの時にボリューム(という場所)を使うのか」というと、Docker Volumeを使わない場合、コンテナは停止する時にただ停止するのではなくコンテナを破壊(消去)するので、データベースに保存していたデータがコンテナの停止と共にに消えてしまうからです。

なので開発するWebアプリケーションで扱うデータの保存先であるボリュームを用意する必要があるわけです。

このDocker Volumeで作成するボリュームはコンテナとは別に独立した領域なのでコンテナが破壊(消去)されても存在し続けます。

コンテナの動作は簡単にいうと『起動→停止(&破壊)』です。

もう一度起動する時は新たなコンテナを立ち上げます。

上の設定コードからローカルのmysql-volumeというボリュームとMySQLコンテナの/var/lib/mysqlを対応させています。

Docker Volumeの定義はdocker-compose.ymlの上部に記載しています。

volumes:
  mysql-volume:

Docker Volumeはちょっと難しい概念だと思いますので、もっと知りたい!という方はこちらの記事がわかりやすかったので読んでみてください。

以上で3つのミドルウェア(Nginx、MySQL、PHP)のコンテナの設定が完了です。

環境変数を設定する

次に環境変数の設定です。

ここまで何度か登場してきた${****}に値を設定する作業が今からです。

.envの作成

docker-laravel-vueディレクトリで.envという名前のファイルを作成してください。

docker-laravel-vue
├─ docker
│    ├─ php
│    ├─ nginx
│    └─ mysql
│─ .env ← コレ作成
└─ docker-compose.yml

.envを作成したらまずこのように書きます。

WEB_PORT=
DB_PORT=

DB_NAME=
DB_USER=
DB_PASSWORD=
DB_ROOT_PASSWORD=

ここに書いているそれぞれの項目はdocker-compose.ymlに書いている${****}の中身と一致しています。

.envdocker-compose.ymlは同じ階層に存在しているため、.envに定義した値(これを環境変数を言います)を${****}の形で使うことができます。

それでは.envのそれぞれの環境変数の値を定義します。

WEB_PORT=80
DB_PORT=3306

DB_NAME=db_name
DB_USER=db_user
DB_PASSWORD=db_password
DB_ROOT_PASSWORD=root

DB関連の環境変数は一例としてとても簡単(推測されやすい)な値にしていますので適宜変更してください。(命名は自由です)

DBの接続情報(ユーザー名、パスワード)や個人情報等、公開範囲をローカルだけにしておきたい情報は.envに定義して他のファイルで呼び出すことが望ましいです。

GitHubにpushしたら世界中にDBのユーザー名とパスワードが公開されてしまいますからね…

ただ、今のままだとGit管理した場合、.envもGitHubにうっかりpushしてしまう可能性があるのでGit管理下から外しておきます。

.gitignoreの作成

docker-laravel-vueディレクトリで.gitignoreという名前のファイルを作成してください。

docker-laravel-vue
├─ docker
│    ├─ php
│    ├─ nginx
│    └─ mysql
│─ .env
│─ .gitignore ← コレ作成
└─ docker-compose.yml

.gitignoreGit管理から外すリソースを定義するファイルです。

先ほど作成した.envを追加します。

.env

これで.envをうっかりGithubにpushすることを防ぐことができます。

各コンテナのDockerfileを作成する

ここまででも既に結構なボリュームがありますが、もう少し頑張りましょう!

次はコンテナの元となるイメージの設計書であるDockerfileを作成します。

phpnginxmysqlディレクトリそれぞれの下にDockerfileという名前のファイルを作成します。

docker-laravel-vue
├─ docker
│    ├─ php
│    │   └─ Dockerfile ← コレ作成
│    ├─ nginx
│    │    └─ Dockerfile ← コレ作成
│    └─ mysql
│         └─ Dockerfile ← コレ作成
│─ .env
│─ .gitignore   
└─ docker-compose.yml

それぞれのDockerfileのコードを解説していきます。

PHP用のDockerfile

PHPコンテナにはLaravel+Vue.jsを使うために以下の2つのインストールが必要です。

  • Composer:パッケージ管理ツールであり、Laravelをインストールするために必要
  • npm:パッケージ管理ツールであり、Vue.jsをインストールするために必要

もし、フロントエンドにVue.jsを使わない場合(JavaScriptオンリー)は該当の箇所を読み飛ばしてください。

完成形のコード

こちらがDockerfileの中身です。

FROM php:7.4.1-fpm

# php.iniをコピー
COPY ./docker/php/php.ini /usr/local/etc/php/php.ini

# Composer install
COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

#node.js install
COPY --from=node:10.22 /usr/local/bin /usr/local/bin
COPY --from=node:10.22 /usr/local/lib /usr/local/lib

RUN apt-get update \
    && apt-get install -y \
    git \
    zip \
    unzip \
    vim \
    && docker-php-ext-install pdo_mysql bcmath

WORKDIR /var/www/html

Dockerfileの中身をざっくりですが解説します。

php.iniのコピー

# php.iniをコピー
COPY ./docker/php/php.ini /usr/local/etc/php/php.ini

ローカルで作成するphp.ini(PHPの設定ファイル)をDockerコンテナ内にコピーするコマンドを書いています。

php.iniは後編で作成します。

イメージのベースを指定

FROM php:7.4.1-fpm

今回構築するPHPコンテナはphp:7.4-fpmのイメージをベースに作成します。

composerをインストール

# Composer install
COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

Composerをインストールする方法はいくつかありますが、今回はマルチステージビルド公式ドキュメント)という方法を採用します。

npmをインストール

フロントエンドにVue.jsを導入しない方はこちらは飛ばしてもらってOKです。

#node.js install
COPY --from=node:10.22 /usr/local/bin /usr/local/bin
COPY --from=node:10.22 /usr/local/lib /usr/local/lib

npmのインストールもComposer同様マルチステージビルドを採用しています。

パッケージ管理ツールの更新とパッケージのインストール

次にパッケージ管理ツールの更新と構築する環境に必要なパッケージ、ライブラリをインストールします。

RUN apt-get update \
    && apt-get install -y \
    git \
    zip \
    unzip \
    vim \
    && docker-php-ext-install pdo_mysql bcmath

Docker Desktop(Docker for Mac)の場合はapt-getというパッケージ管理ツールを使います。

まず、apt-getを更新します。

RUN apt-get update

ここに繋げてパッケージやPHP拡張モジュールをインストールします。

    && apt-get install -y \
    git \
    zip \
    unzip \
    vim \
    && docker-php-ext-install pdo_mysql bcmath

コンテナに入った時の作業ディレクトリを指定

PHPコンテナに入った時の作業ディレクトリ(つまりカレントディレクトリ)を指定します。

WORKDIR /var/www/html

docker-compose exec app bashというコマンドでappコンテナの中に入った場合、/var/www/htmlがカレントディレクトリになります。

これでPHP用のDockerfileの解説は終わりです。

Nginx用のDockerfile

次はNginx用のDockerfileを作成します。

こちらが完成形です。

FROM nginx:1.18

ENV TZ=UTC

# nginx config file
COPY ./docker/nginx/*.conf /etc/nginx/conf.d/

WORKDIR /var/www/html

PHP用のDockerfileで解説した内容とほぼ同じなので(かなり)ざっくりまとめます。

  • イメージのベースを指定
  • 環境変数(TZ)を定義
  • Nginxの設定ファイルをコンテナ内にコピーして対応づける
  • コンテナに入った時の作業ディレクトリを指定

MySQL用のDockerfile

最後にMySQL用のDockerfileを作成します。

こちらが完成形です。

FROM mysql:8.0

ENV TZ=UTC

COPY ./docker/mysql/my.cnf /etc/my.cnf

先ほどと同様、(かなり)ざっくりまとめます。

  • イメージのベースを指定
  • 環境変数(TZ)を定義
  • MySQLの設定ファイルをコンテナ内にコピーして対応づける

これでPHP、Nginx、MySQLそれぞれのイメージの設計書となるDockerfileのが作成できました。

M1 Macの方へ

この記事の執筆時時点ではMySQLのイメージがM1に対応できていないので少し修正が必要です。

修正内容をこちらにまとめています。

最後に

これで

  • 複数のコンテナの設定を行うdocker-compose.yml
  • イメージの設計書となるDockerfile

の作成が完了しました。

また、DBの接続情報を.envで管理しセキュリティ面を考慮する方法も解説しました。

前編はこれで完了です。

お疲れ様でした!

少し休憩して最後の後編に進んでください。

オススメ教材

Laravel

PHPフレームワークLaravel入門 第2版(通称:青本)

定番の青本です。これからLaravelを学習したいという方全員にオススメできる入門書です。
今買うなら上記リンクから飛べるLaravel6対応版の青本を強くオススメします。

PHPフレームワーク Laravel実践開発(通称:緑本)

青本と同じ著者が執筆した技術書で青本の次に読むとLaravelの理解がかなり深まります。
Laravelの基礎は身についた方にオススメです。

Docker

Udemy:米国AI開発者がゼロから教えるDocker講座

Dockerを1から学習したい方にとてもオススメする教材です。
僕はこの教材でしか勉強をしていませんが、実務で困らないレベルまで理解することができました。

Vue.js

【超オススメ】Udemy:超Vue.js 2 完全パック (Vue Router, Vuex含む)

Vue.jsを勉強したい全ての方にオススメできる教材です。
Vue.jsの基礎〜応用まで網羅できるプラス、Vue Router、Vuex、AxiosなどVue.jsでのフロントエンド開発には欠かせないパッケージについても学習できます。超オススメ。

Vue.js&Nuxt.js超入門

書籍でVue.jsを勉強して、Vue.jsのフレームワークNuxt.jsも学習したい方にオススメです。
(僕はNuxt.js学習用に購入しました)

“頭おかしい”プログラミングスクール『やんばるエキスパート』

内定者続出のエンジニア転職特化オンラインコミュニティ『転職クエスト』

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

上場グループのHRTechベンチャーで働くWebエンジニアです。
新卒で入社した大手重工メーカを4年で退職し、2020年4月からエンジニアとキャリアチェンジしました。

仕事ではTypeScript/Vue.js(Nuxt.js)/Laravelを主に使っています。

プログラミングスクールの講師やデザイン関連のお仕事もさせてもらっています。

神戸で「つながる勉強会」という勉強会を月1で運営しています。
https://tsunagaru-kobe.connpass.com/

お仕事のご依頼、ご相談はお問い合わせページもしくはTwitterのDMからお願いします。

コメント

コメントする

目次
閉じる