mirror of
https://github.com/coollabsio/coolify.git
synced 2026-10-28 09:34:36 +08:00
chore(seeding): seed railpack examples from new repo layout
Move all git examples into ApplicationSeeder on railpack, using the reorganized coollabsio/coolify-examples main branch, and drop the separate Railpack Examples project. Add DEV_SEED_IP to set the IP for seeded sslip.io domains (e.g. a Tailscale IP). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a7e1cecfa7
commit
b13ecb0542
11 files changed
+194
-867
No files matched your search
@@ -9,6 +9,9 @@ APP_DEBUG=true
|
||||
SSH_MUX_ENABLED=true
|
||||
COOLIFY_CONTAINER_ROLE=all
|
||||
DEV_SENTINEL_URL=
|
||||
# IPv4 address for seeded sslip.io domains (server wildcard domain and example apps). Empty uses 127.0.0.1.
|
||||
# Set it to a LAN or Tailscale IP to reach seeded deployments from other devices, then reseed.
|
||||
DEV_SEED_IP=
|
||||
|
||||
# PostgreSQL Database Configuration
|
||||
DB_DATABASE=coolify
|
||||
|
||||
@@ -14,6 +14,8 @@ return [
|
||||
// devHostDockerPath() uses them only for that server. The defaults are the legacy docker-compose.dev.yml names.
|
||||
'dev_data_volume' => env('DEV_COOLIFY_DATA_VOLUME', 'coolify_dev_coolify_data'),
|
||||
'dev_backups_volume' => env('DEV_COOLIFY_BACKUPS_VOLUME', 'coolify_dev_backups_data'),
|
||||
// Development only: IP for the seeded sslip.io wildcard domain and application domains (for example a Tailscale IP).
|
||||
'dev_seed_ip' => env('DEV_SEED_IP') ?: '127.0.0.1',
|
||||
'registry_url' => env('REGISTRY_URL', 'docker.io'),
|
||||
'helper_image' => env('HELPER_IMAGE', env('REGISTRY_URL', 'docker.io').'/coollabsio/coolify-helper'),
|
||||
'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false),
|
||||
|
||||
@@ -10,18 +10,24 @@ use Illuminate\Database\Seeder;
|
||||
|
||||
class ApplicationSeeder extends Seeder
|
||||
{
|
||||
public const EXAMPLES_REPOSITORY = 'coollabsio/coolify-examples';
|
||||
|
||||
public const EXAMPLES_REPOSITORY_PROJECT_ID = 603035348;
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$sslipHost = ServerSettingSeeder::sslipHost();
|
||||
|
||||
Application::create([
|
||||
'uuid' => 'docker-compose',
|
||||
'name' => 'Docker Compose Example',
|
||||
'repository_project_id' => 603035348,
|
||||
'git_repository' => 'coollabsio/coolify-examples',
|
||||
'repository_project_id' => self::EXAMPLES_REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => self::EXAMPLES_REPOSITORY,
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => '/docker-compose',
|
||||
'base_directory' => '/internal/compose',
|
||||
'docker_compose_location' => '/docker-compose-test.yaml',
|
||||
'build_pack' => 'dockercompose',
|
||||
'ports_exposes' => '80',
|
||||
@@ -31,30 +37,14 @@ class ApplicationSeeder extends Seeder
|
||||
'source_id' => 1,
|
||||
'source_type' => GithubApp::class,
|
||||
]);
|
||||
Application::create([
|
||||
'uuid' => 'nodejs',
|
||||
'name' => 'NodeJS Fastify Example',
|
||||
'fqdn' => 'http://nodejs.127.0.0.1.sslip.io',
|
||||
'repository_project_id' => 603035348,
|
||||
'git_repository' => 'coollabsio/coolify-examples',
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => '/nodejs',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 0,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => 1,
|
||||
'source_type' => GithubApp::class,
|
||||
]);
|
||||
Application::create([
|
||||
'uuid' => 'dockerfile',
|
||||
'name' => 'Dockerfile Example',
|
||||
'fqdn' => 'http://dockerfile.127.0.0.1.sslip.io',
|
||||
'repository_project_id' => 603035348,
|
||||
'git_repository' => 'coollabsio/coolify-examples',
|
||||
'fqdn' => "http://dockerfile.{$sslipHost}",
|
||||
'repository_project_id' => self::EXAMPLES_REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => self::EXAMPLES_REPOSITORY,
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => '/dockerfile',
|
||||
'base_directory' => '/dockerfile/single-stage',
|
||||
'build_pack' => 'dockerfile',
|
||||
'ports_exposes' => '80',
|
||||
'environment_id' => 1,
|
||||
@@ -66,7 +56,7 @@ class ApplicationSeeder extends Seeder
|
||||
Application::create([
|
||||
'uuid' => 'dockerfile-pure',
|
||||
'name' => 'Pure Dockerfile Example',
|
||||
'fqdn' => 'http://pure-dockerfile.127.0.0.1.sslip.io',
|
||||
'fqdn' => "http://pure-dockerfile.{$sslipHost}",
|
||||
'git_repository' => 'coollabsio/coolify',
|
||||
'git_branch' => 'main',
|
||||
'git_commit_sha' => 'HEAD',
|
||||
@@ -99,51 +89,81 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
CMD ["sh", "-c", "echo Crashing in 5 seconds... && sleep 5 && exit 1"]
|
||||
',
|
||||
]);
|
||||
Application::create([
|
||||
'uuid' => 'github-deploy-key',
|
||||
'name' => 'GitHub Deploy Key Example',
|
||||
'fqdn' => 'http://github-deploy-key.127.0.0.1.sslip.io',
|
||||
'git_repository' => 'git@github.com:coollabsio/coolify-examples-deploy-key.git',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '80',
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 0,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => 0,
|
||||
'source_type' => GithubApp::class,
|
||||
'private_key_id' => 1,
|
||||
]);
|
||||
Application::create([
|
||||
'uuid' => 'gitlab-deploy-key',
|
||||
'name' => 'GitLab Deploy Key Example',
|
||||
'fqdn' => 'http://gitlab-deploy-key.127.0.0.1.sslip.io',
|
||||
'git_repository' => 'git@gitlab.com:coollabsio/php-example.git',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '80',
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 0,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
'private_key_id' => 1,
|
||||
]);
|
||||
Application::create([
|
||||
'uuid' => 'gitlab-public-example',
|
||||
'name' => 'GitLab Public Example',
|
||||
'fqdn' => 'http://gitlab-public.127.0.0.1.sslip.io',
|
||||
'git_repository' => 'https://gitlab.com/andrasbacsai/coolify-examples.git',
|
||||
'base_directory' => '/astro/static',
|
||||
'publish_directory' => '/dist',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '80',
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 0,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
]);
|
||||
|
||||
foreach (self::railpackExamples() as $example) {
|
||||
$application = Application::create([
|
||||
'uuid' => $example['uuid'],
|
||||
'name' => $example['name'],
|
||||
'fqdn' => "http://{$example['uuid']}.{$sslipHost}",
|
||||
'repository_project_id' => isset($example['git_repository']) ? null : self::EXAMPLES_REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => $example['git_repository'] ?? self::EXAMPLES_REPOSITORY,
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => $example['base_directory'] ?? '/',
|
||||
'publish_directory' => $example['publish_directory'] ?? null,
|
||||
'build_command' => $example['build_command'] ?? null,
|
||||
'start_command' => $example['start_command'] ?? null,
|
||||
'build_pack' => 'railpack',
|
||||
'static_image' => 'nginx:alpine',
|
||||
'ports_exposes' => $example['ports_exposes'],
|
||||
'environment_id' => 1,
|
||||
'destination_id' => 0,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => $example['source_id'] ?? 0,
|
||||
'source_type' => $example['source_type'] ?? GithubApp::class,
|
||||
'private_key_id' => $example['private_key_id'] ?? null,
|
||||
]);
|
||||
|
||||
$application->settings->update([
|
||||
'is_static' => $example['is_static'] ?? false,
|
||||
'is_spa' => $example['is_spa'] ?? false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Railpack examples from coollabsio/coolify-examples (main branch) and the deploy key / GitLab examples.
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function railpackExamples(): array
|
||||
{
|
||||
return [
|
||||
// JavaScript runtimes
|
||||
['uuid' => 'nodejs', 'name' => 'Node.js Fastify Example', 'base_directory' => '/javascript/runtimes/nodejs', 'ports_exposes' => '3000', 'source_id' => 1],
|
||||
['uuid' => 'bun', 'name' => 'Bun Example', 'base_directory' => '/javascript/runtimes/bun', 'ports_exposes' => '3000'],
|
||||
// JavaScript frameworks (server)
|
||||
['uuid' => 'nestjs', 'name' => 'NestJS Example', 'base_directory' => '/javascript/frameworks/nestjs', 'ports_exposes' => '3000', 'start_command' => 'npm run start:prod'],
|
||||
['uuid' => 'adonisjs', 'name' => 'AdonisJS Example', 'base_directory' => '/javascript/frameworks/adonisjs/simple', 'ports_exposes' => '3333'],
|
||||
['uuid' => 'remix', 'name' => 'Remix Example', 'base_directory' => '/javascript/frameworks/remix', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'nextjs-ssr', 'name' => 'Next.js SSR Example', 'base_directory' => '/javascript/frameworks/nextjs/ssr', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'nuxt-server', 'name' => 'Nuxt Server Example', 'base_directory' => '/javascript/frameworks/nuxt/server', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'nuxt-nitro', 'name' => 'Nuxt Nitro Example', 'base_directory' => '/javascript/frameworks/nuxt/nitro', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'astro-server', 'name' => 'Astro Server Example', 'base_directory' => '/javascript/frameworks/astro/server', 'ports_exposes' => '4321', 'start_command' => 'HOST=0.0.0.0 node dist/server/entry.mjs'],
|
||||
['uuid' => 'vue-ssr', 'name' => 'Vue SSR Example', 'base_directory' => '/javascript/frameworks/vue/ssr', 'ports_exposes' => '3000'],
|
||||
// JavaScript frameworks and build tools (static)
|
||||
['uuid' => 'nextjs-static', 'name' => 'Next.js Static Example', 'base_directory' => '/javascript/frameworks/nextjs/spa', 'ports_exposes' => '80', 'publish_directory' => '/out', 'is_static' => true],
|
||||
['uuid' => 'nuxt-static', 'name' => 'Nuxt Static Example', 'base_directory' => '/javascript/frameworks/nuxt/static', 'ports_exposes' => '80', 'build_command' => 'npm run generate', 'publish_directory' => '/.output/public', 'is_static' => true],
|
||||
['uuid' => 'astro-static', 'name' => 'Astro Static Example', 'base_directory' => '/javascript/frameworks/astro/static', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'is_static' => true],
|
||||
['uuid' => 'vue-spa', 'name' => 'Vue SPA Example', 'base_directory' => '/javascript/frameworks/vue/spa', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'is_static' => true, 'is_spa' => true],
|
||||
['uuid' => 'vue-spa-router', 'name' => 'Vue SPA Router Example', 'base_directory' => '/javascript/frameworks/vue/spa-router', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'is_static' => true, 'is_spa' => true],
|
||||
['uuid' => 'vite-vanilla-js', 'name' => 'Vite Vanilla JS Example', 'base_directory' => '/javascript/build-tools/vite/vanilla-js', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'is_static' => true],
|
||||
['uuid' => 'vite-vanilla-ts', 'name' => 'Vite Vanilla TS Example', 'base_directory' => '/javascript/build-tools/vite/vanilla-ts', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'is_static' => true],
|
||||
['uuid' => 'static', 'name' => 'Static HTML Example', 'base_directory' => '/static', 'ports_exposes' => '80', 'publish_directory' => '/', 'is_static' => true],
|
||||
// PHP
|
||||
['uuid' => 'laravel', 'name' => 'Laravel Example', 'base_directory' => '/php/laravel', 'ports_exposes' => '80'],
|
||||
['uuid' => 'laravel-pure', 'name' => 'Laravel Pure Example', 'base_directory' => '/php/laravel-pure', 'ports_exposes' => '80'],
|
||||
['uuid' => 'laravel-inertia', 'name' => 'Laravel Inertia Example', 'base_directory' => '/php/laravel-inertia', 'ports_exposes' => '80'],
|
||||
['uuid' => 'symfony', 'name' => 'Symfony Example', 'base_directory' => '/php/symfony', 'ports_exposes' => '80'],
|
||||
// Other languages
|
||||
['uuid' => 'python-flask', 'name' => 'Python Flask Example', 'base_directory' => '/python/flask', 'ports_exposes' => '5000', 'start_command' => 'flask run --host=0.0.0.0 --port=5000'],
|
||||
['uuid' => 'go-gin', 'name' => 'Go Gin Example', 'base_directory' => '/go/gin', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'rust-rocket', 'name' => 'Rust Rocket Example', 'base_directory' => '/rust/rocket', 'ports_exposes' => '8000'],
|
||||
['uuid' => 'ruby-rails', 'name' => 'Ruby on Rails Example', 'base_directory' => '/ruby/rails', 'ports_exposes' => '3000'],
|
||||
['uuid' => 'elixir-phoenix', 'name' => 'Elixir Phoenix Example', 'base_directory' => '/elixir/phoenix', 'ports_exposes' => '4000'],
|
||||
// Deploy keys and GitLab
|
||||
['uuid' => 'github-deploy-key', 'name' => 'GitHub Deploy Key Example', 'git_repository' => 'git@github.com:coollabsio/coolify-examples-deploy-key.git', 'ports_exposes' => '80', 'private_key_id' => 1],
|
||||
['uuid' => 'gitlab-deploy-key', 'name' => 'GitLab Deploy Key Example', 'git_repository' => 'git@gitlab.com:coollabsio/php-example.git', 'ports_exposes' => '80', 'source_id' => 1, 'source_type' => GitlabApp::class, 'private_key_id' => 1],
|
||||
['uuid' => 'gitlab-public-example', 'name' => 'GitLab Public Example', 'git_repository' => 'https://gitlab.com/andrasbacsai/coolify-examples.git', 'base_directory' => '/astro/static', 'ports_exposes' => '80', 'publish_directory' => '/dist', 'source_id' => 1, 'source_type' => GitlabApp::class, 'is_static' => true],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,5 @@ class ApplicationSettingsSeeder extends Seeder
|
||||
$application_1 = Application::find(1)->load(['settings']);
|
||||
$application_1->settings->is_debug_enabled = false;
|
||||
$application_1->settings->save();
|
||||
|
||||
$gitlabPublic = Application::where('uuid', 'gitlab-public-example')->first();
|
||||
if ($gitlabPublic) {
|
||||
$gitlabPublic->load(['settings']);
|
||||
$gitlabPublic->settings->is_static = true;
|
||||
$gitlabPublic->settings->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,5 @@ class DatabaseSeeder extends Seeder
|
||||
CaSslCertSeeder::class,
|
||||
PersonalAccessTokenSeeder::class,
|
||||
]);
|
||||
|
||||
if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {
|
||||
$this->call([
|
||||
DevelopmentRailpackExamplesSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,604 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\ProxyStatus;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Database\Seeder;
|
||||
use RuntimeException;
|
||||
|
||||
class DevelopmentRailpackExamplesSeeder extends Seeder
|
||||
{
|
||||
public const PROJECT_UUID = 'railpack-examples';
|
||||
|
||||
public const GIT_REPOSITORY = 'coollabsio/coolify-examples';
|
||||
|
||||
public const GIT_BRANCH = 'next';
|
||||
|
||||
public const REPOSITORY_PROJECT_ID = 603035348;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
if (! $this->isDevelopmentEnvironment()) {
|
||||
$this->command?->warn('Skipping DevelopmentRailpackExamplesSeeder outside development mode.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ensureDevelopmentPrerequisitesExist();
|
||||
|
||||
if (! StandaloneDocker::query()->find(0)) {
|
||||
throw new RuntimeException('StandaloneDocker with id=0 is required before running DevelopmentRailpackExamplesSeeder.');
|
||||
}
|
||||
|
||||
$this->cleanupLegacyLimaProjects();
|
||||
$this->cleanupLegacyProductionExamples();
|
||||
|
||||
$this->seedEnvironment(StandaloneDocker::query()->findOrFail(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function examples(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'uuid' => 'railpack-simple-webserver',
|
||||
'name' => 'Railpack Simple Webserver Example',
|
||||
'base_directory' => '/node/simple-webserver',
|
||||
'ports_exposes' => '3000',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-expressjs',
|
||||
'name' => 'Railpack Express.js Example',
|
||||
'base_directory' => '/node/expressjs',
|
||||
'ports_exposes' => '3000',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-fastify',
|
||||
'name' => 'Railpack Fastify Example',
|
||||
'base_directory' => '/node/fastify',
|
||||
'ports_exposes' => '3000',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-nestjs',
|
||||
'name' => 'Railpack NestJS Example',
|
||||
'base_directory' => '/node/nestjs',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start:prod',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-adonisjs',
|
||||
'name' => 'Railpack AdonisJS Example',
|
||||
'base_directory' => '/node/adonisjs',
|
||||
'ports_exposes' => '3333',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-hono',
|
||||
'name' => 'Railpack Hono Example',
|
||||
'base_directory' => '/node/hono',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-koa',
|
||||
'name' => 'Railpack Koa Example',
|
||||
'base_directory' => '/node/koa',
|
||||
'ports_exposes' => '3000',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-nextjs-ssr',
|
||||
'name' => 'Railpack Next.js SSR Example',
|
||||
'base_directory' => '/node/nextjs/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-nuxtjs-ssr',
|
||||
'name' => 'Railpack NuxtJS SSR Example',
|
||||
'base_directory' => '/node/nuxtjs/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run preview -- --host 0.0.0.0 --port 3000',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-astro-ssr',
|
||||
'name' => 'Railpack Astro SSR Example',
|
||||
'base_directory' => '/node/astro/ssr',
|
||||
'ports_exposes' => '4321',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-sveltekit-ssr',
|
||||
'name' => 'Railpack SvelteKit SSR Example',
|
||||
'base_directory' => '/node/sveltekit/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-tanstack-start-ssr',
|
||||
'name' => 'Railpack TanStack Start SSR Example',
|
||||
'base_directory' => '/node/tanstack-start/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-angular-ssr',
|
||||
'name' => 'Railpack Angular SSR Example',
|
||||
'base_directory' => '/node/angular/ssr',
|
||||
'ports_exposes' => '4000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-vue-ssr',
|
||||
'name' => 'Railpack Vue SSR Example',
|
||||
'base_directory' => '/node/vue/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run start',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-qwik-ssr',
|
||||
'name' => 'Railpack Qwik SSR Example',
|
||||
'base_directory' => '/node/qwik/ssr',
|
||||
'ports_exposes' => '3000',
|
||||
'build_command' => 'npm run build',
|
||||
'start_command' => 'npm run serve',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-react-static',
|
||||
'name' => 'Railpack React Static Example',
|
||||
'base_directory' => '/node/react',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-vite-static',
|
||||
'name' => 'Railpack Vite Static Example',
|
||||
'base_directory' => '/node/vite',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-eleventy-static',
|
||||
'name' => 'Railpack Eleventy Static Example',
|
||||
'base_directory' => '/node/eleventy',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/_site',
|
||||
'is_static' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-gatsby-static',
|
||||
'name' => 'Railpack Gatsby Static Example',
|
||||
'base_directory' => '/node/gatsby',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/public',
|
||||
'is_static' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-nextjs-static',
|
||||
'name' => 'Railpack Next.js Static Example',
|
||||
'base_directory' => '/node/nextjs/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/out',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-nuxtjs-static',
|
||||
'name' => 'Railpack NuxtJS Static Example',
|
||||
'base_directory' => '/node/nuxtjs/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/.output/public',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-astro-static',
|
||||
'name' => 'Railpack Astro Static Example',
|
||||
'base_directory' => '/node/astro/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist',
|
||||
'is_static' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-sveltekit-static',
|
||||
'name' => 'Railpack SvelteKit Static Example',
|
||||
'base_directory' => '/node/sveltekit/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/build',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-tanstack-start-static',
|
||||
'name' => 'Railpack TanStack Start Static Example',
|
||||
'base_directory' => '/node/tanstack-start/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/.output/public',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-angular-static',
|
||||
'name' => 'Railpack Angular Static Example',
|
||||
'base_directory' => '/node/angular/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist/static/browser',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-vue-static',
|
||||
'name' => 'Railpack Vue Static Example',
|
||||
'base_directory' => '/node/vue/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-qwik-static',
|
||||
'name' => 'Railpack Qwik Static Example',
|
||||
'base_directory' => '/node/qwik/static',
|
||||
'ports_exposes' => '80',
|
||||
'build_command' => 'npm run build',
|
||||
'publish_directory' => '/dist',
|
||||
'is_static' => true,
|
||||
'is_spa' => true,
|
||||
],
|
||||
// Multi-language examples on the main branch.
|
||||
[
|
||||
'uuid' => 'railpack-python-flask',
|
||||
'name' => 'Railpack Python Flask Example',
|
||||
'base_directory' => '/flask',
|
||||
'ports_exposes' => '5000',
|
||||
'git_branch' => 'main',
|
||||
'start_command' => 'flask run --host=0.0.0.0 --port=5000',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-go-gin',
|
||||
'name' => 'Railpack Go Gin Example',
|
||||
'base_directory' => '/go/gin',
|
||||
'ports_exposes' => '3000',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-rust',
|
||||
'name' => 'Railpack Rust Example',
|
||||
'base_directory' => '/rust',
|
||||
'ports_exposes' => '8000',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-laravel',
|
||||
'name' => 'Railpack Laravel Example',
|
||||
'base_directory' => '/laravel',
|
||||
'ports_exposes' => '80',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-laravel-pure',
|
||||
'name' => 'Railpack Laravel Pure Example',
|
||||
'base_directory' => '/laravel-pure',
|
||||
'ports_exposes' => '80',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-laravel-inertia',
|
||||
'name' => 'Railpack Laravel Inertia Example',
|
||||
'base_directory' => '/laravel-inertia',
|
||||
'ports_exposes' => '80',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-symfony',
|
||||
'name' => 'Railpack Symfony Example',
|
||||
'base_directory' => '/symfony',
|
||||
'ports_exposes' => '80',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-rails',
|
||||
'name' => 'Railpack Ruby on Rails Example',
|
||||
'base_directory' => '/rails-example',
|
||||
'ports_exposes' => '3000',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-elixir-phoenix',
|
||||
'name' => 'Railpack Elixir Phoenix Example',
|
||||
'base_directory' => '/elixir-phoenix',
|
||||
'ports_exposes' => '4000',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-bun',
|
||||
'name' => 'Railpack Bun Example',
|
||||
'base_directory' => '/bun',
|
||||
'ports_exposes' => '3000',
|
||||
'git_branch' => 'main',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-github-deploy-key',
|
||||
'name' => 'Railpack GitHub Deploy Key Example',
|
||||
'git_repository' => 'git@github.com:coollabsio/coolify-examples-deploy-key.git',
|
||||
'git_branch' => 'main',
|
||||
'ports_exposes' => '80',
|
||||
'private_key_id' => 1,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-gitlab-deploy-key',
|
||||
'name' => 'Railpack GitLab Deploy Key Example',
|
||||
'git_repository' => 'git@gitlab.com:coollabsio/php-example.git',
|
||||
'git_branch' => 'main',
|
||||
'ports_exposes' => '80',
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
'private_key_id' => 1,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-gitlab-public-example',
|
||||
'name' => 'Railpack GitLab Public Example',
|
||||
'git_repository' => 'https://gitlab.com/andrasbacsai/coolify-examples.git',
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => '/astro/static',
|
||||
'publish_directory' => '/dist',
|
||||
'ports_exposes' => '80',
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
'is_static' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function ensureDevelopmentPrerequisitesExist(): void
|
||||
{
|
||||
Team::query()->firstOrCreate(
|
||||
['id' => 0],
|
||||
[
|
||||
'name' => 'Root Team',
|
||||
'description' => 'The root team',
|
||||
'personal_team' => true,
|
||||
],
|
||||
);
|
||||
|
||||
PrivateKey::query()->firstOrCreate(
|
||||
['id' => 1],
|
||||
[
|
||||
'uuid' => 'ssh',
|
||||
'team_id' => 0,
|
||||
'name' => 'Testing Host Key',
|
||||
'description' => 'This is a test docker container',
|
||||
'private_key' => <<<'KEY'
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
|
||||
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
|
||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
KEY,
|
||||
],
|
||||
);
|
||||
|
||||
Server::query()->firstOrCreate(
|
||||
['id' => 0],
|
||||
[
|
||||
'uuid' => 'localhost',
|
||||
'name' => 'localhost',
|
||||
'description' => 'This is a test docker container in development mode',
|
||||
'ip' => 'coolify-testing-host',
|
||||
'team_id' => 0,
|
||||
'private_key_id' => 1,
|
||||
'proxy' => [
|
||||
'type' => ProxyTypes::TRAEFIK->value,
|
||||
'status' => ProxyStatus::EXITED->value,
|
||||
],
|
||||
],
|
||||
);
|
||||
|
||||
StandaloneDocker::query()->firstOrCreate(
|
||||
['id' => 0],
|
||||
[
|
||||
'uuid' => 'docker',
|
||||
'name' => 'Standalone Docker 1',
|
||||
'network' => 'coolify',
|
||||
'server_id' => 0,
|
||||
],
|
||||
);
|
||||
|
||||
$this->ensurePublicGithubSourceExists();
|
||||
$this->ensurePublicGitlabSourceExists();
|
||||
}
|
||||
|
||||
private function ensurePublicGithubSourceExists(): void
|
||||
{
|
||||
GithubApp::query()->firstOrCreate(
|
||||
['id' => 0],
|
||||
[
|
||||
'uuid' => 'github-public',
|
||||
'name' => 'Public GitHub',
|
||||
'api_url' => 'https://api.github.com',
|
||||
'html_url' => 'https://github.com',
|
||||
'is_public' => true,
|
||||
'team_id' => 0,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
private function ensurePublicGitlabSourceExists(): void
|
||||
{
|
||||
GitlabApp::query()->firstOrCreate(
|
||||
['id' => 1],
|
||||
[
|
||||
'uuid' => 'gitlab-public',
|
||||
'name' => 'Public GitLab',
|
||||
'api_url' => 'https://gitlab.com/api/v4',
|
||||
'html_url' => 'https://gitlab.com',
|
||||
'is_public' => true,
|
||||
'team_id' => 0,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
private function isDevelopmentEnvironment(): bool
|
||||
{
|
||||
return in_array(config('app.env'), ['local', 'development', 'dev'], true);
|
||||
}
|
||||
|
||||
private function cleanupLegacyLimaProjects(): void
|
||||
{
|
||||
Project::query()
|
||||
->whereIn('uuid', [
|
||||
'railpack-examples-lima-ubuntu-2404',
|
||||
'railpack-examples-lima-ubuntu-2604',
|
||||
])
|
||||
->get()
|
||||
->each(function (Project $project): void {
|
||||
Application::withTrashed()
|
||||
->whereIn('environment_id', $project->environments()->pluck('id'))
|
||||
->get()
|
||||
->each
|
||||
->forceDelete();
|
||||
|
||||
$project->delete();
|
||||
});
|
||||
}
|
||||
|
||||
private function cleanupLegacyProductionExamples(): void
|
||||
{
|
||||
$project = Project::query()->where('uuid', self::PROJECT_UUID)->first();
|
||||
|
||||
if (! $project) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application::withTrashed()
|
||||
->whereIn('environment_id', $project->environments()->pluck('id'))
|
||||
->whereIn('uuid', collect(self::examples())->pluck('uuid'))
|
||||
->get()
|
||||
->each
|
||||
->forceDelete();
|
||||
}
|
||||
|
||||
private function seedEnvironment(StandaloneDocker $destination): void
|
||||
{
|
||||
$environment = $this->prepareEnvironment();
|
||||
|
||||
foreach (self::examples() as $example) {
|
||||
$this->upsertApplication($environment, $destination, $example);
|
||||
}
|
||||
}
|
||||
|
||||
private function prepareEnvironment(): Environment
|
||||
{
|
||||
$project = Project::query()->firstOrNew(['uuid' => self::PROJECT_UUID]);
|
||||
$project->fill([
|
||||
'name' => 'Railpack Examples',
|
||||
'description' => 'Development-only Railpack examples from coollabsio/coolify-examples@next.',
|
||||
'team_id' => 0,
|
||||
]);
|
||||
$project->save();
|
||||
|
||||
$environment = $project->environments()->firstOrCreate(['name' => 'production']);
|
||||
|
||||
$project->environments()
|
||||
->whereKeyNot($environment->id)
|
||||
->get()
|
||||
->each(function (Environment $obsoleteEnvironment): void {
|
||||
Application::withTrashed()
|
||||
->where('environment_id', $obsoleteEnvironment->id)
|
||||
->get()
|
||||
->each
|
||||
->forceDelete();
|
||||
|
||||
$obsoleteEnvironment->delete();
|
||||
});
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $example
|
||||
*/
|
||||
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example): void
|
||||
{
|
||||
$uuid = $example['uuid'];
|
||||
$name = $example['name'];
|
||||
$application = Application::withTrashed()->firstOrNew(['uuid' => $uuid]);
|
||||
$application->fill([
|
||||
'name' => $name,
|
||||
'description' => $name,
|
||||
'fqdn' => "http://{$uuid}.127.0.0.1.sslip.io",
|
||||
'repository_project_id' => $example['repository_project_id'] ?? self::REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => $example['git_repository'] ?? self::GIT_REPOSITORY,
|
||||
'git_branch' => $example['git_branch'] ?? self::GIT_BRANCH,
|
||||
'build_pack' => 'railpack',
|
||||
'ports_exposes' => $example['ports_exposes'],
|
||||
'base_directory' => $example['base_directory'] ?? '/',
|
||||
'publish_directory' => $example['publish_directory'] ?? null,
|
||||
'static_image' => 'nginx:alpine',
|
||||
'install_command' => $example['install_command'] ?? null,
|
||||
'build_command' => $example['build_command'] ?? null,
|
||||
'start_command' => $example['start_command'] ?? null,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => $example['source_id'] ?? 0,
|
||||
'source_type' => $example['source_type'] ?? GithubApp::class,
|
||||
'private_key_id' => $example['private_key_id'] ?? null,
|
||||
]);
|
||||
$application->save();
|
||||
|
||||
if ($application->trashed()) {
|
||||
$application->restore();
|
||||
}
|
||||
|
||||
$application->settings()->updateOrCreate(
|
||||
['application_id' => $application->id],
|
||||
[
|
||||
'is_static' => $example['is_static'] ?? false,
|
||||
'is_spa' => $example['is_spa'] ?? false,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Database\Seeders;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Database\Seeder;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class ServerSettingSeeder extends Seeder
|
||||
{
|
||||
@@ -13,10 +14,24 @@ class ServerSettingSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$server_2 = Server::find(0)->load(['settings']);
|
||||
$server_2->settings->wildcard_domain = 'http://127.0.0.1.sslip.io';
|
||||
$server_2->settings->wildcard_domain = 'http://'.self::sslipHost();
|
||||
$server_2->settings->is_build_server = false;
|
||||
$server_2->settings->is_usable = true;
|
||||
$server_2->settings->is_reachable = true;
|
||||
$server_2->settings->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* The sslip.io host for seeded domains, based on DEV_SEED_IP (default 127.0.0.1).
|
||||
*/
|
||||
public static function sslipHost(): string
|
||||
{
|
||||
$ip = config('constants.coolify.dev_seed_ip');
|
||||
|
||||
if (! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
throw new InvalidArgumentException("DEV_SEED_IP must be an IPv4 address, got: {$ip}");
|
||||
}
|
||||
|
||||
return "{$ip}.sslip.io";
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -2,22 +2,22 @@
|
||||
#
|
||||
# Railpack end-to-end deploy smoke test against the local dev stack.
|
||||
#
|
||||
# Walks a curated set of railpack-* example apps from
|
||||
# DevelopmentRailpackExamplesSeeder, triggers a deploy via the Coolify API,
|
||||
# Walks a curated set of Railpack example apps from
|
||||
# ApplicationSeeder, triggers a deploy via the Coolify API,
|
||||
# waits for the deployment queue to finish, then exec()s into the resulting
|
||||
# container and checks that COOLIFY_*, SOURCE_COMMIT, and any RAILPACK_*
|
||||
# build inputs landed correctly. Optionally curls the FQDN.
|
||||
#
|
||||
# Requires:
|
||||
# - Dev stack running: docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
|
||||
# - Seeder run: php artisan db:seed --class=DevelopmentRailpackExamplesSeeder
|
||||
# - Seeder run: php artisan migrate:fresh --seed
|
||||
# - Personal token: PersonalAccessTokenSeeder run (creates Bearer 'root')
|
||||
# - jq, curl available on host
|
||||
#
|
||||
# Usage:
|
||||
# scripts/railpack-smoke.sh # default subset
|
||||
# scripts/railpack-smoke.sh --app railpack-laravel # single app
|
||||
# scripts/railpack-smoke.sh --all # every seeded railpack-* app
|
||||
# scripts/railpack-smoke.sh --app laravel # single app
|
||||
# scripts/railpack-smoke.sh --all # every seeded Railpack app
|
||||
# scripts/railpack-smoke.sh --timeout 900 # build wait per app, seconds
|
||||
# scripts/railpack-smoke.sh --no-curl # skip FQDN curl
|
||||
# scripts/railpack-smoke.sh --extra-env KEY=VALUE # build+runtime env (alias of --both-env)
|
||||
@@ -37,16 +37,16 @@ BOTH_ENVS=()
|
||||
APPS=()
|
||||
|
||||
DEFAULT_APPS=(
|
||||
railpack-expressjs
|
||||
railpack-nestjs
|
||||
railpack-nextjs-ssr
|
||||
railpack-vite-static
|
||||
railpack-astro-static
|
||||
railpack-python-flask
|
||||
railpack-go-gin
|
||||
railpack-rust
|
||||
railpack-symfony
|
||||
railpack-bun
|
||||
nodejs
|
||||
nestjs
|
||||
nextjs-ssr
|
||||
vite-vanilla-js
|
||||
astro-static
|
||||
python-flask
|
||||
go-gin
|
||||
rust-rocket
|
||||
symfony
|
||||
bun
|
||||
)
|
||||
|
||||
while (( $# > 0 )); do
|
||||
@@ -87,7 +87,7 @@ if (( ${#APPS[@]} == 0 )); then
|
||||
fi
|
||||
|
||||
if [[ "${APPS[0]}" == "__ALL__" ]]; then
|
||||
mapfile -t APPS < <(curl_api GET /applications | jq -r '.[].uuid' | grep '^railpack-' || true)
|
||||
mapfile -t APPS < <(curl_api GET /applications | jq -r '.[] | select(.build_pack == "railpack") | .uuid' || true)
|
||||
fi
|
||||
|
||||
log() { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"; }
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use Database\Seeders\ApplicationSeeder;
|
||||
use Database\Seeders\GithubAppSeeder;
|
||||
use Database\Seeders\GitlabAppSeeder;
|
||||
use Database\Seeders\PrivateKeySeeder;
|
||||
use Database\Seeders\ProjectSeeder;
|
||||
use Database\Seeders\ServerSeeder;
|
||||
use Database\Seeders\ServerSettingSeeder;
|
||||
use Database\Seeders\StandaloneDockerSeeder;
|
||||
use Database\Seeders\TeamSeeder;
|
||||
use Database\Seeders\UserSeeder;
|
||||
@@ -13,8 +18,9 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('seeds the default applications without railpack examples', function () {
|
||||
$this->seed([
|
||||
function seedApplicationSeederPrerequisites(): void
|
||||
{
|
||||
test()->seed([
|
||||
UserSeeder::class,
|
||||
TeamSeeder::class,
|
||||
PrivateKeySeeder::class,
|
||||
@@ -22,22 +28,65 @@ it('seeds the default applications without railpack examples', function () {
|
||||
ProjectSeeder::class,
|
||||
StandaloneDockerSeeder::class,
|
||||
GithubAppSeeder::class,
|
||||
ApplicationSeeder::class,
|
||||
GitlabAppSeeder::class,
|
||||
]);
|
||||
}
|
||||
|
||||
$nixpacksExample = Application::where('uuid', 'nodejs')->first();
|
||||
|
||||
expect($nixpacksExample)
|
||||
->not->toBeNull()
|
||||
->and($nixpacksExample->name)->toBe('NodeJS Fastify Example')
|
||||
->and($nixpacksExample->build_pack)->toBe('nixpacks')
|
||||
->and($nixpacksExample->base_directory)->toBe('/nodejs')
|
||||
->and($nixpacksExample->ports_exposes)->toBe('3000');
|
||||
|
||||
expect(Application::query()->where('build_pack', 'railpack')->exists())->toBeFalse();
|
||||
expect(Application::query()->whereIn('uuid', ['railpack-nodejs', 'railpack-static'])->exists())->toBeFalse();
|
||||
|
||||
expect(Application::query()
|
||||
->whereIn('git_repository', ['coollabsio/coolify-examples', 'coollabsio/coolify'])
|
||||
->pluck('git_branch')->unique()->all())->toBe(['main']);
|
||||
beforeEach(function () {
|
||||
config()->set('constants.coolify.dev_seed_ip', '127.0.0.1');
|
||||
});
|
||||
|
||||
it('seeds every git example as railpack in the default project', function () {
|
||||
seedApplicationSeederPrerequisites();
|
||||
$this->seed(ApplicationSeeder::class);
|
||||
|
||||
$railpackUuids = collect(ApplicationSeeder::railpackExamples())->pluck('uuid')->sort()->values()->all();
|
||||
|
||||
expect(Application::query()->where('build_pack', 'railpack')->pluck('uuid')->sort()->values()->all())->toBe($railpackUuids)
|
||||
->and(Application::query()->whereNotIn('build_pack', ['railpack', 'dockerfile', 'dockercompose'])->exists())->toBeFalse()
|
||||
->and(Project::query()->count())->toBe(1)
|
||||
->and(Application::query()->pluck('environment_id')->unique()->all())->toBe([1])
|
||||
->and(Application::query()->whereNotNull('git_branch')->pluck('git_branch')->unique()->all())->toBe(['main']);
|
||||
});
|
||||
|
||||
it('seeds railpack examples with the new example repository layout', function () {
|
||||
seedApplicationSeederPrerequisites();
|
||||
$this->seed(ApplicationSeeder::class);
|
||||
|
||||
$nodejs = Application::query()->where('uuid', 'nodejs')->sole();
|
||||
$astroServer = Application::query()->where('uuid', 'astro-server')->sole();
|
||||
$vueSpa = Application::query()->where('uuid', 'vue-spa')->with('settings')->sole();
|
||||
$gitlabPublic = Application::query()->where('uuid', 'gitlab-public-example')->with('settings')->sole();
|
||||
$compose = Application::query()->where('uuid', 'docker-compose')->sole();
|
||||
|
||||
expect($nodejs->git_repository)->toBe(ApplicationSeeder::EXAMPLES_REPOSITORY)
|
||||
->and($nodejs->base_directory)->toBe('/javascript/runtimes/nodejs')
|
||||
->and($nodejs->fqdn)->toBe('http://nodejs.127.0.0.1.sslip.io')
|
||||
->and($astroServer->start_command)->toBe('HOST=0.0.0.0 node dist/server/entry.mjs')
|
||||
->and($vueSpa->publish_directory)->toBe('/dist')
|
||||
->and($vueSpa->settings->is_static)->toBeTrue()
|
||||
->and($vueSpa->settings->is_spa)->toBeTrue()
|
||||
->and($gitlabPublic->source_type)->toBe(GitlabApp::class)
|
||||
->and($gitlabPublic->repository_project_id)->toBeNull()
|
||||
->and($gitlabPublic->settings->is_static)->toBeTrue()
|
||||
->and($compose->base_directory)->toBe('/internal/compose');
|
||||
});
|
||||
|
||||
it('uses DEV_SEED_IP for the server wildcard domain and application domains', function () {
|
||||
config()->set('constants.coolify.dev_seed_ip', '100.64.1.2');
|
||||
|
||||
seedApplicationSeederPrerequisites();
|
||||
$this->seed([ServerSettingSeeder::class, ApplicationSeeder::class]);
|
||||
|
||||
expect(Server::query()->find(0)->settings->wildcard_domain)->toBe('http://100.64.1.2.sslip.io')
|
||||
->and(Application::query()->where('uuid', 'nodejs')->value('fqdn'))->toBe('http://nodejs.100.64.1.2.sslip.io')
|
||||
->and(Application::query()->where('uuid', 'dockerfile')->value('fqdn'))->toBe('http://dockerfile.100.64.1.2.sslip.io')
|
||||
->and(Application::query()->whereNotNull('fqdn')->where('fqdn', 'not like', '%.100.64.1.2.sslip.io')->exists())->toBeFalse();
|
||||
});
|
||||
|
||||
it('rejects a DEV_SEED_IP that is not an IPv4 address', function (string $value) {
|
||||
config()->set('constants.coolify.dev_seed_ip', $value);
|
||||
|
||||
ServerSettingSeeder::sslipHost();
|
||||
})->with(['hostname' => 'devserver.ts.net', 'ipv6' => 'fd7a:115c:a1e0::1', 'injection' => '1.2.3.4; rm -rf /'])
|
||||
->throws(InvalidArgumentException::class);
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
it('runs the normal development database seeder without v5 seeders', function () {
|
||||
$databaseSeeder = file_get_contents(database_path('seeders/DatabaseSeeder.php'));
|
||||
$developmentSeederBlock = str($databaseSeeder)->after("if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {")->before(' }')->toString();
|
||||
|
||||
expect($developmentSeederBlock)->toContain('DevelopmentRailpackExamplesSeeder::class')
|
||||
->and($developmentSeederBlock)->not->toContain('V5DevLimaSeeder::class');
|
||||
});
|
||||
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use Database\Seeders\DevelopmentRailpackExamplesSeeder;
|
||||
use Database\Seeders\GithubAppSeeder;
|
||||
use Database\Seeders\PrivateKeySeeder;
|
||||
use Database\Seeders\ProjectSeeder;
|
||||
use Database\Seeders\ServerSeeder;
|
||||
use Database\Seeders\StandaloneDockerSeeder;
|
||||
use Database\Seeders\TeamSeeder;
|
||||
use Database\Seeders\UserSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function seedRailpackExamplePrerequisites(): void
|
||||
{
|
||||
test()->seed([
|
||||
UserSeeder::class,
|
||||
TeamSeeder::class,
|
||||
PrivateKeySeeder::class,
|
||||
ServerSeeder::class,
|
||||
ProjectSeeder::class,
|
||||
StandaloneDockerSeeder::class,
|
||||
GithubAppSeeder::class,
|
||||
]);
|
||||
}
|
||||
|
||||
it('can seed the railpack examples directly on a clean development database', function () {
|
||||
config()->set('app.env', 'local');
|
||||
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
|
||||
expect(Team::query()->find(0))->not->toBeNull()
|
||||
->and(PrivateKey::query()->find(1))->not->toBeNull()
|
||||
->and(Server::query()->count())->toBe(1)
|
||||
->and(Server::query()->find(0)?->uuid)->toBe('localhost')
|
||||
->and(StandaloneDocker::query()->find(0))->not->toBeNull()
|
||||
->and(GithubApp::query()->find(0))->not->toBeNull()
|
||||
->and(GitlabApp::query()->find(1))->not->toBeNull()
|
||||
->and(Application::query()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
|
||||
|
||||
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
|
||||
|
||||
expect($project->environments)->toHaveCount(1)
|
||||
->and($project->environments->first()->name)->toBe('production')
|
||||
->and($project->applications()->whereRelation('destination.server', 'uuid', 'localhost')->count())
|
||||
->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
|
||||
});
|
||||
|
||||
it('seeds every railpack example in the production environment on testing-host', function () {
|
||||
config()->set('app.env', 'local');
|
||||
|
||||
seedRailpackExamplePrerequisites();
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
|
||||
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
|
||||
$environment = $project->environments()->sole();
|
||||
$applications = $environment->applications()->with('settings', 'destination.server')->orderBy('uuid')->get();
|
||||
|
||||
expect($environment->name)->toBe('production')
|
||||
->and($applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()))
|
||||
->and($applications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue()
|
||||
->and($applications->every(fn (Application $application) => $application->destination->server->uuid === 'localhost'))->toBeTrue()
|
||||
->and($applications->pluck('uuid')->sort()->values()->all())
|
||||
->toBe(collect(DevelopmentRailpackExamplesSeeder::examples())->pluck('uuid')->sort()->values()->all());
|
||||
|
||||
$nestjs = $applications->firstWhere('uuid', 'railpack-nestjs');
|
||||
$angularStatic = $applications->firstWhere('uuid', 'railpack-angular-static');
|
||||
$githubDeployKey = $applications->firstWhere('uuid', 'railpack-github-deploy-key');
|
||||
$gitlabDeployKey = $applications->firstWhere('uuid', 'railpack-gitlab-deploy-key');
|
||||
|
||||
expect($applications->where('git_repository', DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY)
|
||||
->pluck('git_branch')->unique()->sort()->values()->all())->toBe(['main', 'next'])
|
||||
->and($applications->firstWhere('uuid', 'railpack-python-flask')->git_branch)->toBe('main')
|
||||
->and($nestjs->git_branch)->toBe('next');
|
||||
|
||||
expect($nestjs->base_directory)->toBe('/node/nestjs')
|
||||
->and($nestjs->build_command)->toBe('npm run build')
|
||||
->and($nestjs->start_command)->toBe('npm run start:prod')
|
||||
->and($angularStatic->publish_directory)->toBe('/dist/static/browser')
|
||||
->and($angularStatic->settings->is_static)->toBeTrue()
|
||||
->and($githubDeployKey->private_key_id)->toBe(1)
|
||||
->and($githubDeployKey->source_type)->toBe(GithubApp::class)
|
||||
->and($gitlabDeployKey->source_type)->toBe(GitlabApp::class);
|
||||
});
|
||||
|
||||
it('consolidates legacy railpack environments into production', function () {
|
||||
config()->set('app.env', 'local');
|
||||
|
||||
seedRailpackExamplePrerequisites();
|
||||
$project = Project::query()->create([
|
||||
'uuid' => DevelopmentRailpackExamplesSeeder::PROJECT_UUID,
|
||||
'name' => 'Railpack Examples',
|
||||
'team_id' => 0,
|
||||
]);
|
||||
$project->environments()->first()->update(['name' => 'ubuntu24', 'uuid' => 'railpack-examples-ubuntu24']);
|
||||
$project->environments()->create(['name' => 'ubuntu26', 'uuid' => 'railpack-examples-ubuntu26']);
|
||||
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
|
||||
$project->refresh();
|
||||
|
||||
expect($project->environments)->toHaveCount(1)
|
||||
->and($project->environments->first()->name)->toBe('production')
|
||||
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
|
||||
});
|
||||
|
||||
it('skips the railpack examples outside development mode', function () {
|
||||
config()->set('app.env', 'testing');
|
||||
|
||||
seedRailpackExamplePrerequisites();
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
|
||||
expect(Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->exists())->toBeFalse();
|
||||
});
|
||||
|
||||
it('is idempotent when run multiple times', function () {
|
||||
config()->set('app.env', 'local');
|
||||
|
||||
seedRailpackExamplePrerequisites();
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
$this->seed(DevelopmentRailpackExamplesSeeder::class);
|
||||
|
||||
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
|
||||
|
||||
expect($project->environments)->toHaveCount(1)
|
||||
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
|
||||
});
|
||||
Reference in new issue
Block a user