{
    "slug": "docker_multistage",
    "term": "Docker Multi-Stage Builds",
    "category": "devops",
    "difficulty": "intermediate",
    "short": "Dockerfile builds using multiple FROM stages — build dependencies (Composer, Node, test tools) in earlier stages, copy only production artifacts to the final minimal image.",
    "long": "Multi-stage builds eliminate the need for separate Dockerfiles for build and production. The builder stage installs Composer and dev dependencies, runs tests, and compiles assets. The final stage copies only the production files — resulting in an image without Composer, dev packages, Xdebug, or build tools. A typical PHP app goes from a 800MB single-stage image to a 80MB multi-stage image. Smaller images: faster CI pulls, smaller attack surface, and lower registry storage costs.",
    "aliases": [
        "multi-stage build",
        "Docker builder pattern",
        "minimal Docker image"
    ],
    "tags": [
        "devops",
        "docker",
        "php",
        "ci-cd"
    ],
    "misconception": "Multi-stage builds are only for compiled languages — PHP apps benefit just as much: removing Composer, Xdebug, and dev dependencies from production images reduces size by 80% and attack surface significantly.",
    "why_it_matters": "A production PHP image with Xdebug, Composer, and dev dependencies installed is both slower to deploy and has a larger security attack surface — multi-stage builds solve both problems.",
    "common_mistakes": [
        "COPY --from=builder . . — copies everything including dev files; be specific about what to copy.",
        "Not using .dockerignore — the build context includes node_modules, .git, and test files without it.",
        "Running tests in the production stage — tests belong in the builder stage.",
        "Not pinning base image versions — FROM php:latest changes unexpectedly."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "containerisation",
        "container_security",
        "continuous_deployment",
        "php_fpm"
    ],
    "prerequisites": [
        "containerisation",
        "continuous_integration",
        "php_extensions"
    ],
    "refs": [
        "https://docs.docker.com/build/building/multi-stage/"
    ],
    "bad_code": "# Single stage — dev deps in production:\nFROM php:8.3-fpm\nRUN apt-get install -y git zip unzip\nCOPY composer.json composer.lock ./\nRUN curl -sS https://getcomposer.org/installer | php\nRUN php composer.phar install  # Installs dev deps including Xdebug!\nCOPY . .\n# Image: ~800MB with all dev tools",
    "good_code": "# Multi-stage — minimal production image:\nFROM php:8.3-fpm-alpine AS builder\nCOPY --from=composer:2 /usr/bin/composer /usr/bin/composer\nWORKDIR /app\nCOPY composer.json composer.lock ./\nRUN composer install --no-dev --optimize-autoloader\nCOPY . .\nRUN vendor/bin/phpunit  # Tests in build stage\n\n# Production — no Composer, no dev deps:\nFROM php:8.3-fpm-alpine\nWORKDIR /app\nCOPY --from=builder /app/public ./public\nCOPY --from=builder /app/src ./src\nCOPY --from=builder /app/vendor ./vendor\n# Image: ~80MB",
    "quick_fix": "Use a multi-stage Dockerfile: first stage runs composer install, second stage copies only vendor/ and src/ without build tools — keeps production image small and secure",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-16",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/docker_multistage",
        "html_url": "https://codeclaritylab.com/glossary/docker_multistage",
        "json_url": "https://codeclaritylab.com/glossary/docker_multistage.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": "[Docker Multi-Stage Builds](https://codeclaritylab.com/glossary/docker_multistage) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/docker_multistage"
            }
        }
    }
}