Files
amare/openspec/specs/container-runtime/spec.md

3.9 KiB

container-runtime Specification

Purpose

Define the production container image for the application: a reproducible multi-stage FrankenPHP build serving the public directory, run in regular mode as a non-root user, shared by web/queue/scheduler processes, with no secrets in layers and a healthcheck on /up.

Requirements

Requirement: Production image uses multi-stage FrankenPHP build

The system SHALL provide a multi-stage Dockerfile that builds Composer dependencies, frontend assets, and a FrankenPHP runtime image serving public/.

Scenario: Image builds reproducibly in CI

  • WHEN the container CI job builds the Docker image from a clean checkout
  • THEN the build completes successfully and produces a runnable image

Requirement: FrankenPHP runs in regular mode only

The system MUST NOT enable FrankenPHP worker mode in the MVP. The runtime SHALL use FrankenPHP in regular mode (ADR-006).

Scenario: Runtime configuration is regular mode

  • WHEN the production image starts the web process
  • THEN FrankenPHP serves requests in regular mode without worker persistence

Requirement: Runtime image runs as non-root when supported

The system SHALL configure the production runtime to run as a non-root user when the base image supports it.

Scenario: Container process is non-root

  • WHEN the web container is running in production configuration
  • THEN the primary process MUST NOT run as root

Requirement: Same image supports web queue and scheduler processes

The system SHALL use the same application image for web, queue worker, and scheduler processes with distinct commands (SPEC §15.2).

Scenario: Queue worker starts from application image

  • WHEN the queue process is started with php artisan queue:work
  • THEN it uses the same built image as the web process

Requirement: Production image contains no secrets in layers

The system MUST NOT embed secrets, credentials, or private keys in Docker image layers.

Scenario: Image inspection finds no embedded secrets

  • WHEN the image is built in CI
  • THEN build arguments and layers MUST NOT contain production secrets or .env values

Requirement: Container healthcheck validates application availability

The system SHALL define a container healthcheck that verifies application availability via the /up endpoint or equivalent boot check.

Scenario: Unhealthy container is detected

  • WHEN the application inside the container fails to respond healthy on /up
  • THEN the container healthcheck MUST report unhealthy status

Requirement: Local Compose runs FrankenPHP application alongside PostgreSQL

The local Docker Compose stack SHALL include a FrankenPHP application service built from the project Dockerfile, dependent on a healthy PostgreSQL service, exposing the application on port 8000 (or documented equivalent). FrankenPHP MUST run in regular mode (ADR-006).

Scenario: Developer starts full local stack

  • WHEN a developer runs docker compose up -d with the application service enabled
  • THEN PostgreSQL and the FrankenPHP app containers MUST become healthy
  • AND GET /up on the app port MUST return HTTP 200

Scenario: App waits for database readiness

  • WHEN the application service starts
  • THEN it MUST depend on the PostgreSQL healthcheck succeeding before becoming ready

Requirement: Runtime PHP version is canonically 8.4

Docker, CI, and project documentation MUST treat PHP 8.4 as the canonical runtime for this MVP. Statements that require PHP 8.5+ MUST NOT remain in project docs while the runtime image uses 8.4.

Scenario: Dockerfile pins PHP 8.4

  • WHEN the production/runtime image is built
  • THEN the FrankenPHP base image MUST use PHP 8.4

Scenario: Documentation matches the runtime

  • WHEN a contributor reads the README requirements
  • THEN the documented PHP version MUST be 8.4 (compatible with Composer ^8.3)