mirror of
https://github.com/tiennm99/coolify.git
synced 2026-09-04 18:19:55 +00:00
fix(railpack): fail fast when buildx is unavailable
Require Docker buildx before Railpack builds, normalize environment variable keys before validation, and align private deploy key API docs with the supported dockerfile build pack.
This commit is contained in:
@@ -650,7 +650,7 @@ class ApplicationsController extends Controller
|
||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||
'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'],
|
||||
'build_pack' => ['type' => 'string', 'enum' => ['nixpacks', 'railpack', 'static', 'dockerfile', 'dockercompose'], 'description' => 'The build pack type.'],
|
||||
'build_pack' => ['type' => 'string', 'enum' => ['dockerfile'], 'description' => 'The build pack type.'],
|
||||
'ports_exposes' => ['type' => 'string', 'description' => 'The ports to expose.'],
|
||||
'destination_uuid' => ['type' => 'string', 'description' => 'The destination UUID.'],
|
||||
'name' => ['type' => 'string', 'description' => 'The application name.'],
|
||||
|
||||
@@ -181,6 +181,8 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
|
||||
private bool $dockerBuildkitSupported = false;
|
||||
|
||||
private bool $dockerBuildxAvailable = false;
|
||||
|
||||
private bool $dockerSecretsSupported = false;
|
||||
|
||||
private bool $skip_build = false;
|
||||
@@ -421,6 +423,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
|
||||
if ($majorVersion < 18 || ($majorVersion == 18 && $minorVersion < 9)) {
|
||||
$this->dockerBuildkitSupported = false;
|
||||
$this->dockerBuildxAvailable = false;
|
||||
$this->application_deployment_queue->addLogEntry("Docker {$dockerVersion} on {$serverName} does not support BuildKit (requires 18.09+).");
|
||||
|
||||
return;
|
||||
@@ -434,8 +437,11 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
|
||||
if (trim($buildxAvailable) === 'available') {
|
||||
$this->dockerBuildkitSupported = true;
|
||||
$this->dockerBuildxAvailable = true;
|
||||
$this->application_deployment_queue->addLogEntry("Docker {$dockerVersion} with BuildKit and Buildx detected on {$serverName}.");
|
||||
} else {
|
||||
$this->dockerBuildxAvailable = false;
|
||||
|
||||
// Fallback: test DOCKER_BUILDKIT=1 support via --progress flag
|
||||
$buildkitTest = instant_remote_process(
|
||||
["DOCKER_BUILDKIT=1 docker build --help 2>&1 | grep -q '\\-\\-progress' && echo 'supported' || echo 'not-supported'"],
|
||||
@@ -468,6 +474,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->dockerBuildkitSupported = false;
|
||||
$this->dockerBuildxAvailable = false;
|
||||
$this->dockerSecretsSupported = false;
|
||||
$this->application_deployment_queue->addLogEntry("Could not detect BuildKit capabilities on {$serverName}: {$e->getMessage()}");
|
||||
}
|
||||
@@ -2760,8 +2767,19 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
return $prepare_command;
|
||||
}
|
||||
|
||||
private function ensure_docker_buildx_available_for_railpack(): void
|
||||
{
|
||||
if ($this->dockerBuildxAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new DeploymentException('Railpack deployments require the Docker buildx CLI plugin on the build server. Install or enable docker buildx and retry the deployment.');
|
||||
}
|
||||
|
||||
private function build_railpack_image(): void
|
||||
{
|
||||
$this->ensure_docker_buildx_available_for_railpack();
|
||||
|
||||
$railpackVariables = $this->generate_railpack_env_variables();
|
||||
$railpackConfigPath = $this->generate_railpack_config_file();
|
||||
|
||||
|
||||
@@ -371,7 +371,9 @@ class EnvironmentVariable extends BaseModel
|
||||
protected function key(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
set: fn (string $value) => ValidationPatterns::validatedEnvironmentVariableKey($value),
|
||||
set: fn (string $value) => ValidationPatterns::validatedEnvironmentVariableKey(
|
||||
ValidationPatterns::normalizeEnvironmentVariableKey($value)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -1451,11 +1451,7 @@
|
||||
"build_pack": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"nixpacks",
|
||||
"railpack",
|
||||
"static",
|
||||
"dockerfile",
|
||||
"dockercompose"
|
||||
"dockerfile"
|
||||
],
|
||||
"description": "The build pack type."
|
||||
},
|
||||
|
||||
+1
-1
@@ -935,7 +935,7 @@ paths:
|
||||
description: 'The Dockerfile content.'
|
||||
build_pack:
|
||||
type: string
|
||||
enum: [nixpacks, railpack, static, dockerfile, dockercompose]
|
||||
enum: [dockerfile]
|
||||
description: 'The build pack type.'
|
||||
ports_exposes:
|
||||
type: string
|
||||
|
||||
@@ -205,6 +205,17 @@ it('builds railpack prepare command using railpack env for install and cli flags
|
||||
expect($command)->not->toContain('RAILPACK_START_CMD=');
|
||||
});
|
||||
|
||||
it('fails fast when docker buildx is unavailable for railpack builds', function () {
|
||||
[$job, $reflection] = makeRailpackDeploymentJob();
|
||||
|
||||
$dockerBuildxAvailableProperty = $reflection->getProperty('dockerBuildxAvailable');
|
||||
$dockerBuildxAvailableProperty->setAccessible(true);
|
||||
$dockerBuildxAvailableProperty->setValue($job, false);
|
||||
|
||||
expect(fn () => invokeRailpackMethod($job, $reflection, 'ensure_docker_buildx_available_for_railpack'))
|
||||
->toThrow(DeploymentException::class, 'Railpack deployments require the Docker buildx CLI plugin');
|
||||
});
|
||||
|
||||
it('builds railpack docker command with matching env and secret flags for all railpack variables', function () {
|
||||
[$job, $reflection] = makeRailpackDeploymentJob([
|
||||
'uuid' => 'application-uuid',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Models\EnvironmentVariable;
|
||||
use App\Support\ValidationPatterns;
|
||||
|
||||
it('accepts valid names with common characters', function (string $name) {
|
||||
@@ -165,3 +166,10 @@ it('generates environment variable key rules with correct defaults', function ()
|
||||
it('normalizes environment variable keys by trimming surrounding whitespace', function () {
|
||||
expect(ValidationPatterns::normalizeEnvironmentVariableKey(' node.name '))->toBe('node.name');
|
||||
});
|
||||
|
||||
it('normalizes environment variable keys before model validation', function () {
|
||||
$environmentVariable = new EnvironmentVariable;
|
||||
$environmentVariable->key = ' APP_ENV ';
|
||||
|
||||
expect($environmentVariable->key)->toBe('APP_ENV');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user