# Deliver public assets through CDN for Symfony

## Summary
Cdn assets for a Symfony app on Ample. Verified on Symfony: a versioned, immutable-cached asset uploaded to a published bucket and served from the CDN URL. Build and start: composer install --no-dev from composer.lock with Symfony Runtime's dotenv disabled (extra.runtime.disable_dotenv; .env never ships, its values arrive as encrypted env, and compile-time parameters such as DEFAULT_URI need a default), then FrankenPHP serving public/ (php-server with the index.php fallback) reading PORT on the php-8.5 template with APP_ENV=prod.

## Workflow Steps
### Build and start
composer install --no-dev from composer.lock with Symfony Runtime's dotenv disabled (extra.runtime.disable_dotenv; .env never ships, its values arrive as encrypted env, and compile-time parameters such as DEFAULT_URI need a default), then FrankenPHP serving public/ (php-server with the index.php fallback) reading PORT on the php-8.5 template with APP_ENV=prod; the server must bind 0.0.0.0 on PORT.

### Publish a bucket for public assets
Publish only the asset bucket; upload versioned keys with an immutable Cache-Control header and build URLs from its public URL.

Command: `ample bucket publish`

### Verify
Fetch the live URL and /p/versioned-static-assets on the example; on failure read the build and runtime logs.

Command: `ample logs  --kind build`

## Prerequisites
- A Symfony project (composer install --no-dev from composer.lock with Symfony Runtime's dotenv disabled (extra.runtime.disable_dotenv; .env never ships, its values arrive as encrypted env, and compile-time parameters such as DEFAULT_URI need a default), then FrankenPHP serving public/ (php-server with the index.php fallback) reading PORT on the php-8.5 template with APP_ENV=prod)
- A bucket from `ample bucket create` with credentials passed as encrypted S3_* environment variables
- An Ample account token with servers:write, buckets:read

## Limitations
- Verified on the php-8.5 template at s-1vcpu-1gb; other sizes and Symfony major versions are not verified.
- Region, compliance attestations and request-duration limits are unknown and not claimed.
- The CDN serves published-bucket objects only; cache rules, purge and TTL control are not verified.

## Success Checks
1. **App responds on its public URL**
   - Kind: `http_get`
   - Path: `/`
   - Expect: `ample canary symfony patterns`
2. **Versioned-static-assets check from the example**
   - Kind: `http_get`
   - Path: `/p/versioned-static-assets`
   - Expect: `see the pattern fixture checks`

## Cost Estimate
- Currency: USD
- Monthly Amount: 5.0
- Basis: size prices from pricing.toml (loaded by the API) at build revision 1ac5595375130d45290090e82ed0f554ccd45405-dirty
- Components:
  - Name: app server
  - Size: s-1vcpu-1gb
  - Quantity: 1.0
  - Monthly Amount: 5.0
- Note: Always-on monthly price of the tested sizes; apps auto-pause when idle. Buckets are allocation-priced per quota and not included.

## Examples
- Title: **Symfony pattern fixture**
  - Description: Verified CDN assets on Symfony.
  - Source Ref: tests/deploy-canaries/symfony-patterns

## Evidence Summary
- Kind: canary_run
- Summary: Symfony pattern fixture deployed on Ample (composer install --no-dev from composer.lock with Symfony Runtime's dotenv disabled (extra.runtime.disable_dotenv; .env never ships, its values arrive as encrypted env, and compile-time parameters such as DEFAULT_URI need a default), then FrankenPHP serving public/ (php-server with the index.php fallback) reading PORT on the php-8.5 template with APP_ENV=prod); for this guide: a versioned, immutable-cached asset uploaded to a published bucket and served from the CDN URL.
- Observed At: 2026-09-20T22:23:52Z
- Implementation Revision: 64a7bb8e37dd-dirty (CLI 64a7bb8)
- Expires At: 2027-03-19T22:23:52Z
- Scope: Checks: ['/p/versioned-static-assets'], Template: 'php-8.5'
