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>
182 lines
5.5 KiB
Text
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;
|
|
}
|
|
}
|