DockerでLaravel6.2/Vue.js/Nginx/Mysql/RedisのSPAを構築する

## Dockerとは
Dockerの有用性もSPA(Single Page Application)の有用性も強調されるようになって久しく昨今はDocker/SPAもかなり浸透してきたと思います。DockerはLaravelなどのウェブアプリを動かすための仮想環境を作るもので、このDocker環境は本番にもデプロイできちゃいます。今回はDocker上にLaravelでPHP+Vue.jsのSPAを作ってみましょう。

なおDocker-comppseは複数のDockerイメージの作成と管理をするいわゆるオーケストレーションのためのツールです。

## Dockerのインストール
まずDockerのインストールをします。
1. Windowsユーザーは[Docker for Windows](https://docs.docker.com/docker-for-windows/)を使用してください。Windows7とか使っている人がいれば[Docker toolbox](https://docs.docker.com/toolbox/toolbox_install_windows/)を使えるかも（toolboxはDeprecatedなので注意）
2. Macユーザーは[Docker for Mac](https://docs.docker.com/docker-for-mac/)を使いましょう。
3. 私のようなUbuntu 18ユーザーは以下のようにインストールします。
まず古いDockerを消します。

```
$ sudo apt-get remove docker docker-engine docker.io
```

それから公式レポジトリからインストールします。

```
$ sudo apt-get update
# To enable https connection.
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# To download GPG key.
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Install the docker repository.
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable" 
$ sudo apt-get update
# Install Docker.
$ sudo apt-get install docker-ce
```

## Dockerが正常にインストールされたか確認
Dockerが正常にインストールされたか確認しましょう。ターミナル上で以下のコマンドを打ってバージョンが表示されれば成功です。 

```
docker --version
#Docker version 19.03.5, build 633a0ea838
```

こんな感じでバージョンが表示できたらOKです。

## Docker-composeも確認する
Dockerのインストールと併せてDocker-composeもインストールされたはずです。以下のコマンドで確認してください。バージョンが表示されれば成功です。

```
docker-compose -v
#docker-compose version 1.24.1, build 4667896b
```


## DockerとDocker-composeを使ってみる
以下のコマンドで私のgitレポジトリからdocker-composeファイルを落として実行します。

```
$ git clone https://github.com/lechatthecat/laravel-coreuivue-integration-by-docker-compose
$ cd laravel-coreuivue-integration-by-docker-compose
$ docker-compose up -d --build
$ docker-compose exec laravel ash
$ ash ./laravel_build.sh
```

すると[CoreUI vue](https://github.com/coreui/coreui-free-vue-admin-template)がローカルで動いているのがわかると思います。
http://localhost:10080/

ただし、面倒だったのでdashboardとloginページしかちゃんとつくっていません。ちゃんとしたデモページはこちら。
https://coreui.io/vue/demo/3.1.0/#/dashboard

MITライセンスなので権利表示をちゃんとすれば商用利用もできます。
![Screenshot from 2020-11-11 23-27-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260163/443eca06-b00d-dfb8-674c-f979f38f78fa.png)



## docker composeの設定ファイル

Gitから落とした[docker-composeファイル](https://github.com/lechatthecat/laravel-nginx-mysql-example-en/blob/master/docker-compose.yml)はこういう設定が書いてあります。ちゃんとNginx/Mysql/Redisを使っていることがわかります。

```docker-compose
version: "3.5"
# コンテナ間でvolumeのシェアするときに使う
x-services-volume:
  &laravel-volume
  type: bind
  source: ./laravel-coreui
  target: /laravel-coreui

services:
  laravel:
    container_name: laravel
    depends_on:
      - mydb
      - myredis
    build:
      context: .
      dockerfile: docker/laravel/Dockerfile
      args:
        - TZ=${TZ}
    # bind mount
    volumes:
      - <<: *laravel-volume
      - ./docker/laravel/laravel_build.sh:/laravel-coreui/laravel_build.sh
      - ./logs:/var/log/php
      - ./docker/laravel/php.ini:/usr/local/etc/php/php.ini
    working_dir: /laravel-coreui
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - TZ=${TZ}
    networks:
      - app_net
  # nginx 1.17
  web:
    container_name: my_nginx
    image: nginx:1.17-alpine
    depends_on:
      - laravel
    ports:
      - 10080:80
    volumes:
      - *laravel-volume
      - ./logs:/var/log/nginx
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:z
    environment:
      - TZ=${TZ}
    networks:
      - app_net
  # MySQL 8.0
  mydb:
    container_name: mydb
    image: mysql:8.0
    volumes:
      - db-store:/var/lib/mysql
      - ./logs:/var/log/mysql:z
      - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:z
    ports:
      - 13306:3306
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - TZ=${TZ}
    networks:
      - app_net
  # redis 5.0.5 
  myredis:
    container_name: myredis
    image: redis:5.0.5-alpine
    # bind mount
    volumes:
      - redis-store:/data
      - ./logs:/var/log/redis.log:z
      - ./docker/redis/my.conf:/etc/redis/my.conf:z
    ports:
      - 16379:6379
    command: redis-server /etc/redis/my.conf
    networks:
      - app_net
networks:
    # Containers in same network can access each other by using its container name as host name
    app_net:
        driver: "bridge"
volumes:
  db-store:
  redis-store:
```