{"record":{"id":"09b8d0abf00e1db4","repo":"coollabsio/coolify","slug":"post-deployment-command-could-not-find-a-valid-co","errorCode":null,"errorMessage":"Post-deployment command: Could not find a valid container. Is the container name correct?","messagePattern":"Post-deployment command: Could not find a valid container\\. Is the container name correct\\?","errorType":"exception","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"app/Jobs/ApplicationDeploymentJob.php","lineNumber":4807,"sourceCode":"\n    private function run_post_deployment_command()\n    {\n        if (empty($this->application->post_deployment_command)) {\n            return;\n        }\n        $this->application_deployment_queue->addLogEntry('----------------------------------------');\n        $this->application_deployment_queue->addLogEntry('Executing post-deployment command (see debug log for output).');\n\n        $containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);\n        if ($containers->count() == 0) {\n            $this->application_deployment_queue->addLogEntry('Post-deployment command: No running containers found. Skipping.');\n\n            return;\n        }\n\n        $container = $this->resolveCommandContainer($containers, $this->application->post_deployment_command_container, 'Post-deployment');\n        if ($container === null) {\n            throw new DeploymentException('Post-deployment command: Could not find a valid container. Is the container name correct?');\n        }\n\n        $containerName = data_get($container, 'Names');\n        if ($containerName) {\n            $this->validateContainerName($containerName);\n        }\n        // Security: post_deployment_command is intentionally treated as arbitrary shell input.\n        // See the equivalent comment in run_pre_deployment_command() for the full security rationale.\n        // Newlines are normalized to spaces to prevent injection via SSH heredoc transport.\n        $postCommand = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], ' ', $this->application->post_deployment_command);\n        $cmd = \"sh -c '\".str_replace(\"'\", \"'\\''\", $postCommand).\"'\";\n        $exec = \"docker exec {$containerName} {$cmd}\";\n        try {\n            $this->execute_remote_command(\n                [\n                    'command' => $exec,\n                    'hidden' => true,\n                    'save' => 'post-deployment-command-output',","sourceCodeStart":4789,"sourceCodeEnd":4825,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Jobs/ApplicationDeploymentJob.php#L4789-L4825","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: multi-container app, no target chosen\n$application->post_deployment_command = 'php artisan optimize:clear';\n$application->post_deployment_command_container = null;\n\n// after\n$application->post_deployment_command = 'php artisan optimize:clear';\n$application->post_deployment_command_container = 'app';\n$application->save();","handlingStrategy":"validation","validationCode":"// Before saving a post-deployment command, check it against current containers\n$containers = getCurrentApplicationContainerStatus($server, $application->id, $pullRequestId);\nif ($containers->count() > 1) {\n    $prefix = ($application->post_deployment_command_container ?? '') . '-' . $application->uuid;\n    if (! $containers->pluck('Names')->contains(fn ($n) => str_starts_with($n, $prefix))) {\n        // block save: choose a container name from the running set\n    }\n}","typeGuard":null,"tryCatchPattern":"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; } }","preventionTips":["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."],"tags":["docker","deployment","container-resolution","coolify"],"backgroundTag":"container-not-found","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}