Как создать субдомен и отдельную базу данных для каждого пользователя, используя миграции в Laravel и Docker?

Как настроить субдомен и отдельную базу данных для каждого пользователя в Laravel с использованием Docker и миграций? В проекте должна быть основная база данных (например, mainDB), а для каждого пользователя с его субдоменом необходимо создавать отдельную базу данных.
  • 30 марта 2025 г. 14:45
Ответы на вопрос 2
Чтобы создать субдомены и отдельные базы данных для каждого пользователя в Laravel с использованием Docker и миграций, вам нужно выполнить несколько шагов. Ниже приведена пошаговая инструкция для реализации этого подхода.

### 1. Подготовка окружения Docker

Сначала установите Docker и создайте файл `docker-compose.yml` для вашего проекта Laravel. Примерный файл может выглядеть следующим образом:

```yaml
version: '3.8'

services:
  app:
    image: laravelphp/php-fpm
    volumes:
      - .:/var/www
    networks:
      - laravel

  webserver:
    image: nginx:alpine
    volumes:
      - .:/var/www
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "80:80"
    networks:
      - laravel

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

volumes:
  db_data:
  
networks:
  laravel:
```

### 2. Настройка конфигурации Nginx

Создайте файл `nginx.conf` в корне проекта для настройки Nginx:

```nginx
server {
    listen 80;

    server_name ~^(?<subdomain>.+)\.yourdomain\.com$;

    root /var/www/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass app:9000;  # Убедитесь, что этот порт соответствует вашему приложению
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
```

### 3. Создание модели пользователя и миграция

Создайте модель пользователя с помощью команды:

```bash
php artisan make:model User -m
```

В миграции (`database/migrations/create_users_table.php`) добавьте необходимые поля:

```php
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('subdomain')->unique();
    $table->string('database_name')->unique();
    $table->timestamps();
});
```

### 4. Migration для каждой базы данных

Когда пользователь создается, необходимо создать базу данных для него. Для этого можно написать Artisan команду:

```bash
php artisan make:command CreateUserDatabase
```

Внутри команды реализуйте логику создания базы данных.

```php
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class CreateUserDatabase extends Command
{
    protected $signature = 'user:create-db {userId}';
    protected $description = 'Create a database for the specified user';

    public function handle()
    {
        $userId = $this->argument('userId');
        $user = User::find($userId);

        if ($user) {
            $dbName = $user->database_name;
            DB::statement("CREATE DATABASE $dbName");
            // Возможно, вам потребуется также настроить доступ пользователя к этой базе данных
            $this->info("Database $dbName created for user {$user->name}");
        } else {
            $this->error('User not found');
        }
    }
}
```

### 5. Настройка соединения с базой данных

В `config/database.php` добавьте логику для динамической настройки соединения с базой данных в зависимости от субдомена.

```php
$subdomain = request()->route()->parameter('subdomain');
$user = User::where('subdomain', $subdomain)->first();

if ($user) {
    config(['database.connections.mysql.database' => $user->database_name]);
}
```

### 6. Миграция баз данных

При создании базы данных пользователя вы можете выполнить команду миграции для создания необходимых таблиц:

```bash
php artisan migrate --database=mysql --path=database/migrations/user -- --database=$user->database_name
```

### 7. Сделайте маршрут для создания пользователя

Создайте маршрут для обработки регистрации пользователя и создания базы данных.

```php
use App\Http\Controllers\UserController;

Route::post('/register', [UserController::class, 'register']);
```

В контроллере `UserController` реализуйте метод `register`, который будет создавать пользователя и вызывать команду создания базы данных.

### 8. Запуск проекта

Убедитесь, что у вас правильно настроен Docker, и запустите проект:

```
Домен настраиваете согласно документации на ваш веб-сервер, а так же DNS сервер/провайдера. Управление отдельной БД для каждого пользователя реализуете в рамках логики вашего приложения. Конкретный механизм реализации зависит от вашего проекта, его требований и особенностей. Докер - это часть инфраструктуры, каких-то специфических настроек не требует для реализации данной задачи. Вот миграции - тут несколько сложнее и зависит от структуры БД и логики вашего проекта. Может как повторять структуру основной БД так и иметь свою отдельную структуру. Соответственно и миграции - либо в всё в одной куче либо отдельные кучки.
Похожие вопросы