【Docker】Laravel 6+Vue.js+PostgreSQLで環境構築

上記記事ではRails v6を使用してSPA Webサーバを構築しました。まだご覧になっていない方はご確認頂けるとスムーズです。今回はちょっととある事情があり、Laravelでも環境構築してみたいと思って作ってみました。

Laravelって何?

モダンな技術に縁のある方はもうわかっているとは思いますが、どちらかと初心者向けサイトのため、解説しておきます。

LaravelはPHPのフレームワークです。ですのでメインの言語はPHPです。

2020/11現在の主要Webアプリのフレームワーク

  • PHPフレームワークのLaravel
  • RubyフレームワークのRails
  • Python フレームワークの Django

現在はこの3つが主流ですが、Pythonはどちらかといえば機械学習向け言語ですね。なので主流はLaravelかRailsですが、海外の方は既にLaravelの方が人気だそうです。

どれ使うべき?3大WebフレームワークRails・Django・Laravelを徹底比較してみた

この記事を見るとRailsは既に全体のピークが過ぎているのか落ちてきて、LaravelがDjangoより伸びてきているのがわかります。

何故いきなりRailsではなくLaravelを?

  1. Railsに憧れたのは3年くらい前だが最近になって見るとこの3年でRailsは落ちているので今から学ぶにはちょっとリターンが弱い。
  2. 転職ドラフトで見ても企業だけでなく、他ユーザにRails経験者が多いため、今から始めました!レベルの人を採用すると思えない。
  3. 個人アプリ作る前に技術選定をしたい。
  4. フリーランスで商談が来そうなのだが実務でPHPを使うため、参画が決まった時のためにLaravelでPHPを先回り学習しておきたい。
  5. Qiitaで見てもあまりLaravelとRailsの比較記事みたいなのを見かけないので率先して操作性や仕様の比較記事を作りたかった。
  6. RubyよりもPHPの方がWordPressの業務で実績があり、馴染みがある

と、これだけ理由があったので学ばない理由がないと思い、決定しました。

構築する環境とRailsとの違い

タイトルにもあったようにDockerは使いますが今回はRailsではなくLaravelで構築します。それ以外は同じです。しかしWordPressがそうなようにPHPMySQLを採用する方が多いのかな?あまりPostgreSQLを使って構築したという記事がなかったです。用意するdocker-compose.ymlDockerfileですが、前回の記事で参考にした構成が最低限で好印象だったので今回も最小限をコンセプトに参考にできるサイト様を探しました。以下がオススメです。

絶対に失敗しないDockerでLaravel+Vueの実行環境(LEMP環境)を構築する方法〜前編〜

絶対に失敗しないDockerでLaravel6.8+Vueの実行環境(LEMP環境)を構築する方法〜後編〜

こちらの記事はMacのPCで構築したそうですが、Windows Homeでも行けました。あと、この記事はDBがMySQLになっていますが、これはPostgreSQLに置き換えて作る事が必要でした。ちなみにこの時点でもうRailsと違う所が出てきます。

Nginx?(エンジンエックス)

NginxはApacheと同じWebサーバの種類です。でも前回(セクション4)の記事はNginxもApacheも入れてないよね?何で動いているの?といった疑問が沸くと思います。それについては以下のサイトの説明がわかりやすかったです。

アプリケーションサーバーはあなたのRailsアプリケーションを動かしているものです。 アプリケーションサーバーはあなたのコードを読み込み、アプリケーションをメモリに保持します。アプリケーションサーバーはwebサーバーからリクエストを受け取ると、Railsアプリケーションにそのことを知らせます。アプリケーションがリクエストを処理すると、アプリケーションサーバーはそのレスポンスをwebサーバーに返します。(そのレスポンスは最終的にユーザーへ届きます。)大半のアプリケーションサーバーはwebサーバーを使わずに単体で実行できます。

Rails用のアプリケーションサーバーは山ほどあります。たとえば、Mongrel(ただし最近はほとんど使われていない)、Unicorn、Thin、Rainbows、Pumaなどです。それぞれに異なる長所があり、異なる設計思想を持っています。とはいえ、みんなやっていることは一緒です。つまり、どのアプリケーションサーバーもあなたのRailsアプリケーションを動かし、リクエストを処理し続けています。

Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳)

つまりRailsにはセットでアプリケーションサーバが用意されていて開発環境であればそれがWebサーバの代わりをしてくれている。と理解しておけばいいと思います。確かにRailsを動かしていた時のDockerログを見るとPumaというアプリケーションサーバが動いていた事がわかります。

web_1  | => Booting Puma
web_1  | => Rails 6.0.3.4 application starting in development
web_1  | => Run `rails server --help` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 4.3.6 (ruby 2.7.2-p137), codename: Mysterious Traveller
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

RailsにはアプリケーションサーバがついてくるからWebサーバはいらないけど、PHPにはつかないのでNginx(またはApache)を入れましょうということです。

MySQLをPostgreSQLに変更したい!

おそらくMySQLを使いたい時は特に変更する必要はないと思いますが、PostgreSQLを使いたい場合は以下のエラーが出てしまいます。

configure: error: Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path

これは以下のサイトを見てみた所、3.の※に記載があってlibpq-devがないと、ヘッダが無いと言われてエラーとなるらしいです。

[備忘録]Dockerでapache+php+postgresql環境

後は、Rails6 以降の場合はWebpackerが自動で入る関係でyarnのインストールが必須でしたが、PHP環境はそんな事ないため、npmの方をインストールしています。

その代わり、PHP開発時はcomposerが必要不可欠みたいなのでインストールに入っています。

PHP開発でComposerを使わないなんてありえない!基礎編

おそらく最低限の環境

という訳でおそらくこれが最低限であろう、Laravel + PostgreSQL + Vue.js環境の基礎ができあがりました。わずか3ファイル!

※nginx/default.confは参考記事の内容のまま変更していないため、載せていません。

docker-compose.yml

version: "3.8"
services:
  web:
    image: nginx:1.18
    ports:
      - '8000:80'
    depends_on:
      - app
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/var/www/html
  db:
    image: postgres
    volumes:
      - psgl_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: password
      TZ: 'Asia/Tokyo'
    ports:
      - 5432:5432
volumes:
  psgl_data:
FROM php:7.4-fpm

RUN apt-get update && apt-get install -y zip unzip

#composerをインストール
COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer

#npmインストール
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 install -y libpq-dev

#失敗したらコメント外して実行
#RUN docker-php-ext-configure pgsql -with-pgsql=/var/lib/postgresql/data

RUN docker-php-ext-install pdo pdo_pgsql

WORKDIR /var/www/html

立ち上がったら解説サイトの通りにセットアップできます。

DBのマイグレーションでエラー

SQLSTATE[08006] [7] could not connect to server: Connection refused

サーバが見つからないよ!というエラーかな?これも解説サイトを探したら以下のようにしたら解決しました。

root@9e41b949c831:/var/www/html/laravel-vue-app# cat .env

DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=postgres
DB_USERNAME=root
DB_PASSWORD=password

docker-compose.yml で登録したコンテナ名(db)をDB_HOSTに入れるちなみにDB_DATABASEはpostgresが標準です。

Dockerの環境構築で`could not connect to server: Connection refused`のエラーが出た時の対処法

ここまで終わったら8000をアクセスしたらLaravelの初期画面が出てきます。

DBがつながったら簡単なSPAを作ってみる

Laravelの場合RailsWebpackerと違い、Hello Vue!を生成してくれるチュートリアルがなかったのでHello Vue!相当のチュートリアルサイトを探したら以下の記事がありました。

[Laravel]Laravel6.8 × Vue.jsでSPAを構築する流れ

ただ、この記事の通りだと足りませんでした。その時のエラーをお見せします。

Running: npm install sass-loader@7.* sass resolve-url-loader@3.1.0 –save-dev –production=false

sass関連のエラー。特に指定していないのだけどなんか出てしまう。

 webpack.mix.js

let mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for your application, as well as bundling up your JS files.
 |
 */

mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/');

最後のsass(‘src/app.scss’, ‘dist/’);が最初から入っていたから消した。

あと記事にはvue-template-compilerが書いていないがこれも入れた方がいい。

Module not found: Error: Can’t resolve ‘axios’ in ‘/var/www/html/laravel-vue-app/resources/js’

Laravelのapp.jsではデフォルトでbootstrapを参照しているようで、その先でaxiosがなく怒られてしまっています。今は疎通確認なのでここも消す。

import './bootstrap'

アクセスしたけどLaravelの初期ページが出る

viewでindex.blade.phpを作っている割にはルートファイルで参照先を変える記載が漏れている。。。

root@9e41b949c831:/var/www/html/laravel-vue-app/routes# cat web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

初期状態ではwelcomeになっています。(welcomeがLaravelの初期ページ) ですのでこれをreturn view(‘index’);に変えてあげればOKです。さすがにこの部分はRailsで構築した時の経験を生かせました。

完成

今回はこのSPAをHello Vue!表示の代わりにしました。

まとめ

Laravelを使ってみて確かにRailsと似通ってるなぁーと思いつつも、全体的に直感的でわかりやすい感じしました。PHPの構成自体はWordPressで環境構築した時とそんなに変わらないので馴染みもあったかもしれません。とはいえ、時期的にもLaravelの方がRailsより後に出てるんだから使いやすくないとおかしい。。意外と気に入ったので個人アプリもRailsじゃなくてLaravelで作るかもしれません。

それにRoutesの所が最初から記載があったので特にわかりやすかったRailsのは最初何もないから初心者が見ても、何を入れていいかわからない…(rootだったり、Toだったりgetだったり参考にするサイトによって記述がバラバラだったりする)。あとは最終的にHerokuサーバにデプロイする時は最初からWebサーバのNginxを使っているのでデプロイ時はLaravelの方がやりやすいかも。

Railsだとアプリケーションサーバというものが間に挟んでるのでデプロイ時の習得コストがかかりそう。

Laravelの疑問

  • なぜバージョン新しい方がバグ修正・セキュリティサポート短いんだろう・・(最新は8だが安定はバージョン6です(LTSと呼ばれている))Laravel リリース・サポート期限