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:3306
Dockerfile の設定
各 Dockerfile は以下のように書きました。
FROM nginx:latest
FROM mysql:8.0.16
Lumen のインストールもあるため、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 = On
Nginx の設定
図のように、フロントエンドからリクエストがあった際に、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.log
Lumen と MySQL の v8 は相性が悪いみたいで、この設定をしないと Lumen と MySQL を接続できません。 詳しくは、こちらの記事を参照。
ここで、コンテナを立ち上げます。
$ docker-compose up -d
そして、MySQL のコンテナに入りましょう。
$ docker-compose exec mysql
MySQL 起動
$ mysql -u root -p
docker-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 の内容が表示されていると思います。
