fix(railpack): pass command overrides through supported prepare/build args

Use Railpack's install env handling and dedicated CLI flags for build/start overrides, and forward install commands into docker build secrets so image builds stay aligned with prepare-time configuration. Update the railpack config test to cover the new command format.
This commit is contained in:
Andras Bacsai 2026-04-09 19:01:52 +02:00
parent d7e1b7ec37
commit 3c51b1aacc
2 changed files with 30 additions and 31 deletions

View file

@ -2540,25 +2540,6 @@ private function railpack_config_overrides(): array
return [];
}
private function railpack_prepare_environment_variables(): Collection
{
$variables = collect([]);
if ($this->application->install_command) {
$variables->put('RAILPACK_INSTALL_CMD', $this->application->install_command);
}
if ($this->application->build_command) {
$variables->put('RAILPACK_BUILD_CMD', $this->application->build_command);
}
if ($this->application->start_command) {
$variables->put('RAILPACK_START_CMD', $this->application->start_command);
}
return $variables;
}
private function generated_railpack_config_relative_path(): string
{
return self::RAILPACK_GENERATED_CONFIG_PATH;
@ -2627,12 +2608,17 @@ private function generate_railpack_config_file(): ?string
private function railpack_prepare_command(?string $configFilePath = null): string
{
$prepare_command = 'railpack prepare';
$prepareEnvironmentVariables = $this->railpack_prepare_environment_variables()
->map(fn ($value, $key) => "{$key}=".escapeShellValue($value))
->implode(' ');
if ($prepareEnvironmentVariables !== '') {
$prepare_command = "{$prepareEnvironmentVariables} {$prepare_command}";
if ($this->application->install_command) {
$prepare_command .= ' --env '.escapeShellValue("RAILPACK_INSTALL_CMD={$this->application->install_command}");
}
if ($this->application->build_command) {
$prepare_command .= ' --build-cmd '.escapeShellValue($this->application->build_command);
}
if ($this->application->start_command) {
$prepare_command .= ' --start-cmd '.escapeShellValue($this->application->start_command);
}
if ($this->env_railpack_args) {
@ -2681,11 +2667,22 @@ private function build_railpack_image(): void
$cache_args = "--build-arg cache-key='{$this->application->uuid}'";
}
$installCommandEnv = '';
$installCommandSecret = '';
if ($this->application->install_command) {
$installCommandEnv = 'env RAILPACK_INSTALL_CMD='.escapeShellValue($this->application->install_command).' ';
$installCommandSecret = ' --secret id=RAILPACK_INSTALL_CMD,env=RAILPACK_INSTALL_CMD';
$cache_args .= ' --build-arg secrets-hash='.$this->generate_secrets_hash(collect([
'RAILPACK_INSTALL_CMD' => $this->application->install_command,
]));
}
$build_command = 'docker buildx create --name coolify-railpack --driver docker-container 2>/dev/null || true'
.' && docker buildx build --builder coolify-railpack'
." && {$installCommandEnv}docker buildx build --builder coolify-railpack"
." {$this->addHosts} --network host"
." --build-arg BUILDKIT_SYNTAX='ghcr.io/railwayapp/railpack-frontend'"
." {$cache_args}"
."{$installCommandSecret}"
.' -f /artifacts/railpack-plan.json'
.' --progress plain'
.' --load'

View file

@ -167,7 +167,7 @@ function invokeRailpackMethod(object $job, ReflectionClass $reflection, string $
->toThrow(DeploymentException::class, 'Invalid repository railpack.json');
});
it('builds railpack prepare command using process env vars for command overrides', function () {
it('builds railpack prepare command using railpack env for install and cli flags for build/start overrides', function () {
[$job, $reflection] = makeRailpackDeploymentJob(
[
'install_command' => 'npm ci',
@ -183,13 +183,15 @@ function invokeRailpackMethod(object $job, ReflectionClass $reflection, string $
['.coolify/railpack.generated.json'],
);
expect($command)->toContain("railpack prepare --env 'RAILPACK_NODE_VERSION=22'");
expect($command)->toContain('RAILPACK_INSTALL_CMD='.escapeshellarg('npm ci'));
expect($command)->toContain('RAILPACK_BUILD_CMD='.escapeshellarg('npm run build'));
expect($command)->toContain('RAILPACK_START_CMD='.escapeshellarg('node server.js'));
expect($command)->toContain('railpack prepare');
expect($command)->toContain('--env '.escapeshellarg('RAILPACK_INSTALL_CMD=npm ci'));
expect($command)->toContain("--env 'RAILPACK_NODE_VERSION=22'");
expect($command)->toContain('--build-cmd '.escapeshellarg('npm run build'));
expect($command)->toContain('--start-cmd '.escapeshellarg('node server.js'));
expect($command)->toContain('--config-file '.escapeshellarg('.coolify/railpack.generated.json'));
expect($command)->toContain('--plan-out /artifacts/railpack-plan.json /artifacts/test-app');
expect($command)->not->toContain("--env 'RAILPACK_BUILD_CMD=");
expect($command)->not->toContain("--env 'RAILPACK_START_CMD=");
expect($command)->not->toContain("--env 'RAILPACK_INSTALL_CMD=");
expect($command)->not->toContain('RAILPACK_BUILD_CMD=');
expect($command)->not->toContain('RAILPACK_START_CMD=');
});