{
    "slug": "php_deployment_pipeline",
    "term": "PHP Deployment Pipeline",
    "category": "devops",
    "difficulty": "intermediate",
    "short": "A complete CI/CD pipeline for PHP — from push to production — covering lint, test, build, staging deploy, smoke test, and production release.",
    "long": "A mature PHP deployment pipeline: (1) Push triggers CI — composer install --no-dev, phpcs, phpstan analyse, phpunit --coverage-clover, security audit. (2) Docker image built from production Dockerfile — tagged with git SHA. (3) Image pushed to container registry. (4) Staging deploy — image rolled out to staging environment, migrations run, smoke tests executed against staging. (5) Manual or automatic approval gate. (6) Production deploy — rolling or blue/green, zero downtime, post-deploy health check. (7) Automated rollback if health check fails. Tools: GitHub Actions / GitLab CI for orchestration, Deployer or Kubernetes for deployment, Sentry for error monitoring post-release. Keep the pipeline fast — under 10 minutes total is the target. Flaky tests erode trust and must be fixed immediately.",
    "aliases": [
        "PHP CI/CD pipeline",
        "PHP deployment",
        "deploy PHP application"
    ],
    "tags": [
        "devops",
        "php",
        "ci-cd",
        "automation"
    ],
    "misconception": "FTP uploading files to a server is a valid PHP deployment strategy. Manual file uploads introduce inconsistency, cannot be rolled back atomically, skip tests, and leave the server in a mixed state mid-deploy. Atomic deployments via symlink switching ensure the server either runs the old or new version, never a mix.",
    "why_it_matters": "A PHP deployment pipeline automates the path from commit to production — reducing human error, ensuring tests always run, and making deployments a non-event rather than a stressful manual procedure.",
    "common_mistakes": [
        "No zero-downtime deploy — FPM restart during traffic causes dropped requests.",
        "Running composer install on production instead of deploying vendor/ or a built artifact.",
        "Not clearing OPcache after deploy — stale bytecode serves old code.",
        "No smoke test after deploy — a broken deploy serves errors until someone notices."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "continuous_integration",
        "continuous_deployment",
        "zero_downtime_deploy",
        "containerisation"
    ],
    "prerequisites": [
        "continuous_integration",
        "github_actions_php",
        "blue_green_deployment"
    ],
    "refs": [
        "https://deployer.org/",
        "https://docs.github.com/en/actions"
    ],
    "bad_code": "# Naive deploy — causes downtime:\ngit pull origin main\ncomposer install          # Runs on live server\nphp artisan migrate       # Runs on live server\nsystemctl restart php-fpm # Drops in-flight requests\n\n# Better: atomic symlink swap after all prep is done on idle copy",
    "good_code": "# PHP deployment pipeline — .github/workflows/deploy.yml\n\nsteps:\n  # 1. Install dependencies (production only)\n  - run: composer install --no-dev --optimize-autoloader --no-interaction\n\n  # 2. Quality gates (fail fast)\n  - run: composer audit                    # CVE check\n  - run: vendor/bin/phpcs --standard=PSR12 # code style\n  - run: vendor/bin/phpstan analyse        # type errors\n  - run: vendor/bin/phpunit                # tests\n\n  # 3. Build assets\n  - run: npm ci && npm run build\n\n  # 4. Deploy\n  - run: rsync -az --delete public/ deploy@prod:/var/www/app/public/\n\n  # 5. Migrations (backwards-compatible first)\n  - run: ssh deploy@prod 'php /var/www/app/artisan migrate --force'\n\n  # 6. Cache warm + graceful restart\n  - run: ssh deploy@prod 'php /var/www/app/artisan optimize && sudo systemctl reload php8.3-fpm'\n\n  # 7. Health check\n  - run: curl --fail https://yourapp.com/health",
    "quick_fix": "Structure your PHP pipeline: composer install → phpcs → phpstan → test → build docker image → push to registry → deploy to staging → smoke test → deploy to production",
    "severity": "high",
    "effort": "high",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/php_deployment_pipeline",
        "html_url": "https://codeclaritylab.com/glossary/php_deployment_pipeline",
        "json_url": "https://codeclaritylab.com/glossary/php_deployment_pipeline.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[PHP Deployment Pipeline](https://codeclaritylab.com/glossary/php_deployment_pipeline) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/php_deployment_pipeline"
            }
        }
    }
}