けけずんセルフハッキング

エンジニアっぽい雰囲気を醸しだしているかのようなブログです!

SPA な Web アプリを継続的デリバリーする環境を作る (1) 〜 バックエンド( Laravel )編

概要

SPA な Web アプリを継続的デリバリーする環境を作るシリーズ第一回、バックエンド編。 ちなみに序章はこちら。

kkznch.hatenablog.com

全4部構成でお届けする。

ハンズオンするぞ

ひたすら手を動かそう。

Laravel プロジェクトの作成と git の初期設定

バックエンドで動作する Laravel プロジェクトを作成する。

$ composer create-project --prefer-dist laravel/laravel app-backend

ついでに git でリポジトリの設定もする。 ハンズオンの前に自分で作成したリポジトリを git のリモートとして設定してあげよう。

$ cd app-backend
$ git init
$ git remote add origin git@gitlab.com:自分のユーザ名/app-backend.git

なんとなくコミットしてプッシュまでしとく。

$ git add .
$ git commit -m "first commit"
$ git push origin master

開発環境で使用する Docker な環境の構築

ローカル環境で動作を確認しながら開発をしたいと思うことがしばしばあるだろう。 雰囲気こんな感じでやる。

f:id:kkznch:20200222134439p:plain
ローカルでの実行環境

本記事では図中の右側にある Docekr Engine の枠と、Laravel の部分を実装していく。 Docker 環境は一度作っておくと使いまわしが効くので便利、頑張って理解しよう。

docker-compose.yml の作成

ローカル環境で開発をする際に使用する Docker Compose の設定ファイル docker-compose.yml を作成する。 Dockerfile などはこの後で用意するから心配無用。

docker-compose.yml

version: '3.7'
services:
  php-fpm:
    build:
      context: .
      dockerfile: ./Dockerfile
    depends_on:
      - mysql
    volumes:
      - .:/app:cached
    working_dir: /app
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    depends_on:
      - php-fpm
    volumes:
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
  mysql:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=laravel
      - MYSQL_USER=root
      - MYSQL_PASSWORD=
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - 3306:3306
    volumes:
      - db-volume:/var/lib/mysql
volumes:
  db-volume:

php-fpm 用の Dockerfile の作成

Laravel が動作する php-fpm な Dockerfile を作成する。

Dockerfile

FROM php:7.3-fpm-alpine

RUN apk --no-cache update && apk --no-cache upgrade
RUN docker-php-ext-install \
    bcmath \
    pdo_mysql

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN composer global require hirak/prestissimo

nginx の設定ファイルの作成

リクエストを nginx コンテナから php-fpm コンテナに流すよう設定ファイルを作成する。 こいつは nginx コンテナを起動する際にファイルがコンテナ内にマウントされるよう ./docker-compose.yml に記述されてる。

docker/nginx/default.conf

server {
    server_name localhost;
    listen 80;
    root /app/public;
    index index.php index.html;

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

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

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

docker-compose でビルドとコンテナの起動

docker-compose コマンドを実行して Docker イメージのビルドをする。

$ docker-compose build

ついでにイメージからコンテナを作成して起動する。

$ docker-compose up -d

これでアプリケーションが動作する環境が動いている状態になる。 このあとで Laravel プロジェクトを作成するので、その後にアクセスすると動作が確認できるはず。

ちなみにコンテナを停止して削除したい場合は以下のコマンドを実行するとよい。 今は実行しなくてもいいよ。

$ docker-compose down

バックエンドアプリの実装

Laravel で API コントローラの作成

フロントからリクエストがあった際にシンプルな文字列を返すためのコントローラを作成する。 以下のコマンドを実行するのだ。

$ docker-compose exec php-fpm php artisan make:controller Api/HelloController

app/Http/Controllers/Api/HelloController.php というファイルが作成されるので、その内容を以下のようにする。

app/Http/Controllers/Api/HelloController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Carbon\Carbon;

class HelloController extends Controller
{
    public function index()
    {
        return response()->json([
            'body' => 'Hello, World!',
            'datetime' => Carbon::now(),
        ]);
    }
}

コントローラの index にアクセスがあると "Hello, World!" と一緒に日時を返すだけのアクションになっている。

API コントローラ用のルーティングを設定する

ルーティングの設定を以下のように行う。 今回は / にアクセスされると HelloController の index メソッドに記述された処理が実行される。

routes/api.php

<?php

Route::get('/', 'Api\HelloController@index');

CORS 対策用パッケージのインストールと設定ファイルの編集

今回想定している構成だと別のドメインにある API を実行するため、 CORS エラーが起きてアクセスが遮断される。 それを回避するために、バックエンド側で CORS の対策を行う。

CORS 知らん人はここを見てね。

developer.mozilla.org

というわけで、まずは Laravel で CORS 対策用のパッケージをインストールする。

$ docker-compose exec php-fpm composer require fruitcake/laravel-cors

CORS 対策パッケージを有効化するために Kernel.php の middleware に以下のように記述する。

app/Http/Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    protected $middleware = [
        ...略
+        \Fruitcake\Cors\HandleCors::class, 
    ];
    
    ...略

以下のようにCORS 対策パッケージの設定ファイルを書く。

config/cors.php

<?php

return [
    'paths' => ['*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => false,
    'max_age' => false,
    'supports_credentials' => false,
];

動作の確認

以下のコマンドを実行してレスポンスが返ることを確認する。 レスポンスが返ってこない人はドンマイ。

$ curl http://localhost/api

{"body":"Hello, World!","datetime":"2020-02-20T09:00:00.000000Z"}

curl コマンドを実行することで、Vue.js からではなく直接ローカルホストを経由して nginx 、 php-fpm にアクセスしたことになる。

f:id:kkznch:20200222135135p:plain
ローカルでの実行環境_curlでアクセスしたよ

確認できたらコミットしてプッシュまでしておく。 この後の工程で必要になるので、忘れずに。

$ git add .
$ git commit -m "second commit"
$ git push origin master