LoginSignup
1

posted at

updated at

【Docker+Laravel6】開発環境構築についてまとめてみました

背景

AWSでの本番環境構築にむけてポートフォリオ開発を進めていたところ、以前の開発環境が簡易的で必要な設定がされておらず、環境依存が起こってしまう可能性が高いと考えたので、本番環境構築前に整えておこうという目的で再構築しました。

今回は再構築、初構築両方に対応できるように手順を記載しました。
状況に応じて実行、スキップします。

  • GitHubリポジトリ

開発環境について

前提条件

  • Dockerインストール済み
  • VScodeインストール済み(Vimでも大丈夫です)

開発環境

  • OS : Mac
  • Docker 20.10.12
  • Docker Compose v2.2.3
    • Docker image
      • laravel-app(appコンテナ)
        • php7.4-fpm-alpine(nginx,php-fpm,supervisor)
        • Laravel 6.20.34
      • laravel-db(mysqlコンテナ)
        • MySQL 8.0.27

開発環境ディレクトリ構成

docker/dev配下
.
├── app
│   ├──nginx
│   │   ├──dev.ドメイン名.conf
│   │   └──nginx.conf
│   ├──php
│     │   ├──config.inc.php
│     │   ├──php-fpm.conf
│     │   ├──php.ini
│      │   └── www.conf
│   ├──supervisor
│   │   ├──app.conf
│   │   └──supervisord.conf
│   └──Dockerfile
├──mysql
│   ├──Dockerfile
│   └──my.cnf
└──docker-compose.yml

開発環境構成図

スクリーンショット 2022-03-07 1.22.05.png

構築手順(サマリー)

手順 説明
ディレクトリ作成 ホームディレクトリにgit/githubディレクトリを作成
git clone 作業ディレクトリに元の開発環境をgit cloneする
※初めて構築する場合はスキップ
作業ディレクトリ作成 git/github配下に作業ディレクトリを作成
※初めて構築する場合のみ実行
LEMP環境設定 appコンテナ,mysqlコンテナ,docker-compose.ymlの設定
docker run コンテナの構築と起動
Laravel install appコンテナに入り、Laravelのインストールを行います
※初めて構築する場合のみ実行
app deploy appコンテナ内でcomposer install, マイグレーション(初めて構築する場合はスキップ)など実行
Access 設定したドメイン名でアクセス確認
DB login MySQLにログインできることを確認
Vue.js install ※Vue.jsを使用する場合に実行

構築手順

ディレクトリ作成

  • git/github配下に開発環境を構築します。
  • git/github配下に移動
~/
$ mkdir -p ~/git/github
$ cd ~/git/github

git clone

初めて構築する場合はスキップ

  • GitHubリポジトリをcloneする。
  • クローンしたディレクトリに移動
~/git/github/
$ git clone リモートリポジトリURL
$ cd クローンしたディレクトリ

作業ディレクトリ作成

初めて構築する場合のみ実行

  • git/github配下に任意のディレクトリを作成。
    このディレクトリで開発をしていきます。
  • 作成したディレクトリに移動
~/git/github/
$ mkdir 任意のディレクトリ名
$ cd 作成したディレクトリ

LEMP環境設定

docker/devディレクトリ作成

  • docker/devディレクトリ作成
  • docker/dev配下に移動
~/git/github/クローンしたリポジトリ
$ mkdir docker
$ mkdir docker/dev
$ cd docker/dev

各ディレクトリ, docker-compose.yml作成

  • app, mysqlディレクトリ作成
  • docker-compose.yml作成
docker/dev/
$ mkdir app mysql
$ touch docker-compose.yml

appコンテナ設定

  • appディレクトリに移動
  • nginx, php, supervisorディレクトリ作成
  • Dockerfile作成
docker/dev/
$ cd app
$ mkdir nginx php supervisor
$ touch Dockerfile

nginx設定

  • nginx配下に移動
  • dev.ドメイン名.conf, nginx.conf作成
app
$ cd nginx
$ touch dev.ドメイン名.conf nginx.conf
  • dev.ドメイン名.conf設定
dev.ドメイン名.conf
server {
    listen       80;
    server_name  dev.ドメイン名;

    root /var/www/app/public;
    index index.php index.html index.htm;

    access_log  /var/log/nginx/dev.access.log main;
    error_log  /var/log/nginx/dev.error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }
}

設定ファイル内の説明

設定 説明
server{} バーチャルホスト定義
listen 80; 使用するポート指定
server_name 使用するホスト名(ドメイン名を指定)
root /var/www/app/public; 公開するディレクトリ指定
index index.php index.html index.htm; index.phpというファイルが存在すれば、"/public/index.php"に内部リダイレクト。
index.phpが在せず、index.htmlが存在すれば、/public/index.phpに内部リダイレクト。
access_log /var/log/nginx/dev.access.log main; エラーログの出力先を設定
error_log /var/log/nginx/dev.error.log; アクセスログの出力先を設定
location / {} リクエストされたURIにマッチししたときに使われる設定。
設定は{}内に書く
try_files $uri $uri/ /index.php?$query_string; $urlにファイルがあるか、そしてディレクトリがあるかの確認。なければ/index.php$query_string へ内部リダイレクトする
location ~ .php$ {} location ~ .php$の設定に従い、php-fpmを経由してLaravelの開始スクリプトのindex.phpが実行される

location ~ .php$ {}内の設定については以下記事の説明が参考になります

  • nginx.conf設定

include /etc/nginx/conf.d/*.conf;で先程設定したdev.ドメイン名.confを読み込んでいます。
通常はnginx.confに直接書き込みますが、複数のバーチャルホストの設定を仮定してファイルを分割しました

nginx.conf
user root;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid       /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '[nginx]\t'
                    'time:$time_iso8601\t'
                    'server_addr:$server_addr\t'
                    'host:$remote_addr\t'
                    'method:$request_method\t'
                    'reqsize:$request_length\t'
                    'uri:$request_uri\t'
                    'query:$query_string\t'
                    'status:$status\t'
                    'size:$body_bytes_sent\t'
                    'referer:$http_referer\t'
                    'ua:$http_user_agent\t'
                    'forwardedfor:$http_x_forwarded_for\t'
                    'reqtime:$request_time\t'
                    'apptime:$upstream_response_time\t';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    keepalive_timeout 65;

    gzip  on;
	gzip_static on;
    gzip_http_version 1.0;
    gzip_disable "msie6";
    gzip_proxied any;
    gzip_min_length 1024;
    gzip_comp_level 6;
	gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    proxy_buffer_size 32k;
    proxy_buffers 50 32k;
    proxy_busy_buffers_size 32k;

    include /etc/nginx/conf.d/*.conf;
}

PHP設定

  • php配下に移動
  • config.inc.php, php-fpm.conf, php.ini, www.conf 作成
$ cd ../php
$ touch config.inc.php php-fpm.conf php.ini www.conf

以下のファイル設定についてはかなりの文字数となるため掲載は諦めました。
私のポートフォリオの設定ファイルがそれになります。
ご参考までに。

  • config.inc.php
  • php-fpm.conf
  • php.ini
  • www.conf

参考:PHP設定(GitHub)

supervisor設定

  • supervisor配下へ移動
  • app.conf, supervisord.conf作成
  • app.conf, supervisord.conf設定

Supervisorでnginx(webサーバー)とphp-fpm(アプリの起動)の起動プロセスを一括管理しています。

参考:Supervisor を Docker で使う

$ cd ../supervisor
$ touch app.conf supervisord.conf
app.conf
[supervisord]
nodaemon=true
[program:app]
command=/usr/local/sbin/php-fpm -F
autorestart=true
stopsignal=TERM
user=root
directory=/var/www/app/
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stopsignal=TERM
user=root
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
supervisord.conf
[unix_http_server]
file=/run/supervisord.sock

[supervisord]
logfile=/var/log/supervisord.log
loglevel=info
pidfile=/var/run/supervisord.pid

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///run/supervisord.sock

[include]
files = /etc/supervisor.d/*.ini
files = /etc/supervisor/conf.d/app.conf

Dockerfile設定

Dockerfile
FROM php:7.4-fpm-alpine
ENV APP_ROOT /var/www/app
WORKDIR $APP_ROOT

# Setup UTC+9
RUN apk --update add tzdata && \
  cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
  apk del tzdata && \
  rm -rf /var/cache/apk/*

# install packages
RUN apk update && \
  apk upgrade && \
  apk add --update --no-cache \
  autoconf \
  bash \
  build-base \
  curl-dev \
  freetype-dev \
  g++ \
  gcc \
  git \
  libjpeg-turbo-dev \
  libpng-dev \
  libxml2-dev \
  libxslt-dev \
  make \
  mysql-dev \
  mysql-client \
  nginx \
  openssh \
  openssl \
  py3-pip \
  sudo \
  supervisor \
  tzdata \
  vim \
  redis \
  yaml-dev \
  zlib-dev

RUN docker-php-ext-install pdo_mysql soap

RUN docker-php-ext-configure gd \
  --with-freetype=/usr/include/ \
  --with-jpeg=/usr/include/ && \
  NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
  docker-php-ext-install -j${NPROC} gd

# Install awscli
RUN pip install awscli

# PHP
RUN rm -f /usr/local/etc/php-fpm.conf.default
RUN rm -f /usr/local/etc/php-fpm.d/zz-docker.conf
COPY php/php-fpm.conf /usr/local/etc/php-fpm.conf
COPY php/php.ini /usr/local/etc/php/php.ini
COPY php/www.conf /usr/local/etc/php-fpm.d/www.conf

# Install xdebug
RUN pecl install xdebug redis
RUN docker-php-ext-enable xdebug

# composer install
RUN curl -sS https://getcomposer.org/installer | php -- --version=1.9.1 --install-dir=/usr/bin
RUN mv /usr/bin/composer.phar /usr/bin/composer

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

## nginx
ADD nginx/nginx.conf /etc/nginx/nginx.conf
ADD nginx/dev.ドメイン名.conf /etc/nginx/conf.d/dev.ドメイン名.conf

# setting superviser
COPY supervisor/supervisord.conf /etc/supervisord.conf
COPY supervisor/app.conf /etc/supervisor/conf.d/app.conf
RUN echo files = /etc/supervisor/conf.d/*.conf >> /etc/supervisord.conf

EXPOSE 80
CMD ["/usr/bin/supervisord"]
設定 説明
FROM ベースイメージ。php:7.4-fpm-alpine
ENV 環境変数
WORKDIR 指定したディレクトリでWORKDIR以下の命令が実行される。今回はENVで定義されたAPP_ROOT(=/var/www/app)
RUN 実行コマンド
ADD ファイルを追加する命令
EXPOSE コンテナ実行時にリッスンするポートやプロトコルをDockerに通知する命令。
CMD コンテナの初期設定の命令。Dockerfileの中で1つだけ指定できる。
複数書いた場合は最後に書いたものが実行される。
supervisordを指定し、管理対象ファイルを実行。

参考:Dockerfileリファレンス

MySQLコンテナ設定

  • mysql配下に移動
  • Dockerfile, my.cnf作成
  • Dockerfile, my.cnf設定
$ cd ../../mysql
$ touch Dockerfile my.cnf
Dockerfile
FROM --platform=linux/x86_64 mysql:8.0.27

ENV TZ Asia/Tokyo
ENV LC_ALL ja_JP.UTF-8
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
RUN apt-get update
RUN apt-get install -y --no-install-recommends\
  locales \
  python \
  vim \
  && apt-get clean \
  && rm -rf /var/cache/apt/archives/* \
  /var/lib/apt/lists/*

RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
  locale-gen ja_JP.UTF-8

# Setup MySQL
RUN touch /var/log/mysqld.log \
  && chown mysql:adm /var/log/mysqld.log

RUN mkdir /var/mysql \
  && chown mysql:adm /var/mysql \
  && rm -rf /etc/mysql/conf.d

COPY ./my.cnf /etc/mysql/
my.cnf
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
disable_log_bin
log-error=/var/log/mysqld.log

character_set_server=utf8mb4
collation-server=utf8mb4_bin
default-authentication-plugin = mysql_native_password
default-time-zone='+9:00'

innodb_file_per_table=ON
innodb_buffer_pool_size=4G
#innodb_log_file_size=1G
join_buffer_size=256K
read_buffer_size=1M
read_rnd_buffer_size=2M
sort_buffer_size=4M
max_heap_table_size=16M
tmp_table_size=16M
thread_cache_size=100
wait_timeout            = 86400
max_allowed_packet      = 1G
innodb_buffer_pool_size = 1G
max_allowed_packet = 16M
innodb_strict_mode = 0
long_query_time = 5

sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

[mysql]
default-character-set=utf8mb4

docker-compose.yml設定

  • dev配下に移動
  • docker-compose.yml設定
$ cd ../
docker-compose.yml
version: '2'
services:
    app:
        container_name: アプリ名-app
        build: ./app/
        image: アプリ名-app
        ports:
            - '80:80'
        volumes:
            - ~/git/github/アプリのディレクトリ名:/var/www/app:delegated
        tty: true
        depends_on:
            - db
    db:
        container_name: アプリ名-db
        build: ./mysql/
        image: アプリ名-db
        command: --default-authentication-plugin=mysql_native_password
        ports:
            - '3306:3306'
        environment:
            MYSQL_DATABASE: アプリのディレクトリ名
        volumes:
            - ./mysql/db_data:/var/lib/mysql
設定 説明
version Composeファイルのバージョン。参考:公式サイト
services サービスの指定。サービス名:app, db
container_name コンテナ名:アプリ名-app, アプリ名-db(分かりやすい名前が無難)
build サービスをビルドする。Dockerfileを使ってDockerイメージを構築
image イメージ名:アプリ名-app, アプリ名-db
ports ローカル(ホスト)側とDockerコンテナ側のポート番号の関連付け
ローカルの80番ポートとNginxコンテナの80番ポートをマッピングしている。
environment 環境変数
volumes ローカルとDockerコンテナ間のディレクトリのリソースを関連付ける設定
tty コンテナを起動し続ける設定
depends_on コンテナの起動順。DBコンテナから起動するように設定

環境変数の設定

初めて構築する場合はスキップ

  • アプリのディレクトリへ移動
  • .envの作成、環境変数の設定
$ cd ~/git/github/アプリのディレクトリ名

$ cp .env.example .env
// 作成した.envの設定をする

docker run

  • docker/dev配下へ移動
  • コンテナの構築と起動
  • コンテナの起動を確認
$ cd docker/dev
$ docker-compose up -d
$ docker-compose ps

Laravel install

初めて構築する場合のみ実行

  • appコンテナに入る
  • Composerインストール
  • Composerバージョン確認
  • Laravelインストール
  • Laravelのディレクトリやファイルを確認
  • .env作成、環境変数の設定
  • APP_KEY生成
  • .envの更新反映
  • app再起動
$ docker exec -it appコンテナ名 bash
# composer install
# composer -V
# composer create-project --prefer-dist "laravel/laravel=6.*" .
# ls
# cp .env.example .env
// 作成した.envの設定をする
# php artisan key:generate
# php artisan config:cache
# /usr/bin/supervisorctl restart app

app deploy

初めて構築する場合はスキップ

  • appコンテナに入る
  • Composerインストール
  • Composerバージョン確認
  • APP_KEY生成
  • .envの更新反映
  • マイグレーション
  • app再起動
$ docker exec -it appコンテナ名 bash
# composer install
# composer -V
# php artisan key:generate
# php artisan config:cache
# php artisan migrate
# /usr/bin/supervisorctl restart app
  • gitignore修正
gitignore
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
docker-compose.override.yml
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
/docker/dev/mysql/db_data 

Access

  • /etc/hosts編集
$ sudo vim /etc/hosts
127.0.0.1 dev.ドメイン名 に変更
  • http://dev.ドメイン名/にアクセスしてアプリ(又はLaravelウェルカムページ)の表示確認できたら完成

再構築の場合

スクリーンショット 2022-04-01 17.27.24.png

初構築の場合
スクリーンショット 2022-03-18 4.10.07.png

DB login

-appコンテナに入る

  • 最後にMySQLログイン確認
$ docker exec -it appコンテナ名 bash
# mysql -u root -h db -p

Vue.js install

※Vue.jsを使用する場合に実行

  • appコンテナに入る
  • npmバージョン確認
  • npmがinstallされてない場合は以下手順
    • npm インストール
    • npmバージョン確認
  • Vue.sインストール
$ docker exec -it appコンテナ名 bash
# npm -v

// npmがinstallされてない場合は以下手順
   # npm install
   # npm -v

# npm install -D vue
# npm install -D vue-template-compiler

振り返り

Dockerひとつとっても様々な構築手順があるんだなぁと感じました。
まだまだnginx, php-fpmなどの設定に関する知識が乏しいので、これから深く学習していきます!!

やはりDockerを使用した環境構築は速くて便利!! 自由自在に構築できるようになりたいですね。

参考

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
What you can do with signing up
1