fix: preserve Docker build cache by excluding dynamic variables from build-time contexts

- Remove COOLIFY_CONTAINER_NAME from build-time ARGs (timestamp-based, breaks cache)
- Use APP_KEY instead of random_bytes for COOLIFY_BUILD_SECRETS_HASH (deterministic)
- Add forBuildTime parameter to generate_coolify_env_variables() to control injection
- Keep COOLIFY_CONTAINER_NAME available at runtime for container identification
- Fix misleading log message about .env file purpose

Fixes #7040

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai 2025-11-26 09:16:32 +01:00
parent f460bb63cc
commit 4e896cca05

View file

@ -1363,7 +1363,7 @@ private function save_runtime_environment_variables()
$envs_base64 = base64_encode($environment_variables->implode("\n"));
// Write .env file to workdir (for container runtime)
$this->application_deployment_queue->addLogEntry('Creating .env file with runtime variables for build phase.', hidden: true);
$this->application_deployment_queue->addLogEntry('Creating .env file with runtime variables for container.', hidden: true);
$this->execute_remote_command(
[
executeInDocker($this->deployment_uuid, "echo '$envs_base64' | base64 -d | tee $this->workdir/.env > /dev/null"),
@ -1402,7 +1402,7 @@ private function generate_buildtime_environment_variables()
}
$envs = collect([]);
$coolify_envs = $this->generate_coolify_env_variables();
$coolify_envs = $this->generate_coolify_env_variables(forBuildTime: true);
// Add COOLIFY variables
$coolify_envs->each(function ($item, $key) use ($envs) {
@ -1979,7 +1979,6 @@ private function set_coolify_variables()
$this->coolify_variables .= "COOLIFY_BRANCH={$this->application->git_branch} ";
}
$this->coolify_variables .= "COOLIFY_RESOURCE_UUID={$this->application->uuid} ";
$this->coolify_variables .= "COOLIFY_CONTAINER_NAME={$this->container_name} ";
}
private function check_git_if_build_needed()
@ -2230,7 +2229,7 @@ private function generate_nixpacks_env_variables()
}
// Add COOLIFY_* environment variables to Nixpacks build context
$coolify_envs = $this->generate_coolify_env_variables();
$coolify_envs = $this->generate_coolify_env_variables(forBuildTime: true);
$coolify_envs->each(function ($value, $key) {
$this->env_nixpacks_args->push("--env {$key}={$value}");
});
@ -2238,7 +2237,7 @@ private function generate_nixpacks_env_variables()
$this->env_nixpacks_args = $this->env_nixpacks_args->implode(' ');
}
private function generate_coolify_env_variables(): Collection
private function generate_coolify_env_variables(bool $forBuildTime = false): Collection
{
$coolify_envs = collect([]);
$local_branch = $this->branch;
@ -2273,8 +2272,11 @@ private function generate_coolify_env_variables(): Collection
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) {
$coolify_envs->put('COOLIFY_RESOURCE_UUID', $this->application->uuid);
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$coolify_envs->put('COOLIFY_CONTAINER_NAME', $this->container_name);
// Only add COOLIFY_CONTAINER_NAME for runtime (not build-time) - it changes every deployment and breaks Docker cache
if (! $forBuildTime) {
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$coolify_envs->put('COOLIFY_CONTAINER_NAME', $this->container_name);
}
}
}
@ -2311,8 +2313,11 @@ private function generate_coolify_env_variables(): Collection
if ($this->application->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) {
$coolify_envs->put('COOLIFY_RESOURCE_UUID', $this->application->uuid);
}
if ($this->application->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$coolify_envs->put('COOLIFY_CONTAINER_NAME', $this->container_name);
// Only add COOLIFY_CONTAINER_NAME for runtime (not build-time) - it changes every deployment and breaks Docker cache
if (! $forBuildTime) {
if ($this->application->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$coolify_envs->put('COOLIFY_CONTAINER_NAME', $this->container_name);
}
}
}
@ -2328,7 +2333,7 @@ private function generate_env_variables()
$this->env_args = collect([]);
$this->env_args->put('SOURCE_COMMIT', $this->commit);
$coolify_envs = $this->generate_coolify_env_variables();
$coolify_envs = $this->generate_coolify_env_variables(forBuildTime: true);
$coolify_envs->each(function ($value, $key) {
$this->env_args->put($key, $value);
});
@ -2748,7 +2753,7 @@ private function build_image()
} else {
// Traditional build args approach - generate COOLIFY_ variables locally
// Generate COOLIFY_ variables locally for build args
$coolify_envs = $this->generate_coolify_env_variables();
$coolify_envs = $this->generate_coolify_env_variables(forBuildTime: true);
$coolify_envs->each(function ($value, $key) {
$this->build_args->push("--build-arg '{$key}'");
});
@ -3294,7 +3299,9 @@ private function generate_build_secrets(Collection $variables)
private function generate_secrets_hash($variables)
{
if (! $this->secrets_hash_key) {
$this->secrets_hash_key = bin2hex(random_bytes(32));
// Use APP_KEY as deterministic hash key to preserve Docker build cache
// Random keys would change every deployment, breaking cache even when secrets haven't changed
$this->secrets_hash_key = config('app.key');
}
if ($variables instanceof Collection) {