Lumen + Nginx + MySQLで簡単なAPIを作成してみた
PHP
Lumen
Backend
はじめに
最近、フロントエンドに React、サーバーサイドに Lumen を使って簡単な掲示板を開発しました。 ちなみに、Docker 上で実行しています。
万能で機能がたくさんある Laravel とは違い、軽量版である Lumen はハマりポイントがいくつもあって大変でした。 しかも、Laravel に比べると情報が非常に少ない。。。
中々大変だったので、この記事にまとめてみました!
Lumen, Nginx, MySQL 導入
Docker-compose が使える前提で書いているのでご注意ください
ディレクトリ構成
まず最初に、ディレクトリ構成を見ていきましょう!
├── Docker
│   ├── mysql
│   │   ├── Dockerfile
│   │   ├── conf.d
│   │   │   └── my.conf
│   │   ├── initdb.d
│   │   └── mysql_data
│   ├── nginx
│   │   ├── Dockerfile
│   │   └── conf
│   │       └── default.conf
│   └── php
│       ├── Dockerfile
│       └── php.ini
├── docker-compose.yml
└── var
    └── www
        └── backendこんな感じにしました。
Docker-compose.yml の編集
Docker-compose.yml は ↓↓↓
version: '3'
services:
  backend:
    container_name: php
    build: ./Docker/php
    volumes:
      - ./var/www/backend:/var/www/backend
    working_dir: /var/www/backend
    links:
      - mysql
    environment:
      DB_PORT: 3306
      DB_HOST: mysql
      DB_DATABASE: test
      DB_USERNAME: root
      DB_PASSWORD: root
  nginx:
    build: ./Docker/nginx
    container_name: web
    volumes:
      - ./Docker/nginx/conf/default.conf:/etc/nginx/conf.d/default.conf
      - ./var/www/backend/public:/var/www/backend/public
    ports:
      - 8080:80
    links:
      - backend
  mysql:
    build: ./Docker/mysql
    container_name: db
    environment:
      MYSQL_DATABASE: coco
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./Docker/mysql/initdb.d:/docker-entrypoint-initdb.d
      - ./Docker/mysql/conf.d:/etc/mysql/conf.d
      - ./Docker/mysql/mysql_data:/var/lib/mysql
    ports:
      - 13300:3306Dockerfile の設定
各 Dockerfile は以下のように書きました。
FROM  nginx:latestFROM mysql:8.0.16Lumen のインストールもあるため、PHP の Dockerfile は少々複雑です。 特に、ハッシュ値には注意が必要です。
FROM php:7.3-fpm
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
  && apt-get install -y zlib1g-dev libzip-dev mariadb-client \
  && docker-php-ext-install zip pdo_mysql
#Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
#ハッシュ値は更新されるのでhttps://getcomposer.org/download/で確認してください
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/binついでに、php.ini も。
[Date]date.timezone = "Asia/Tokyo"[mbstring]mbstring.internal_encoding = "UTF-8"mbstring.language = "Japanese"display_errors = OnNginx の設定
図のように、フロントエンドからリクエストがあった際に、Nginx から Lumen に流れていくように設定していきます。

server {
  listen       80;
  server_name  localhost;
  charset      utf-8;
  root /var/www/backend/public;
  index index.php;
  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }
  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass  backend:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include       fastcgi_params;
  }
}これで Nginx と Lumen を繋げることができました!
MySQL の設定
必ずコンテナを立ち上げる前にこの設定をしてください!
[mysqld]default_authentication_plugin= mysql_native_passwordexplicit-defaults-for-timestamp=1general-log-file=/var/log/mysql/mysqld.logLumen と MySQL の v8 は相性が悪いみたいで、この設定をしないと Lumen と MySQL を接続できません。 詳しくは、こちらの記事を参照。
ここで、コンテナを立ち上げます。
$ docker-compose up -dそして、MySQL のコンテナに入りましょう。
$ docker-compose exec mysqlMySQL 起動
$ mysql -u root -pdocker-compose.yml で設定したパスワードを入力して MySQL を触れるようになります。 続いて、DB の作成
mysql> CREATE DATABASE test;$ exit を 2 回打って MySQL とコンテナから出ましょう。
Lumen の設定
最初に
/backend/bootstrap/app.php の
// $app->withFacades();
// $app->withEloquent();のコメントアウトを外しておいてください。
Migration
まずは、以下のコマンドで Lumen のコンテナに入っていきます。
docker-compose exec backend bash続いて、
$ php artisan make:migration create_articles_table --create=articlesとすると、 /backend/database/migrations/タイムスタンプ_create_articles_table.php が生成されます。 この タイムスタンプ_create_articles_table.php を以下のように編集します。
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArticleTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tests', function (Blueprint $table) {
            $table->increments('id');
       ////////// ↓↓↓追加↓↓↓ ///////////
            $table->string('name');
            $table->text('comment');
       ////////////////////////////////
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tests');
    }
}編集後、以下のコマンドを実行。
$ php artisan migrateここで、 $ exit のコマンドで一回コンテナから出ます。 その後、MySQL のコンテナに入ってデータベースがあるか確認してみてください。 そして、適当にデータを INSERT しておきましょう。
mysql> INSERT INTO tests (name, comment, created_at, updated_at) VALUE
    ('testman1', 'HELLO!', NOW(), NOW()),('testman2', 'HELLO!', NOW(), NOW()),その後、ログアウトして、コンテナから出てください。
Model の作成
backend/app/ に新しく Tests.php を作成してください。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tests extends Model
{
  protected $table = 'tests';
  protected $fillable = ['name', 'comment'];
}Route の設定
backend/routes/web.php でルーティングを設定できます。 ここに以下のルートを追加してください。
$router->group(['prefix' => 'api/v1'], function() use ($router)
{
  $router->get('tests', 'TestsController@tests');
}Controller の作成
backend/app/Http/Controllers に新しく TestsController.php を作成して、以下のように編集してください。
<?php
namespace App\Http\Controllers;
use App\Tests;
class TestsController extends Controller
{
  public function tests() {
    return response()->json(Tests::all());
  }
}以上で API の基礎的な設定が終わりです!
API の確認
http://localhost:8080/api/v1/tests に行くと、DB の内容が表示されていると思います。
