docs/deploy/docker.md
Snider 85bbb8e828 docs: initial import of CorePHP documentation
173 markdown files covering:
- Framework architecture (lifecycle events, module system, multi-tenancy)
- Package docs (admin, api, mcp, tenant, commerce, content, developer)
- CLI reference (dev, build, go, php, deploy commands)
- Patterns (actions, repositories, seeders, services, HLCRF)
- Deployment (Docker, PHP, LinuxKit, templates)
- Publishing (Homebrew, AUR, npm, Docker, Scoop, Chocolatey)

Source: core-php/docs (core.help content)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 17:51:03 +00:00

3.7 KiB

Docker Deployment

Deploy containerised applications with Docker, Docker Compose, and container orchestrators.

Building Images

Build Docker images with core build:

# Auto-detect Dockerfile and build
core build --type docker

# Custom image name
core build --type docker --image ghcr.io/myorg/myapp

# Build and push to registry
core build --type docker --image ghcr.io/myorg/myapp --push

Docker Compose

Basic Setup

docker-compose.yml:

version: '3.8'

services:
  app:
    image: ghcr.io/myorg/myapp:latest
    ports:
      - "8080:8080"
    environment:
      - APP_ENV=production
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
      - redis

  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

secrets:
  db_password:
    file: ./secrets/db_password.txt

Deploy

# Start services
docker compose up -d

# View logs
docker compose logs -f app

# Scale horizontally
docker compose up -d --scale app=3

# Update to new version
docker compose pull && docker compose up -d

Multi-Stage Builds

Optimised Dockerfile for PHP applications:

# Build stage
FROM composer:2 AS deps
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist

# Production stage
FROM dunglas/frankenphp:latest
WORKDIR /app

COPY --from=deps /app/vendor ./vendor
COPY . .

RUN composer dump-autoload --optimize

EXPOSE 8080
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]

Health Checks

Add health checks for orchestrator integration:

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

Or in docker-compose:

services:
  app:
    image: myapp:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 5s

Environment Configuration

Using .env Files

services:
  app:
    image: myapp:latest
    env_file:
      - .env
      - .env.local

Environment Variables

Variable Description
APP_ENV Environment (production, staging)
APP_DEBUG Enable debug mode
DATABASE_URL Database connection string
REDIS_URL Redis connection string
LOG_LEVEL Logging verbosity

Registry Authentication

GitHub Container Registry

# Login
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# Push
docker push ghcr.io/myorg/myapp:latest

AWS ECR

# Login
aws ecr get-login-password --region eu-west-1 | \
  docker login --username AWS --password-stdin 123456789.dkr.ecr.eu-west-1.amazonaws.com

# Push
docker push 123456789.dkr.ecr.eu-west-1.amazonaws.com/myapp:latest

Orchestration

Docker Swarm

# Initialise swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.yml myapp

# Scale service
docker service scale myapp_app=5

# Rolling update
docker service update --image myapp:v2 myapp_app

Kubernetes

Generate Kubernetes manifests from Compose:

# Using kompose
kompose convert -f docker-compose.yml

# Apply to cluster
kubectl apply -f .

See Also