coollabsio/coolify · error · DeploymentException
Post-deployment command: Could not find a valid container. I
Error message
Post-deployment command: Could not find a valid container. Is the container name correct?
What it means
Same container-resolution logic as the pre-deployment variant, but thrown by run_post_deployment_command() after the new release is up. Because the check runs against freshly started containers, a post-deployment command fails when the app runs multiple containers and post_deployment_command_container is missing or no longer prefix-matches '{name}-{application-uuid}' of the running set.
Source
Thrown at app/Jobs/ApplicationDeploymentJob.php:4807
private function run_post_deployment_command()
{
if (empty($this->application->post_deployment_command)) {
return;
}
$this->application_deployment_queue->addLogEntry('----------------------------------------');
$this->application_deployment_queue->addLogEntry('Executing post-deployment command (see debug log for output).');
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
if ($containers->count() == 0) {
$this->application_deployment_queue->addLogEntry('Post-deployment command: No running containers found. Skipping.');
return;
}
$container = $this->resolveCommandContainer($containers, $this->application->post_deployment_command_container, 'Post-deployment');
if ($container === null) {
throw new DeploymentException('Post-deployment command: Could not find a valid container. Is the container name correct?');
}
$containerName = data_get($container, 'Names');
if ($containerName) {
$this->validateContainerName($containerName);
}
// Security: post_deployment_command is intentionally treated as arbitrary shell input.
// See the equivalent comment in run_pre_deployment_command() for the full security rationale.
// Newlines are normalized to spaces to prevent injection via SSH heredoc transport.
$postCommand = str_replace(["\r\n", "\r", "\n"], ' ', $this->application->post_deployment_command);
$cmd = "sh -c '".str_replace("'", "'\''", $postCommand)."'";
$exec = "docker exec {$containerName} {$cmd}";
try {
$this->execute_remote_command(
[
'command' => $exec,
'hidden' => true,
'save' => 'post-deployment-command-output',View on GitHub (pinned to 70b9acc424)
Solutions
- Set 'Post-deployment command container' in the application's deployment command settings to the bare service name (e.g. 'app'), not the full container name.
- Check the debug log 'Available: ...' line to see which running containers the command could target and pick one.
- Confirm the container survives the rollout — if the service is renamed in the new compose, update the field to the new name.
- docker ps on the destination server to confirm the container is actually running for this application.
Example fix
// before: multi-container app, no target chosen $application->post_deployment_command = 'php artisan optimize:clear'; $application->post_deployment_command_container = null; // after $application->post_deployment_command = 'php artisan optimize:clear'; $application->post_deployment_command_container = 'app'; $application->save();
Defensive patterns
Strategy: validation
Validate before calling
// Before saving a post-deployment command, check it against current containers
$containers = getCurrentApplicationContainerStatus($server, $application->id, $pullRequestId);
if ($containers->count() > 1) {
$prefix = ($application->post_deployment_command_container ?? '') . '-' . $application->uuid;
if (! $containers->pluck('Names')->contains(fn ($n) => str_starts_with($n, $prefix))) {
// block save: choose a container name from the running set
}
} Try / catch
catch (DeploymentException $e) { if (str_starts_with($e->getMessage(), 'Post-deployment command:')) { mark deployment as config error, show 'Available:' list from logs, no auto-retry; } else { throw $e; } } Prevention
- Pin post_deployment_command_container to a service name that survives rollouts and renames.
- When renaming compose services, sweep application settings (pre/post command container, scheduled tasks) for the old name.
- Confirm containers are running post-rollout before relying on post-deployment commands.
When it happens
Trigger: Multi-container app (scaled replicas, multiple compose services) with post_deployment_command_container empty; the configured container name matches a compose service that was renamed or removed in the new release; the target container crashed immediately after starting, so it is absent from getCurrentApplicationContainerStatus.
Common situations: Renaming compose services in the same commit that the post-deployment command was expected to run in; scaling to 2+ replicas after the command was configured; container name entered with the full '-uuid' suffix; PR deploy where the PR-suffixed container is expected but missing.
Related errors
- Pre-deployment command: Could not find a valid container. Is
- ScheduledTaskJob failed: No valid container was found. Is th
- 69420
- Command execution failed (exit code {$process_result->exitCo
- Invalid dockerfile_target_build: contains forbidden characte
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/09b8d0abf00e1db4.
Report an issue: GitHub.