99_27_hyn multi tenantによるマルチテナントアーキテクチャ - hpscript/laravel GitHub Wiki

プロジェクト作成

$ composer create-project --prefer-dist laravel/laravel tenancy-demo
$ cd tenancy-demo
$ composer require hyn/multi-tenant

mysql driverインストール

$ composer require "doctrine/dbal:2.*"
$ composer require tenancy/db-driver-mysql

config/app.php

    'providers' => [
        // 省略
        Hyn\Tenancy\Providers\TenancyProvider::class,
        Hyn\Tenancy\Providers\WebserverProvider::class,

    ],

file update
$ php artisan vendor:publish --tag tenancy

config/database.php
L connectionでmysqlをコピペしてsystemを追加します。

    'connections' => [

        'system' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'tenancy'),
            'username' => env('DB_USERNAME', 'hoge'),
            'password' => env('DB_PASSWORD', 'fuga'),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
    ],

.env

TENANCY_HOST=127.0.0.1
TENANCY_PORT=3306
TENANCY_DATABASE=tenancy_demo
TENANCY_USERNAME=hoge
TENANCY_PASSWORD=fuga

mysql> create database tenancy_demo;
Query OK, 1 row affected (0.01 sec)

$ php artisan migrate --database=system
Migrating: 2017_01_01_000003_tenancy_websites
Migrated: 2017_01_01_000003_tenancy_websites (16.88ms)
Migrating: 2017_01_01_000005_tenancy_hostnames
Migrated: 2017_01_01_000005_tenancy_hostnames (44.02ms)
Migrating: 2018_04_06_000001_tenancy_websites_needs_db_host
Migrated: 2018_04_06_000001_tenancy_websites_needs_db_host (12.21ms)

Trying your installation

multi tenantのテストを行うには、apacheかlaravel Valetでテストする必要がある
$ sudo vi /etc/httpd/conf.d/custom.conf

DocumentRoot "/var/www/html/tenancy-demo/public"
# .htaccess 有効化
<Directory /var/www/html/tenancy-demo/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>

$ service httpd restart

routes/tenants.php

use Illuminate\Support\Facades\Route;

Route::get('/', function(){
	return view('tenants.home');
});

resources/views/tenants/home.php

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<h1>Welcom!</h1>
	<p>This will be your <b>dashboard</b> for every tenant in your system.</p>
</body>
</html>

config/tenancy.php
L make sure that path would be right.

    'routes' => [
        'path' => base_path('routes/tenants.php'),
        'replace-global' => false,
    ],

creating first tenant

$ php artisan make:command tenant/create
app/Console/Commands/tenant/create.php

namespace App\Console\Commands\tenant;

use Illuminate\Console\Command;

use Illuminate\Support\Str;

use Hyn\Tenancy\Models\Hostname;
use Hyn\Tenancy\Models\Website;
use Hyn\Tenancy\Repositories\HostnameRepository;
use Hyn\Tenancy\Repositories\WebsiteRepository;

class create extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    // protected $signature = 'command:name';
    protected $signature = 'tenant:create {fqdn}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Given a unique tenant name, creates a new tenant in the sytem';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {

        $fqdn = sprintf('$s.$s', $this->argument('fqdn'), env('APP_DOMAIN'));

        $website = new Website;
        $website->uuid = env('TENANT_WEBSITE_PREFIX') . Str::random(6);
        app(WebsiteRepository::class)->create($website);

        $hostname = new Hostname;
        $hostname->fqdn = $fqdn;
        $hostname = app(HostnameRepository::class)->create($hostname);
        app(HostnameRepository::class)->attach($hostname, $website);
        // return 0;
    }
}

.env

TENANT_WEBSITE_PREFIX=tenancy_demo_

php artisan tenant:create demo

mysql> show tables;
+------------------------+
| Tables_in_tenancy_demo |
+------------------------+
| failed_jobs |
| hostnames |
| migrations |
| password_resets |
| users |
| websites |
+------------------------+
6 rows in set (0.31 sec)

mysql> select * from websites;

⚠️ **GitHub.com Fallback** ⚠️