refactor(railpack): extract static image build, fix port logic, bump to v0.22.0

Extract build_railpack_static_image() into its own method, prevent port
override when is_static is set, bump Railpack to 0.22.0, and improve
test setup with beforeEach and correct polymorphic env var fields.
This commit is contained in:
Aditya Tripathi 2026-03-23 19:02:10 +00:00
parent 793077d74f
commit cddbaf581f
7 changed files with 93 additions and 62 deletions

View file

@ -483,7 +483,7 @@ private function decide_what_to_do()
} elseif ($this->application->build_pack === 'railpack') { } elseif ($this->application->build_pack === 'railpack') {
$this->deploy_railpack_buildpack(); $this->deploy_railpack_buildpack();
} else { } else {
throw new \RuntimeException("Unsupported build pack: {$this->application->build_pack}"); throw new DeploymentException("Unsupported build pack: {$this->application->build_pack}");
} }
$this->post_deployment(); $this->post_deployment();
} }
@ -2517,6 +2517,12 @@ private function build_railpack_image(): void
// Step 3: If static, copy built assets into nginx image // Step 3: If static, copy built assets into nginx image
if ($this->application->settings->is_static) { if ($this->application->settings->is_static) {
$this->build_railpack_static_image();
}
}
private function build_railpack_static_image(): void
{
$publishDir = trim($this->application->publish_directory, '/'); $publishDir = trim($this->application->publish_directory, '/');
$publishDir = $publishDir ? "/{$publishDir}" : ''; $publishDir = $publishDir ? "/{$publishDir}" : '';
$dockerfile = base64_encode("FROM {$this->application->static_image} $dockerfile = base64_encode("FROM {$this->application->static_image}
@ -2546,7 +2552,6 @@ private function build_railpack_image(): void
[executeInDocker($this->deployment_uuid, 'bash '.self::BUILD_SCRIPT_PATH), 'hidden' => true], [executeInDocker($this->deployment_uuid, 'bash '.self::BUILD_SCRIPT_PATH), 'hidden' => true],
); );
} }
}
private function generate_coolify_env_variables(bool $forBuildTime = false): Collection private function generate_coolify_env_variables(bool $forBuildTime = false): Collection
{ {

View file

@ -84,7 +84,9 @@ public function updatedBuildPack()
{ {
if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') { if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') {
$this->show_is_static = true; $this->show_is_static = true;
if (! $this->is_static) {
$this->port = 3000; $this->port = 3000;
}
} elseif ($this->build_pack === 'static') { } elseif ($this->build_pack === 'static') {
$this->show_is_static = false; $this->show_is_static = false;
$this->is_static = false; $this->is_static = false;

View file

@ -97,7 +97,9 @@ public function updatedBuildPack()
{ {
if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') { if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') {
$this->show_is_static = true; $this->show_is_static = true;
if (! $this->is_static) {
$this->port = 3000; $this->port = 3000;
}
} elseif ($this->build_pack === 'static') { } elseif ($this->build_pack === 'static') {
$this->show_is_static = false; $this->show_is_static = false;
$this->is_static = false; $this->is_static = false;

View file

@ -101,7 +101,9 @@ public function updatedBuildPack()
{ {
if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') { if ($this->build_pack === 'nixpacks' || $this->build_pack === 'railpack') {
$this->show_is_static = true; $this->show_is_static = true;
if (! $this->isStatic) {
$this->port = 3000; $this->port = 3000;
}
} elseif ($this->build_pack === 'static') { } elseif ($this->build_pack === 'static') {
$this->show_is_static = false; $this->show_is_static = false;
$this->isStatic = false; $this->isStatic = false;

View file

@ -12,7 +12,7 @@ ARG PACK_VERSION=0.38.2
# https://github.com/railwayapp/nixpacks/releases # https://github.com/railwayapp/nixpacks/releases
ARG NIXPACKS_VERSION=1.41.0 ARG NIXPACKS_VERSION=1.41.0
# https://github.com/railwayapp/railpack/releases # https://github.com/railwayapp/railpack/releases
ARG RAILPACK_VERSION=0.21.0 ARG RAILPACK_VERSION=0.22.0
# https://github.com/jdx/mise/releases — must match railpack's pinned version (https://raw.githubusercontent.com/railwayapp/railpack/refs/heads/main/core/mise/version.txt) # https://github.com/jdx/mise/releases — must match railpack's pinned version (https://raw.githubusercontent.com/railwayapp/railpack/refs/heads/main/core/mise/version.txt)
ARG MISE_VERSION=2026.3.12 ARG MISE_VERSION=2026.3.12
# https://github.com/minio/mc/releases # https://github.com/minio/mc/releases

View file

@ -78,26 +78,29 @@
// Add environment variables that should be deleted // Add environment variables that should be deleted
EnvironmentVariable::create([ EnvironmentVariable::create([
'application_id' => $application->id, 'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'SERVICE_FQDN_APP', 'key' => 'SERVICE_FQDN_APP',
'value' => 'app.example.com', 'value' => 'app.example.com',
'is_build_time' => false, 'is_buildtime' => false,
'is_preview' => false, 'is_preview' => false,
]); ]);
EnvironmentVariable::create([ EnvironmentVariable::create([
'application_id' => $application->id, 'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'SERVICE_URL_APP', 'key' => 'SERVICE_URL_APP',
'value' => 'http://app.example.com', 'value' => 'http://app.example.com',
'is_build_time' => false, 'is_buildtime' => false,
'is_preview' => false, 'is_preview' => false,
]); ]);
EnvironmentVariable::create([ EnvironmentVariable::create([
'application_id' => $application->id, 'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'REGULAR_VAR', 'key' => 'REGULAR_VAR',
'value' => 'should_remain', 'value' => 'should_remain',
'is_build_time' => false, 'is_buildtime' => false,
'is_preview' => false, 'is_preview' => false,
]); ]);
@ -154,6 +157,34 @@
'docker_compose_raw' => 'version: "3.8"\nservices:\n app:\n image: nginx', 'docker_compose_raw' => 'version: "3.8"\nservices:\n app:\n image: nginx',
]); ]);
// Add environment variables that should be deleted
EnvironmentVariable::create([
'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'SERVICE_FQDN_APP',
'value' => 'app.example.com',
'is_buildtime' => false,
'is_preview' => false,
]);
EnvironmentVariable::create([
'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'SERVICE_URL_APP',
'value' => 'http://app.example.com',
'is_buildtime' => false,
'is_preview' => false,
]);
EnvironmentVariable::create([
'resourceable_type' => Application::class,
'resourceable_id' => $application->id,
'key' => 'REGULAR_VAR',
'value' => 'should_remain',
'is_buildtime' => false,
'is_preview' => false,
]);
$application->build_pack = 'railpack'; $application->build_pack = 'railpack';
$application->save(); $application->save();
$application->refresh(); $application->refresh();
@ -161,6 +192,13 @@
expect($application->build_pack)->toBe('railpack'); expect($application->build_pack)->toBe('railpack');
expect($application->docker_compose_domains)->toBeNull(); expect($application->docker_compose_domains)->toBeNull();
expect($application->docker_compose_raw)->toBeNull(); expect($application->docker_compose_raw)->toBeNull();
// Verify SERVICE_FQDN_* and SERVICE_URL_* were deleted
expect($application->environment_variables()->where('key', 'SERVICE_FQDN_APP')->count())->toBe(0);
expect($application->environment_variables()->where('key', 'SERVICE_URL_APP')->count())->toBe(0);
// Verify regular variables remain
expect($application->environment_variables()->where('key', 'REGULAR_VAR')->count())->toBe(1);
}); });
test('model does not clear dockerfile fields when switching to dockerfile', function () { test('model does not clear dockerfile fields when switching to dockerfile', function () {

View file

@ -10,13 +10,15 @@
uses(RefreshDatabase::class); uses(RefreshDatabase::class);
describe('Application Railpack Support', function () { describe('Application Railpack Support', function () {
test('could_set_build_commands returns true for railpack', function () { beforeEach(function () {
$team = Team::factory()->create(); $team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]); $project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]); $this->environment = Environment::factory()->create(['project_id' => $project->id]);
});
test('could_set_build_commands returns true for railpack', function () {
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'railpack', 'build_pack' => 'railpack',
]); ]);
@ -24,12 +26,8 @@
}); });
test('could_set_build_commands returns true for nixpacks', function () { test('could_set_build_commands returns true for nixpacks', function () {
$team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]);
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'nixpacks', 'build_pack' => 'nixpacks',
]); ]);
@ -37,12 +35,8 @@
}); });
test('could_set_build_commands returns false for dockerfile', function () { test('could_set_build_commands returns false for dockerfile', function () {
$team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]);
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'dockerfile', 'build_pack' => 'dockerfile',
]); ]);
@ -50,12 +44,8 @@
}); });
test('railpack_environment_variables returns only RAILPACK_ prefixed vars', function () { test('railpack_environment_variables returns only RAILPACK_ prefixed vars', function () {
$team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]);
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'railpack', 'build_pack' => 'railpack',
]); ]);
@ -92,12 +82,8 @@
}); });
test('runtime_environment_variables excludes RAILPACK_ and NIXPACKS_ prefixed vars', function () { test('runtime_environment_variables excludes RAILPACK_ and NIXPACKS_ prefixed vars', function () {
$team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]);
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'railpack', 'build_pack' => 'railpack',
]); ]);
@ -134,12 +120,8 @@
}); });
test('railpack_environment_variables_preview returns only RAILPACK_ prefixed preview vars', function () { test('railpack_environment_variables_preview returns only RAILPACK_ prefixed preview vars', function () {
$team = Team::factory()->create();
$project = Project::factory()->create(['team_id' => $team->id]);
$environment = Environment::factory()->create(['project_id' => $project->id]);
$application = Application::factory()->create([ $application = Application::factory()->create([
'environment_id' => $environment->id, 'environment_id' => $this->environment->id,
'build_pack' => 'railpack', 'build_pack' => 'railpack',
]); ]);