Deployment
Docker
The application is containerized with a single Dockerfile that bundles Nginx and PHP-FPM together.
Image Build
FROM 056644654815.dkr.ecr.us-east-2.amazonaws.com/php:8.2.6-fpm
# Install PHP extensions, Nginx, SimpleSAMLphp
# Copy application code, Nginx config, SAML certs
# Run composer install
# Entrypoint: deploy/run
EXPOSE 80Key extensions: mysqli, pdo_mysql, pdo_pgsql, bcmath, gd, zip, opcache, exif, xdebug.
Container Entrypoint
deploy/run:
#!/bin/sh
set -e
service nginx restart
php-fpmStarts Nginx, then PHP-FPM in the foreground.
AWS Copilot
The API is deployed as an AWS App Runner service (Request-Driven Web Service) managed by AWS Copilot.
Service Definition
copilot/api/manifest.yml:
name: api
type: Request-Driven Web Service
image:
location: "056644654815.dkr.ecr.us-east-2.amazonaws.com/housr-api/api:insert"
port: 80
cpu: 1024
memory: 2048Production environments (UK prod, US us-prod) have higher resources:
cpu: 2048
memory: 4096Environments
| Copilot Env | Region | Purpose | VPC |
|---|---|---|---|
dev | UK Dev | Development | Public |
demo | US Demo | Demo app (USA=true) | Public |
uat | UK Staging | UK staging | Private |
prod | UK Production | UK production | Private |
us-dev | US Dev | US development | Public |
us-uat | US Staging | US staging | Public |
us-prod | US Production | US production | Public |
UK UAT and Prod environments use private VPC placement, connecting to Aurora MySQL clusters in eu-west-2.
Secrets Management
Secrets are stored in AWS Secrets Manager and referenced in the Copilot manifest:
secrets:
DB_PASSWORD: "'arn:aws:secretsmanager:...'"
FIREBASE_CREDENTIALS: "'arn:aws:secretsmanager:...'"
HUBSPOT_API_KEY: "'arn:aws:secretsmanager:...'"Production and staging environments override specific secrets (e.g., production Finix credentials vs sandbox).
Pipelines
Copilot pipelines are defined in copilot/pipelines/:
housr-api-main- Main deployment pipelinefeature- Feature branch deployments
Nginx Configuration
Main Config (deploy/nginx.conf)
Performance-tuned Nginx configuration:
- Worker processes: auto (based on CPU cores)
- Worker connections: 4000
- Gzip compression enabled
- Keep-alive timeout: 30s
- FastCGI read timeout: 240s
Includes app store redirect maps for deep linking:
map $host $android_redirect_url {
~api\.us\.housr\.com$ "https://play.google.com/store/apps/details?id=com.housr.myhousr";
default "https://play.google.com/store/apps/details?id=com.housr.houser";
}Server Config (deploy/deploy.conf)
Key routing rules:
# Auto-prepend bootstrap.php for all PHP requests
location ~ \.php$ {
fastcgi_param PHP_VALUE "auto_prepend_file=/var/www/api/include/bootstrap.php";
fastcgi_pass localhost:9000;
}
# SimpleSAMLphp for SSO
location ^~ /simplesaml { ... }
# Health check
location /health {
return 200 '{"code":"1", "message": "Hey im Healthy thanks to you!"}';
}
# External API routing (strip .php extension)
location /api/external/ {
rewrite ^/api/external/(.*)$ /api/external/$1.php last;
}
# Entrata webhook routing
location /api/external/entrata/ {
try_files $uri $uri/ /api/external/entrata/index.php$is_args$args;
}
# Deep link redirects to app stores
location /app/ {
try_files $uri @fallback;
}PHP-FPM Config
deploy/www.conf configures the PHP-FPM worker pool.
OPcache
deploy/opcache.ini configures PHP OPcache for production performance. Timestamp validation is disabled in production (files are immutable in the container) but enabled in development via the PHP_OPCACHE_VALIDATE_TIMESTAMPS environment variable.
Domains
| Environment | Domain |
|---|---|
| UK Dev | dev.api.housrportal.co.uk |
| UK UAT | staging.api.uk.housr.com |
| UK Prod | api.uk.housr.com |
| US Demo | demo.api.uk.housr.com |
| US Dev | (App Runner default URL) |
| US UAT | (App Runner default URL) |
| US Prod | api.us.housr.com |