PHP API End-to-End Example

What this page gives you

This deep dive shows a compact two-tier service and is a good first example for understanding dependency and shared-volume modeling.

Shipped example location on NetBSD:

  • /usr/share/examples/cellmgr/php-api

Topology and dependency graph

The stack has two cells and one volume:

  • php-api-app-phpfpm (PHP-FPM backend on 9000)
  • php-api-edge-nginx (public edge on 80)
  • php-api-webroot (shared app files)

Dependency graph:

php-api-app-phpfpm -> php-api-edge-nginx

Operational meaning:

  • backend runtime is converged first
  • edge proxy converges second and forwards traffic to backend

Manifest deep dive

php-api-app-phpfpm.cell

Key fields:

  • CELL_CREATE_RESERVED_PORTS="9000"
  • CELL_SUPERVISE_CMD="...php-fpm83 ... /usr/pkg/etc/php-fpm-cellmgr.conf"
  • CELL_DEPENDS_ON="" (backend is first layer)
  • CELL_VOLUME_MOUNTS="php-api-webroot:/var/www/php-api:rw"

Why this matters:

  • app layer owns write access to webroot content
  • runtime service command is explicit and supervised

php-api-edge-nginx.cell

Key fields:

  • CELL_CREATE_RESERVED_PORTS="80"
  • CELL_DEPENDS_ON="php-api-app-phpfpm"
  • CELL_VOLUME_MOUNTS="php-api-webroot:/var/www/php-api:ro"

The same volume is mounted read-only in edge. This models least privilege and prevents accidental content mutation from the proxy tier.

php-api-webroot.volume

Defines persistent/shared webroot storage used by both tiers.

Apply plans

  • php-api-app-phpfpm.apply
    • installs php83 and php83-fpm
    • writes minimal JSON API endpoint at /var/www/php-api/index.php
    • writes /usr/pkg/etc/php-fpm-cellmgr.conf
  • php-api-edge-nginx.apply
    • installs nginx
    • writes nginx config routing /api/ to PHP-FPM on localhost:9000

End-to-end deployment steps

Run commands as root (or prefix with doas).

  1. bootstrap host once (skip if already done)
cellmgr system bootstrap
  1. copy shipped example manifests
cp /usr/share/examples/cellmgr/php-api/* /etc/cellmgr/
  1. inspect desired state
cellmgr cell show php-api-app-phpfpm --view desired
cellmgr cell show php-api-edge-nginx --view desired
cellmgr volume list --view desired
  1. run targeted dry-run
cellmgr apply --dry-run php-api-app-phpfpm php-api-edge-nginx
  1. apply stack
cellmgr apply php-api-app-phpfpm php-api-edge-nginx
  1. verify runtime
cellmgr cell list --view merged
cellmgr volume list --view merged
cellctl list -T
cellctl stats -T
  1. validate endpoint behavior
  • open http://<host-ip>/api/
  • expected response: JSON payload with service=php-api-app-phpfpm and status=ok

Modeling takeaways

  • CELL_DEPENDS_ON models startup order explicitly
  • one shared volume with rw/ro mount mode split models write authority cleanly
  • apply plans keep package/config provisioning idempotent and reviewable