- Add multi-stage Dockerfile (node-builder, composer-builder, production) - Add Nginx config with WebSocket proxy at /_ws path - Add PHP-FPM pool config, php.ini with OPcache tuning - Add Supervisord managing 7 processes: php-fpm, nginx, horizon, scheduler, reverb, pulse-check, pulse-work - Add entrypoint.sh with auto-migration, config caching, storage setup - Add .dockerignore and .env.production.example - Install laravel/horizon for production queue management and dashboard - Install laravel/pulse for production monitoring with Reverb integration - Configure TrustProxies middleware for HTTPS behind Traefik - Add horizon:snapshot to scheduler - Add VITE_REVERB_PATH for WebSocket path routing through Nginx
85 lines
3.2 KiB
PHP
85 lines
3.2 KiB
PHP
<?php
|
|
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Laravel\Pulse\Support\PulseMigration;
|
|
|
|
return new class extends PulseMigration
|
|
{
|
|
/**
|
|
* Run the migrations.
|
|
*/
|
|
public function up(): void
|
|
{
|
|
if (! $this->shouldRun()) {
|
|
return;
|
|
}
|
|
|
|
Schema::create('pulse_values', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->unsignedInteger('timestamp');
|
|
$table->string('type');
|
|
$table->mediumText('key');
|
|
match ($this->driver()) {
|
|
'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
|
|
'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
|
|
'sqlite' => $table->string('key_hash'),
|
|
};
|
|
$table->mediumText('value');
|
|
|
|
$table->index('timestamp'); // For trimming...
|
|
$table->index('type'); // For fast lookups and purging...
|
|
$table->unique(['type', 'key_hash']); // For data integrity and upserts...
|
|
});
|
|
|
|
Schema::create('pulse_entries', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->unsignedInteger('timestamp');
|
|
$table->string('type');
|
|
$table->mediumText('key');
|
|
match ($this->driver()) {
|
|
'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
|
|
'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
|
|
'sqlite' => $table->string('key_hash'),
|
|
};
|
|
$table->bigInteger('value')->nullable();
|
|
|
|
$table->index('timestamp'); // For trimming...
|
|
$table->index('type'); // For purging...
|
|
$table->index('key_hash'); // For mapping...
|
|
$table->index(['timestamp', 'type', 'key_hash', 'value']); // For aggregate queries...
|
|
});
|
|
|
|
Schema::create('pulse_aggregates', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->unsignedInteger('bucket');
|
|
$table->unsignedMediumInteger('period');
|
|
$table->string('type');
|
|
$table->mediumText('key');
|
|
match ($this->driver()) {
|
|
'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
|
|
'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
|
|
'sqlite' => $table->string('key_hash'),
|
|
};
|
|
$table->string('aggregate');
|
|
$table->decimal('value', 20, 2);
|
|
$table->unsignedInteger('count')->nullable();
|
|
|
|
$table->unique(['bucket', 'period', 'type', 'aggregate', 'key_hash']); // Force "on duplicate update"...
|
|
$table->index(['period', 'bucket']); // For trimming...
|
|
$table->index('type'); // For purging...
|
|
$table->index(['period', 'type', 'aggregate', 'bucket']); // For aggregate queries...
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reverse the migrations.
|
|
*/
|
|
public function down(): void
|
|
{
|
|
Schema::dropIfExists('pulse_values');
|
|
Schema::dropIfExists('pulse_entries');
|
|
Schema::dropIfExists('pulse_aggregates');
|
|
}
|
|
};
|