Wire admin studio SSR and search infrastructure

This commit is contained in:
2026-05-01 11:46:06 +02:00
parent 257b0dbef6
commit 18cea8b0f0
329 changed files with 197465 additions and 2741 deletions

View File

@@ -0,0 +1,36 @@
# -----------------------------------------------------------------------
# nginx X-Accel-Redirect for artwork original file downloads
#
# Problem: PHP streams the file body through FPM → nginx, causing
# "[warn] upstream response is buffered to a temporary file"
# for large downloads because FastCGI buffers are too small.
#
# Solution: PHP sets X-Accel-Redirect, nginx serves the file body
# directly from disk — FPM is only used for the header response.
#
# Setup:
# 1. Set DOWNLOAD_ACCEL_PATH=/internal/originals in .env (production).
# 2. Include this file inside your server {} block:
# include /etc/nginx/conf.d/download-accel.conf;
# 3. Make sure the nginx worker has read access to the originals path.
#
# The /internal/originals prefix MUST match DOWNLOAD_ACCEL_PATH in .env.
# The alias path MUST match ARTWORKS_LOCAL_ORIGINALS_ROOT on the server.
# -----------------------------------------------------------------------
location /internal/originals/ {
# Block direct client access — only X-Accel-Redirect headers trigger this.
internal;
# Replace this with the actual absolute path to artwork originals on disk.
# Typically: /var/www/skinbase/storage/originals or /var/www/skinbase/public/files/originals
alias /var/www/skinbase/public/files/originals/;
# Let nginx send the file efficiently with sendfile + tcp_nopush.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# No nginx-level caching for download responses (private files).
add_header Cache-Control "private, no-store";
}

View File

@@ -0,0 +1,38 @@
# ---------------------------------------------------------------------------
# Nginx static sitemap file serving
# ---------------------------------------------------------------------------
# Include this snippet inside your `server {}` block BEFORE the main
# `location /` (or `location ~ \.php$`) block so nginx serves the pre-built
# static XML files without ever touching PHP/FPM.
#
# The GenerateSitemapsCommand writes these files on a schedule (every 6 h):
# public/sitemap.xml <- root sitemap index
# public/sitemaps/{name}.xml <- per-family / per-shard documents
#
# When a file has not been generated yet (first deploy, cold start) the
# request falls through to @php and Laravel's SitemapController builds it
# live on the first hit.
# ---------------------------------------------------------------------------
# Root sitemap index
location = /sitemap.xml {
# Serve the static file if it exists; otherwise fall through to PHP.
try_files $uri @php;
# Instruct downstream caches / crawlers how long the file is fresh.
add_header Cache-Control "public, max-age=21600" always; # 6 h
add_header Content-Type "application/xml; charset=UTF-8" always;
# Optional: let nginx set a strong ETag automatically (default behaviour).
etag on;
}
# Per-family / per-shard sitemap documents
location ~ ^/sitemaps/[A-Za-z0-9_\-]++\.xml$ {
try_files $uri @php;
add_header Cache-Control "public, max-age=21600" always; # 6 h
add_header Content-Type "application/xml; charset=UTF-8" always;
etag on;
}

View File

@@ -0,0 +1,40 @@
# -----------------------------------------------------------------------
# Long-term caching for static assets
#
# Include this file inside the relevant server {} block, e.g.:
#
# server {
# ...
# include /etc/nginx/conf.d/static-cache.conf;
# }
#
# Also apply equivalent rules on the cdn.skinbase.org server/bucket so
# that artwork thumbnails and avatars are cached for at least 1 year.
# For Contabo object storage, set the Cache-Control metadata on each
# object: Cache-Control: public, max-age=31536000, immutable
# -----------------------------------------------------------------------
# Vite build output — always content-hashed, safe to cache for 1 year.
location ~* ^/build/assets/.+\.(js|css|woff2?|ttf|otf|eot|svg|png|jpg|jpeg|webp|avif|ico|gif)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Vary "Accept-Encoding";
access_log off;
try_files $uri =404;
}
# CDN user-content (artworks, avatars) — content-addressed by hash.
# Apply this block on the cdn.skinbase.org nginx server.
location ~* ^/(artworks|avatars|worlds/media)/.+\.(webp|avif|jpg|jpeg|png|gif|svg)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Vary "Accept-Encoding";
access_log off;
try_files $uri =404;
}
# Public static images (logos, defaults) — not content-addressed, 7-day TTL.
location ~* ^/images/.+\.(webp|avif|jpg|jpeg|png|gif|svg|ico)$ {
add_header Cache-Control "public, max-age=604800, stale-while-revalidate=86400";
add_header Vary "Accept-Encoding";
access_log off;
try_files $uri =404;
}

View File

@@ -0,0 +1,30 @@
# ---------------------------------------------------------------------------
# Nginx upstream / gateway error pages for Skinbase Nova
# ---------------------------------------------------------------------------
# Purpose:
# Serve a Nova-styled static HTML page for nginx-level upstream failures such
# as 502 Bad Gateway and 504 Gateway Timeout. These responses happen before
# Laravel can render Blade error views, so they must be handled by nginx.
#
# Setup:
# 1. Include this file inside the `server {}` block for the Skinbase site.
# 2. Enable `fastcgi_intercept_errors on;` inside every FastCGI location that
# should use these pages (at minimum `location = /index.php` and any other
# direct `fastcgi_pass` location such as upload endpoints).
# 3. Ensure the static file exists at:
# public/errors/upstream-gateway.html
#
# This snippet intentionally intercepts only upstream failures. Keep Laravel in
# control of normal application errors such as 404, 419, 429, and 500.
# ---------------------------------------------------------------------------
error_page 502 504 /errors/upstream-gateway.html;
location = /errors/upstream-gateway.html {
internal;
try_files /errors/upstream-gateway.html =502;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
add_header Content-Type "text/html; charset=UTF-8" always;
}