images/server-php/config/conf.d/unified.conf
Snider 7c7edae110 fix: add missing server-php configs, fix developer git-delta
server-php:
- Add nginx.conf, fpm-pool.conf.template, supervisord.conf
- Add php.ini.template, php-prod.ini, php-dev.ini
- Add opcache-prod.ini, xdebug.ini
- Add nginx-performance.conf for production
- Add entrypoint.sh script

developer:
- Remove git-delta (not available in Alpine 3.22 repos)

Closes #3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:51:48 +00:00

182 lines
5.5 KiB
Text

# Unified nginx configuration
# Routes traffic based on domain:
# - host.uk.com → Laravel Host Hub (PHP-FPM)
# - *.host.uk.com → WordPress (PHP-FPM)
# Map for allowed CORS origins (WordPress REST API)
map $http_origin $cors_origin {
default "";
"~^https?://host\.uk\.com$" $http_origin;
"~^https?://social\.host\.uk\.com$" $http_origin;
"~^https?://link\.host\.uk\.com$" $http_origin;
"~^https?://analytics\.host\.uk\.com$" $http_origin;
"~^https?://trust\.host\.uk\.com$" $http_origin;
"~^https?://notify\.host\.uk\.com$" $http_origin;
"~^https?://localhost(:[0-9]+)?$" $http_origin;
"~^https?://127\.0\.0\.1(:[0-9]+)?$" $http_origin;
}
# ============================================
# LARAVEL HOST HUB - Apex Domain
# ============================================
server {
listen 80;
listen [::]:80;
server_name host.uk.com www.host.uk.com;
root /app/public;
index index.php;
client_max_body_size 64M;
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
# Health check - returns 200 if nginx is up (no PHP needed)
location = /healthz {
access_log off;
add_header Content-Type text/plain;
return 200 "ok\n";
}
# WordPress REST API proxy
# host.uk.com/api/wordpress/* → WordPress /wp-json/*
# Same-origin, no CORS needed
location ~ ^/api/wordpress/(.*)$ {
# Pass to WordPress index.php with rest_route
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www/html/index.php;
fastcgi_param REQUEST_URI /wp-json/$1$is_args$args;
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
fastcgi_index index.php;
fastcgi_buffering off;
fastcgi_read_timeout 300;
include fastcgi_params;
}
# Laravel routing
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM for Laravel
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
fastcgi_index index.php;
fastcgi_buffering off;
fastcgi_read_timeout 300;
include fastcgi_params;
}
# Livewire and Flux - must go to Laravel (not static files)
location ~ ^/(admin|flux)/ {
try_files $uri $uri/ /index.php?$query_string;
}
# Laravel static assets (build, vendor directories only)
location ~* ^/(build|vendor)/.*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
add_header Cache-Control "public, immutable";
log_not_found off;
access_log off;
}
# Deny hidden files
location ~ /\. {
deny all;
}
# PHP-FPM status (internal only)
location ~ ^/(fpm-status|fpm-ping)$ {
access_log off;
allow 127.0.0.1;
deny all;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm.sock;
}
}
# ============================================
# LARAVEL SATELLITES - Subdomains
# ============================================
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name *.host.uk.com;
root /app/public;
index index.php;
client_max_body_size 64M;
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
# Health check
location = /healthz {
access_log off;
add_header Content-Type text/plain;
return 200 "ok\n";
}
# WordPress REST API (for internal content sync)
# Routes /wp-json/* requests to WordPress
# Host header determines which multisite blog to serve
location ~ ^/wp-json/(.*)$ {
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www/html/index.php;
fastcgi_param REQUEST_URI /wp-json/$1$is_args$args;
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
fastcgi_index index.php;
fastcgi_buffering off;
fastcgi_read_timeout 300;
include fastcgi_params;
}
# Laravel routing
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM for Laravel
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
fastcgi_index index.php;
fastcgi_buffering off;
fastcgi_read_timeout 300;
include fastcgi_params;
}
# Livewire and Flux
location ~ ^/(admin|flux)/ {
try_files $uri $uri/ /index.php?$query_string;
}
# Static assets
location ~* ^/(build|vendor)/.*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
add_header Cache-Control "public, immutable";
log_not_found off;
access_log off;
}
# Deny hidden files
location ~ /\. {
deny all;
}
}