{
    "slug": "containerisation",
    "term": "Containerisation (Docker for PHP)",
    "category": "devops",
    "difficulty": "intermediate",
    "short": "Packaging PHP applications and their dependencies into Docker containers for consistent, reproducible environments from dev to production.",
    "long": "Docker containers bundle PHP, extensions, nginx/FPM configuration, and application code into an immutable image. Benefits: environment parity (eliminates 'works on my machine'), fast deployment, horizontal scaling, and isolation. A PHP production Dockerfile typically: starts from php:8.3-fpm-alpine, installs required extensions with docker-php-ext-install, copies Composer dependencies, and sets non-root user. Multi-stage builds separate build dependencies from runtime — keeping production images lean. Docker Compose orchestrates local development with PHP-FPM, nginx, MySQL, and Redis containers. For production, containers run on Kubernetes, ECS, or similar orchestrators.",
    "aliases": [
        "Docker",
        "containers",
        "container runtime"
    ],
    "tags": [
        "devops",
        "infrastructure",
        "deployment",
        "php"
    ],
    "misconception": "Containers provide the same isolation as virtual machines. Containers share the host OS kernel — a kernel exploit can break container isolation. VMs virtualise hardware and have separate kernels. Containers offer process isolation; VMs offer stronger security boundaries at higher resource cost.",
    "why_it_matters": "Containers guarantee that software runs identically on every machine — development, staging, and production all use the same environment. \"It works on my machine\" becomes \"it works in the container\" which runs everywhere.",
    "common_mistakes": [
        "Running containers as root inside the container — any container escape gives the attacker root on the host.",
        "Storing persistent data inside the container — it disappears when the container restarts.",
        "Using latest as the image tag in production — you lose control of which version is deployed.",
        "Baking secrets into the image — they are visible to anyone who can pull the image."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "infrastructure_as_code",
        "twelve_factor_app",
        "php_fpm",
        "continuous_deployment"
    ],
    "prerequisites": [
        "docker_multistage",
        "infrastructure_as_code",
        "cloud_native_patterns"
    ],
    "refs": [
        "https://docs.docker.com/language/php/",
        "https://hub.docker.com/_/php"
    ],
    "bad_code": "// Dockerfile anti-patterns:\nFROM ubuntu:latest          # Unpinned — breaks on new release\nRUN apt-get install -y php  # No version pin\nCOPY . /app                 # Copies .git, node_modules, .env\nRUN composer install        # Dev dependencies included\nUSER root                   # Running as root — security risk\n\n// Better:\nFROM php:8.3-fpm-alpine\nCOPY --chown=www-data:www-data . /app\nRUN composer install --no-dev --optimize-autoloader\nUSER www-data",
    "good_code": "# Dockerfile — production PHP-FPM image\nFROM php:8.3-fpm-alpine AS base\nRUN docker-php-ext-install pdo_mysql opcache\nCOPY php.ini /usr/local/etc/php/conf.d/app.ini\n\nFROM base AS vendor\nCOPY composer.json composer.lock ./\nRUN composer install --no-dev --no-scripts --prefer-dist\n\nFROM base AS production\nCOPY --from=vendor /app/vendor ./vendor\nCOPY . .\nRUN php artisan config:cache && php artisan route:cache\nUSER www-data",
    "quick_fix": "Write a Dockerfile with a multi-stage build: first stage installs Composer deps, second stage copies only the app and vendor/ — keeps the final image small and without build tools",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/containerisation",
        "html_url": "https://codeclaritylab.com/glossary/containerisation",
        "json_url": "https://codeclaritylab.com/glossary/containerisation.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": "[Containerisation (Docker for PHP)](https://codeclaritylab.com/glossary/containerisation) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/containerisation"
            }
        }
    }
}