DockerでLaravel 7+ Nuxt.jsの動作環境をMacから構築する(Nginx+php7.3+MySQL5.7)

2020年8月10日

やりたい事

・Laravel(API) + Nuxt.js(SSR・フロント)でのWEBアプリ開発の勉強の作業環境をすぐに欲しい
・Dockerを使う理由としては次のステップとしてAWSにデプロイしたい為

各バージョンなど

CentOS 7
Laravel 7
Nodejs
Nuxt.js 
MySQL 5.7
Apache
PHP 7.3
※適切なバージョンを選定しないとLaravel7が動作しない場合があるので注意

MacにDockerをインストール

#MacにDocker Desktopをインストール
Mac版をGetDockerボタンを押下してインストール
インストールできればアプリを開きデスクトップ画面上部のくじらアイコンをクリックして、
起動状態になっていることを確認する。(Desktop running)

DockerComposeのインストール

#DockerComposeの説明
docker-compose.yml がある階層まで移動してコマンドを実行する

起動・停止・再起動のコマンド

起動中のコンテナに入りたい時

Laravel 7+ Nuxtjs環境を構築(ここから本題)

#前提
管理画面のフロント側としてNuxt.jsを利用する
バックエンドをAPIとしてLaravelで作成する

#参考記事
https://qiita.com/A-Kira/items/be0602fe28b445e865db
基本的には上記サイトの通り進めていく

#やりたい事
Mac内に共有フォルダ(作業フォルダ)
laravel-sanctumで『SPAの認証機能』を実装
Nuxtのログイン画面からaxiosでログイン

#フォルダ構成

#ディレクトリの作成

#docker-compose.yml の作成

[説明]
version: ’3’   //  Dockerのバージョンの事
services :  //コンテナを登録 (今回の場合:   php  /  nginx  /  db  )
php :   //imageを指定していない
 └  build:   ./laranuxtproj/docker/php 配下の Dockerfile を参照して構築
 └  volumes:  ローカルの  ./src  と /var/www をマウント
nginx
 └  image: nginxの公式イメージを使用
 └  ports:   host  80番:guest 80番  ポートで接続     // laravel 用 (http)
 └  ports:  host  443番:guest 443番 ポートで接続     // laravel 用 (https) SSL化
 └  ports:  host  3000番:guest 3000番 ポートで接続     // Nuxt.js 用
 └ volumes:  ローカルの ./laranuxtproj/docker/nginx/default.conf  と
                             /etc/nginx/conf.d/default.conf をマウント
db
 └  imageにmysql:5.7を指定
 └ restart: コンテナ再起動
 └ environment: DBの設定
 └ ports: host  3306番:guest 3306番  ポートで接続

#Dockerfile作成
./laranuxtproj/docker/php に  Dockerfile を作成する

#php.iniの作成
./laranuxtproj/docker/php にphp.ini を作成する

#nginx設定ファイル作成
./laranuxtproj/docker/nginx直下に作成する

#MySQLの設定

Laravelプロジェクト作成

#起動したコンテナに入りLaravelプロジェクトを作成

#ブラウザで動作確認
ブラウザからlocalhostにアクセスするとLaravelの画面が表示されていれば完了

#MySQLコンテナ確認

Laravel の初期設定

#.envファイルを修正
DB接続情報を書き換える
docker-compose.ymlに記載の情報を.envファイルに追記する

上記完了すれば再起動する

※これでもできない場合以下で権限を変更する

#LaravelのテーブルやAppKeyを作成 ,キャッシュもクリアする場合

#ライブラリのインストール
composer.json にあるライブラリをインストールする必要がある場合

#node.jsをコマンドでインストールする場合

NodejsをインストールするコマンドをDockerfileに追加

#Dockerfileに追記する
プロジェクトの開発途中に必要なライブラリなど増えた場合Dockerfileを作り直す。
node.jsインストールコマンドを追記する

Dockerfileを変更したら一度コンテナを停止させ以下コマンドでビルドする

package.json にあるライブラリをインストールする必要がある場合
※インストールがうまく行かない場合、いったんpackage.jsonを別名で保存しておき
npm init で作成したものに上書きすれば良い

Laravel に認証機能を導入する

#ログイン認証機能の作成
artisan コマンドでログイン機能と新規ユーザー登録機能が一発で作成できる
以下コマンドで /resources/views/auth を作成

#テストデータを自動で挿入する
artisan コマンドで以下の通り実行すると、
database/seeds に作成される

artisan コマンドで以下の通り実行すると、
/database/seeds にUserSeeder.phpに作成される

/database/seeds/UserSeeder.php

/database/seeds/DatabaseSeeder.php

上記完了すれば以下コマンド実行する

Laravel sanctum  インストール編

Laravel sanctum では以下のことができる
・トークンを使った API認証
・SPAからLaravelの組み込みCookieベースのセッション認証サービスを使用して認証することができる

#インストール

インストールが完了後以下のコマンドで必要なファイルをコピー

ファイルが作成されたのでマイグレーションを実行

Laravel sanctum  トークンを使ったAPI認証編

#参考サイト
https://blog.capilano-fw.com/?p=6121

#アクセストークンの作成
UserモデルにHasApiTokensをセットしてトークンを使えるようにする

santumでアクセストークンを作成する
/routes/web.php

上記の修正完了後に以下URLをブラウザで実行すると
http://localhost/create_token
2|0W8S8wN9K5powOArBrLYRxWkL1aarnkVGRM6qUtUB3lKjRSpwVnhwhnxdvq2Met2hRhcUCuMHQIyhslb
ブラウザにアクセストークンが表示されれば成功(冒頭の『2|』は除く)

データベースを確認して、データも正しく挿入されていることを確認する

#ユーザー情報を取得する使い方
/routes/api.php

・トークンが正しければユーザー情報を返す
・それ以外は拒否(もしくはリダイレクト)する
上記の実装が可能となる

#POSTMANでテスト

https://www.postman.com/downloads/
アプリをダウンロードしてアカウントを新規に作成する(Googleアカで作成できる)
 作成完了後管理画面の上部にある+タブで送信画面を表示
URLに入力してSENDボタンで送信テストができる

#TOKENを指定しない場合
GET :  http://localhost/api/user
ページがリダイレクトしてアクセス拒否されれば想定通り

#TOKENを指定した場合
Authorization > Bearer Token に先ほどブラウザに表示されたトークンを入力してアクセス
GET :  http://localhost/api/user
TOKEN : 0W8S8wN9K5powOArBrLYRxWkL1aarnkVGRM6qUtUB3lKjRSpwVnhwhnxdvq2Met2hRhcUCuMHQIyhslb
成功すればuser情報が表示される

Laravel sanctum  CookieベースのAPI認証編(Nuxt.js)

#説明
同一オリジン内でのAPIアクセスを想定している
Nuxt.jsはport 3000で動作させてAPIにアクセスする際は、
はじめにセッションを取得して

#起動したコンテナに入りNuxt.jsプロジェクトを作成

※npx での作成がうまく行かなかった場合以下を実行する

以下のように選択
Generating Nuxt.js project in nuxt
Project name: nuxt
Programming language: JavaScript
Package manager: Npm
UI framework: Vuetify.js
Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
Testing framework: None
Rendering mode: Universal (SSR / SSG)
Deployment target: Server (Node.js hosting)
Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)

#package.jsonにポート3000でアクセスできるように設定
末尾に以下を追記する

#Laravel側にNuxt.jsからのアクセスを許可する設定を行う
Nuxt.jsが起動するドメインを追記する
./config/sanctum.php

Sanctumを使用してSPAを認証する場合ファイル内のミドルウェアグループにSanctumのミドルウェアを追加する
./app/Http/Kernel.php

#Laravel sanctum で認証できるログイン画面を作成
./nuxt/pages/login.vue を作成する

axiosモジュールを使い /sanctum/csrf-cookieルートを呼び出し認証に使用されるXSRF-COOKIEが設定される
withCredentials: true、リクエストにCookieが確実に渡されるように設定

#authモジュールをインストール
Laravel sanctumを使うためにはAxiosとauthモジュールをインストールする必要がある

AxiosはNuxtをインストールする際の選択で選んでいるものとして以下authをインストール

nuxtjs/authの型ファイルもインストール

./nuxt.config.jsに追加したモジュールを追記する

#authモジュールの構成
./nuxt.config.jsを以下のように追記する
【auth:】auth認証モジュールがAPIを操作するために使用するキーを構成に作成する
 【login:】 ログイン資格情報を送信するエンドポイント  /loginURLへのPOSTリクエスト
      withCredentials: true で、cookie(クレデンシャル)を渡す許可
              HTTPリクエストを作成して、jsonデータを送信する
 【user:】 ログインしたユーザーを取得するルートを設定 GETリクエスト
tokenRequired: false,  // Tokenを使用しない為、falseとする
 tokenType: false // Tokenを使用しない為、falseとする

#AxiosリクエストのベースURLを設定
./nuxt.config.js
を以下のように追記する

#CORSライブラリをインストール
SPAやモバイルアプリなど他のオリジンからAPIにアクセスするにはCORSライブラリをインストールする必要がある
※CORS (オリジン間リソース共有、 Cross-Origin Resource Sharing) は、 HTTP ヘッダーの転送で構成されるシステムであり、ブラウザーがオリジンをまたいだリクエストのレスポンスに、フロントエンドの JavaScript コードがアクセスすることをブロックするかどうかを決めるもの

グローバルHTTPミドルウェアの最後にミドルウェアを追加する
./app/Http/Kernel.php

以下コマンドを実行することにより、SanctumがNuxtで動作するようにカスタマイズできる

./config/cors.php  のpath キーに追記
‘sanctum/csrf-cookie’, ・・・ Laravel SanctumでCSRF Coo​​kieを受け取るために使用するルート
‘login’,      ・・・  /loginルートへのPOSTリクエスト
        デフォルトのLaravel Auth(1分でセットアップされます)によって処理される
‘api/*’ ・・・ SPA、モバイル、またはデスクトップアプリからCORSを介してすべてのAPIルートにアクセスできる

CORSが有効なルートに認証リクエストを送信するため、
Access-Control-Allow-Credentialsヘッダーを追加するための設定を有効にする必要があります
Axiosではこのヘッダーが有効でアクセス可能である必要があり、
このヘッダーを有効にするには、supports_credentialsキーfalseを次のtrueように
変更します

最後に

Dockerを使うと簡単に環境を作れるのでかなり便利
実際に今の現場や求人など見てもDockerを使うのは必須になっているようなので覚えるべき
ただ案外簡単にできるのですぐにでもやるべき