# PHP/FrankenPHP Server Template
# A minimal production-ready PHP server with FrankenPHP and Caddy
#
# Variables:
#   ${SSH_KEY}              - SSH public key for management access (required)
#   ${MEMORY:-512}          - Memory in MB (default: 512)
#   ${CPUS:-1}              - Number of CPUs (default: 1)
#   ${HOSTNAME:-php-server} - Hostname for the VM
#   ${APP_NAME:-app}        - Application name
#   ${DOMAIN:-localhost}    - Domain for SSL certificates
#   ${PHP_MEMORY:-128M}     - PHP memory limit

kernel:
  image: linuxkit/kernel:6.6.13
  cmdline: "console=tty0 console=ttyS0"

init:
  - linuxkit/init:v1.2.0
  - linuxkit/runc:v1.1.12
  - linuxkit/containerd:v1.7.13
  - linuxkit/ca-certificates:v1.0.0

onboot:
  - name: sysctl
    image: linuxkit/sysctl:v1.0.0
  - name: dhcpcd
    image: linuxkit/dhcpcd:v1.0.0
    command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]

services:
  - name: sshd
    image: linuxkit/sshd:v1.2.0
    binds:
      - /etc/ssh/authorized_keys:/root/.ssh/authorized_keys

  - name: frankenphp
    image: dunglas/frankenphp:latest
    capabilities:
      - CAP_NET_BIND_SERVICE
    net: host
    binds:
      - /app:/app
      - /data:/data
      - /etc/caddy/Caddyfile:/etc/caddy/Caddyfile
    env:
      - SERVER_NAME=${DOMAIN:-localhost}
      - FRANKENPHP_CONFIG=/etc/caddy/Caddyfile
    command:
      - frankenphp
      - run
      - --config
      - /etc/caddy/Caddyfile

  - name: healthcheck
    image: alpine:3.19
    net: host
    command:
      - /bin/sh
      - -c
      - |
        apk add --no-cache curl
        while true; do
          sleep 30
          curl -sf http://localhost/health || echo "Health check failed"
        done

files:
  - path: /etc/hostname
    contents: "${HOSTNAME:-php-server}"
  - path: /etc/ssh/authorized_keys
    contents: "${SSH_KEY}"
    mode: "0600"
  - path: /etc/caddy/Caddyfile
    contents: |
      {
        frankenphp
        order php_server before file_server
      }

      ${DOMAIN:-localhost} {
        root * /app/public

        # Health check endpoint
        handle /health {
          respond "OK" 200
        }

        # PHP handling
        php_server

        # Encode responses
        encode zstd gzip

        # Security headers
        header {
          X-Content-Type-Options nosniff
          X-Frame-Options DENY
          X-XSS-Protection "1; mode=block"
          Referrer-Policy strict-origin-when-cross-origin
        }

        # Logging
        log {
          output file /data/logs/access.log
          format json
        }
      }
    mode: "0644"
  - path: /app/public/index.php
    contents: |
      <?php
      echo "Welcome to ${APP_NAME:-app}";
    mode: "0644"
  - path: /app/public/health.php
    contents: |
      <?php
      header('Content-Type: application/json');
      echo json_encode([
          'status' => 'healthy',
          'app' => '${APP_NAME:-app}',
          'timestamp' => date('c'),
          'php_version' => PHP_VERSION,
      ]);
    mode: "0644"
  - path: /etc/php/php.ini
    contents: |
      memory_limit = ${PHP_MEMORY:-128M}
      max_execution_time = 30
      upload_max_filesize = 64M
      post_max_size = 64M
      display_errors = Off
      log_errors = On
      error_log = /data/logs/php_errors.log
    mode: "0644"
  - path: /data/logs/.gitkeep
    contents: ""

trust:
  org:
    - linuxkit
    - library
    - dunglas
