PROGRAMMING

【シンプル解説】docker-composeを使ってLaravel,nginx,MySQL環境構築する

こんにちは。もんしょー(@sima199407)です。

悩んでいる人
悩んでいる人
dockerを使った開発環境の作り方が知りたい

という疑問に答えていきます。

完成ソースコードはこちら

動画でも解説してます

作成する開発環境

以下の通りです。

laravel7系
nginx
mysql8系
phpmyadmin

ディレクトリ構造

構造は以下の通りです。

$ tree
.
├── docker-compose.yml
└── docker-config
    ├── mysql
    │   ├── data
    │   └── my.cnf
    ├── nginx
    │   ├── Dockerfile
    │   └── default.conf
    └── php
        ├── Dockerfile
        └── php.in

PHPのファイル

今回作成するのはDockerfileとphp.ini

/docker-config/php/Dockerfile

FROM php:7.2-fpm
COPY php.ini /usr/local/etc/php/

# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

# install packages
RUN apt-get update \
  && apt-get install -y \
    gcc \
    make \
    libpng-dev \
    git \
    unzip \
    vim \
    libmcrypt-dev \
    mariadb-client \
    curl \
    gnupg \
    openssl \
    zlib1g-dev \ 
    && docker-php-ext-install pdo_mysql mysqli mbstring zip

# install stable node and latest npm
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash
RUN apt-get install -y nodejs

# install xdebug
RUN pecl install xdebug-2.7.2 && docker-php-ext-enable xdebug

WORKDIR /var/www
ADD . /var/www
RUN chown -R www-data:www-data /var/www

Laravelを入れるので、composerが必要になります。
合わせて、npmも使うので、node.jsも必須です。

docker-config/php/php.ini

phpの初期設定のファイルになります。

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
[xdebug]
xdebug.remote_enable = On
xdebug.remote_port = 9001
xdebug.remote_autostart = On
xdebug.remote_host = 192.168.99.1
xdebug.profiler_output_dir = "/tmp"
xdebug.max_nesting_level= 1000
xdebug.idekey = "PHPSTORM"

date.timezone = "Asia/Tokyo"とタイムゾーンを合わせておくことはしましょう。

nginxのファイル

Dockerfileとdefault.confを使います。

/docker-config/nginx/Dockerfile

FROM alpine:3.6

# nginxのインストール
RUN apk update && \
    apk add --no-cache nginx
RUN mkdir -p /run/nginx
# RUN apk add openssl
# ADD ssl /etc/nginx/ssl

# フォアグラウンド
CMD nginx -g "daemon off;"

ポイントは軽量化のためにalpineを使っているということ。

ファイルが多くなってくるとストレージをひっ迫するので、最低限の要素のみを入れることができます。

alipineの説明:alipine-docker Hub

/docker-config/nginx/default.conf

server {
    index index.php index.html;
    root /var/www/laravel/public;

    location / {
      root /var/www/laravel/public;
      try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass web:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

rootの部分をlaravelのpublicに合わせてます。

MySQLのファイル

ここでは、my.cnfがあります。
MySQLはDockerfileではなく、docker-compose内に設定しています。

/docker-config/mysql/my.cnf

以下の通り。

# MySQLサーバーへの設定
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin

# タイムゾーン
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# mysql8.0用に認証変更
default-authentication-plugin = mysql_native_password


# エラーログの設定
# log-error = /var/log/mysql/mysql-error.log

# スロークエリログ
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 5.0
log_queries_not_using_indexes = 0

# 実行ログ
general_log = 1
general_log_file = /var/log/mysql/mysql-query.log

# mysqlオプションの設定
[mysql]
default-character-set = utf8mb4

# mysqlクライアントツールの設定
[client]
default-character-set = utf8mb4

 

ポイントは、default-authentication-plugin = mysql_native_passwordでして、5系の時は、設定が必要なかったんですが、8系から認証の方法が変わったので、以前と同じような使用にするために設定します。

docker-composeとは?

そもそも何かって言うと、dockerの管理ファイルようなものです。

ここで、Dockerfile指定をしたり、コンテナの設定をしたりすることができます。

version: '3' 

services:
    
  web: 
    build: ./docker-config/php
    container_name: app_php
    volumes:
      - ./laravel:/var/www/laravel
    working_dir: /var/www/laravel
    depends_on:
      - mysql

  nginx:
    image: nginx
    container_name: app_nginx
    build: ./docker-config/nginx
    ports:
      - "80:80"
    volumes:
      - .:/var/www
      - ./docker-config/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web

  mysql:
    image: mysql:8.0
    container_name: app_db
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: development
      MYSQL_ROOT_USER: root
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: m_user
      MYSQL_PASSWORD: m_user
      TZ: 'Asia/Tokyo'
      
    volumes:
      - ./docker-config/mysql/data:/var/lib/mysql
      - ./docker-config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf

    depends_on:
      - mysql-volume

  mysql-volume:
    image: busybox
    volumes:
      - ./docker-config/mysql/data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: app_pma
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=root
      - PMA_PASSWORD=root
    links:
      - mysql
    ports:
      - 8080:80
    volumes:
      - /sessions

services: のwebとかnginxは任意で変えることができます。

build: ./docker-config/phpと言うのが、Dockerfileの場所を指しております。

working_dir: /var/www/laravelをつけることによって、コンテナに入った時にこのディレクトリから作業をすることができます。

depends_on:
- mysql
は、コンテナを立ち上げる順番を指してまして、今回の場合だったら、mysqlコンテナを立ち上げてからwebコンテナを立ち上げると言うことです。

mysql:mysql-volume:volumes:は揃えることでデータの保存場所を統一させます。これでコンテナを停止した後もデータを保持します。

 

立ち上げ方

docker-composeコマンドを使います。.ymlファイルがある階層でコマンドを叩きます。

docker-compose up -d --build

upと言うのが、コンテナの立ち上げです。逆にdownを使うと停止して、コンテナを削除になります。

オプションの-d はデタッチド・モード: バックグラウンドでコンテナを実行するということです。

--buildがDockerfileの再読み込みをしてくれて、更新した情報を反映してくれます。

これで立ち上がるはずです。

動作を確認する

コンテナが立ち上がっているか確認しましょう。

docker ps

CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                               NAMES
985bf4968d56        nginx                       "/bin/sh -c 'nginx -…"   3 hours ago         Up 2 minutes        0.0.0.0:80->80/tcp                  app_nginx
ce3884c56d5e        phpmyadmin/phpmyadmin       "/docker-entrypoint.…"   3 hours ago         Up 2 minutes        0.0.0.0:8080->80/tcp                app_pma
b074c9aa9a1f        laravel-nginx-mysql80_web   "docker-php-entrypoi…"   3 hours ago         Up 2 minutes        9000/tcp                            app_php
1456a01d168c        mysql:8.0                   "docker-entrypoint.s…"   3 hours ago         Up 9 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   app_db

こんな感じになっているはず。

これで、http://localhost/にアクセスすれば、

出来上がりです。

エラーになる部分や疑問点あればtwitterにご連絡いただければと思います。

dockerのコマンド紹介

コマンドは忘れやすいのでよく使うものを紹介します。

docker ps

動いているコンテナを確認

docker ps -a

全てのコンテナを確認

docker logs [CONTAINER ID]

コンテナのログを確認

docker exec -it [NAMES] bash(or sh)

コンテナ内に入る(bashで入れない時はshを使う)

docker-compose up -d --build

コンテナを立ち上げる

docker-compose down

コンテナを停止、削除する

docker-compose down --rmi all --volumes

【結構危険】コンテナを停止、削除するさらにイメージファイルを削除、volumesを削除。