mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-12 15:53:46 -04:00
fix(deploy): keep start-time buildpack vars in runtime env (#12025)
This commit is contained in:
@@ -2600,6 +2600,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
$nixpacks_php_fallback_path->value = '/index.php';
|
||||
$nixpacks_php_fallback_path->resourceable_id = $this->application->id;
|
||||
$nixpacks_php_fallback_path->resourceable_type = 'App\Models\Application';
|
||||
$nixpacks_php_fallback_path->is_preview = $this->pull_request_id !== 0;
|
||||
$nixpacks_php_fallback_path->save();
|
||||
}
|
||||
if (! $nixpacks_php_root_dir) {
|
||||
@@ -2608,6 +2609,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
$nixpacks_php_root_dir->value = '/app/public';
|
||||
$nixpacks_php_root_dir->resourceable_id = $this->application->id;
|
||||
$nixpacks_php_root_dir->resourceable_type = 'App\Models\Application';
|
||||
$nixpacks_php_root_dir->is_preview = $this->pull_request_id !== 0;
|
||||
$nixpacks_php_root_dir->save();
|
||||
}
|
||||
|
||||
|
||||
@@ -1109,7 +1109,7 @@ class Application extends BaseModel
|
||||
{
|
||||
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||
->where('is_preview', false)
|
||||
->withoutBuildpackControlVariables();
|
||||
->withoutBuildOnlyBuildpackControlVariables();
|
||||
}
|
||||
|
||||
public function nixpacks_environment_variables()
|
||||
@@ -1144,7 +1144,7 @@ class Application extends BaseModel
|
||||
{
|
||||
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||
->where('is_preview', true)
|
||||
->withoutBuildpackControlVariables();
|
||||
->withoutBuildOnlyBuildpackControlVariables();
|
||||
}
|
||||
|
||||
public function nixpacks_environment_variables_preview()
|
||||
|
||||
@@ -40,6 +40,17 @@ class EnvironmentVariable extends BaseModel
|
||||
|
||||
public const BUILDPACK_CONTROL_VARIABLE_PREFIXES = ['NIXPACKS_', 'RAILPACK_'];
|
||||
|
||||
/**
|
||||
* Buildpack control variables that the built image reads when the container starts,
|
||||
* e.g. the Nixpacks PHP prestart script renders nginx.conf from NIXPACKS_PHP_ROOT_DIR.
|
||||
*/
|
||||
public const RUNTIME_BUILDPACK_CONTROL_VARIABLES = [
|
||||
'NIXPACKS_PHP_ROOT_DIR',
|
||||
'NIXPACKS_PHP_FALLBACK_PATH',
|
||||
'NIXPACKS_SPA_OUTPUT_DIR',
|
||||
'RAILPACK_SKIP_MIGRATIONS',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'is_runtime' => true,
|
||||
'is_buildtime' => true,
|
||||
@@ -159,6 +170,14 @@ class EnvironmentVariable extends BaseModel
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function scopeWithoutBuildOnlyBuildpackControlVariables(Builder $query): Builder
|
||||
{
|
||||
return $query->where(function (Builder $query) {
|
||||
$query->whereIn('key', self::RUNTIME_BUILDPACK_CONTROL_VARIABLES)
|
||||
->orWhere(fn (Builder $query) => $query->withoutBuildpackControlVariables());
|
||||
});
|
||||
}
|
||||
|
||||
public static function isBuildpackControlKey(?string $key): bool
|
||||
{
|
||||
if (blank($key)) {
|
||||
|
||||
@@ -943,6 +943,93 @@ it('filters buildpack control vars from preview runtime env fallback', function
|
||||
expect($runtimeEnvs->contains(fn (string $env) => str($env)->startsWith('RAILPACK_NODE_VERSION=')))->toBeFalse();
|
||||
});
|
||||
|
||||
it('keeps buildpack variables read at container start in the runtime env', function (int $pullRequestId, bool $isPreview) {
|
||||
[$application, $server] = makeDeploymentControlVarFixture(['build_pack' => 'nixpacks']);
|
||||
|
||||
foreach ([
|
||||
'APP_NAME' => 'coolify',
|
||||
'NIXPACKS_PHP_ROOT_DIR' => '/app/public',
|
||||
'NIXPACKS_PHP_FALLBACK_PATH' => '/index.php',
|
||||
'NIXPACKS_SPA_OUTPUT_DIR' => 'dist',
|
||||
'RAILPACK_SKIP_MIGRATIONS' => 'true',
|
||||
'NIXPACKS_NODE_VERSION' => '22',
|
||||
'RAILPACK_NODE_VERSION' => '20',
|
||||
] as $key => $value) {
|
||||
createApplicationEnvironmentVariable($application, [
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'is_preview' => $isPreview,
|
||||
]);
|
||||
}
|
||||
|
||||
[$job, $reflection] = makeControlVarFilteringJob($application, $server, [
|
||||
'pull_request_id' => $pullRequestId,
|
||||
]);
|
||||
|
||||
/** @var Collection $runtimeEnvs */
|
||||
$runtimeEnvs = invokeDeploymentJobMethod($job, $reflection, 'generate_runtime_environment_variables');
|
||||
|
||||
expect($runtimeEnvs)->toContain(
|
||||
'APP_NAME='.escapeComposeEnvFileValue('coolify'),
|
||||
'NIXPACKS_PHP_ROOT_DIR='.escapeComposeEnvFileValue('/app/public'),
|
||||
'NIXPACKS_PHP_FALLBACK_PATH='.escapeComposeEnvFileValue('/index.php'),
|
||||
'NIXPACKS_SPA_OUTPUT_DIR='.escapeComposeEnvFileValue('dist'),
|
||||
'RAILPACK_SKIP_MIGRATIONS='.escapeComposeEnvFileValue('true'),
|
||||
);
|
||||
expect($runtimeEnvs->contains(fn (string $env) => str($env)->startsWith('NIXPACKS_NODE_VERSION=')))->toBeFalse();
|
||||
expect($runtimeEnvs->contains(fn (string $env) => str($env)->startsWith('RAILPACK_NODE_VERSION=')))->toBeFalse();
|
||||
})->with([
|
||||
'production' => [0, false],
|
||||
'preview' => [42, true],
|
||||
]);
|
||||
|
||||
it('keeps buildpack variables read at container start out of generic build args', function () {
|
||||
[$application, $server] = makeDeploymentControlVarFixture();
|
||||
|
||||
createApplicationEnvironmentVariable($application, [
|
||||
'key' => 'NIXPACKS_PHP_ROOT_DIR',
|
||||
'value' => '/app/public',
|
||||
]);
|
||||
createApplicationEnvironmentVariable($application, [
|
||||
'key' => 'RAILPACK_SKIP_MIGRATIONS',
|
||||
'value' => 'true',
|
||||
]);
|
||||
|
||||
[$job, $reflection] = makeControlVarFilteringJob($application, $server);
|
||||
|
||||
invokeDeploymentJobMethod($job, $reflection, 'generate_env_variables');
|
||||
|
||||
/** @var Collection $envArgs */
|
||||
$envArgs = readDeploymentJobProperty($job, $reflection, 'env_args');
|
||||
|
||||
expect($envArgs->has('NIXPACKS_PHP_ROOT_DIR'))->toBeFalse();
|
||||
expect($envArgs->has('RAILPACK_SKIP_MIGRATIONS'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('creates missing Laravel defaults as preview variables for preview deployments', function () {
|
||||
[$application, $server] = makeDeploymentControlVarFixture(['build_pack' => 'nixpacks']);
|
||||
|
||||
$keys = ['NIXPACKS_PHP_ROOT_DIR', 'NIXPACKS_PHP_FALLBACK_PATH'];
|
||||
foreach (array_combine($keys, ['/app/web', '/app.php']) as $key => $value) {
|
||||
createApplicationEnvironmentVariable($application, ['key' => $key, 'value' => $value]);
|
||||
}
|
||||
$application->environment_variables_preview()->whereIn('key', $keys)->delete();
|
||||
|
||||
[$job, $reflection] = makeControlVarFilteringJob($application, $server, ['pull_request_id' => 42]);
|
||||
|
||||
[$fallbackPath, $rootDir] = invokeDeploymentJobMethod($job, $reflection, 'laravel_finetunes');
|
||||
|
||||
expect($fallbackPath->is_preview)->toBeTrue()
|
||||
->and($fallbackPath->value)->toBe('/index.php')
|
||||
->and($rootDir->is_preview)->toBeTrue()
|
||||
->and($rootDir->value)->toBe('/app/public')
|
||||
->and($application->environment_variables()->whereIn('key', $keys)->pluck('value', 'key')->all())->toBe([
|
||||
'NIXPACKS_PHP_ROOT_DIR' => '/app/web',
|
||||
'NIXPACKS_PHP_FALLBACK_PATH' => '/app.php',
|
||||
])
|
||||
->and($application->environment_variables_preview()->whereIn('key', $keys)->count())->toBe(2);
|
||||
});
|
||||
|
||||
it('filters buildpack control vars from dockerfile arg injection', function () {
|
||||
[$application, $server] = makeDeploymentControlVarFixture();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user