fix: priority ^~ /uploads/ routing in Nginx and share strapi_uploads volume with backend
This commit is contained in:
@@ -71,6 +71,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- backend_uploads:/app/server/uploads
|
- backend_uploads:/app/server/uploads
|
||||||
- backend_data:/app/server/data
|
- backend_data:/app/server/data
|
||||||
|
- strapi_uploads:/app/strapi-cms/public/uploads
|
||||||
depends_on:
|
depends_on:
|
||||||
- strapi-cms
|
- strapi-cms
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
+35
-21
@@ -2,6 +2,8 @@ server {
|
|||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
@@ -11,7 +13,39 @@ server {
|
|||||||
gzip on;
|
gzip on;
|
||||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
|
||||||
# Explicit handling for static assets (JavaScript, CSS, images, fonts)
|
# Priority prefix location for uploads - proxies to Express backend container
|
||||||
|
location ^~ /uploads/ {
|
||||||
|
proxy_pass http://backend:3005/uploads/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Priority prefix location for backend API
|
||||||
|
location ^~ /api/ {
|
||||||
|
proxy_pass http://backend:3005/api/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Prevent 504 Gateway Timeouts
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Explicit handling for static JS, CSS, images, and fonts
|
||||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
|
||||||
try_files $uri /citpl_website$uri =404;
|
try_files $uri /citpl_website$uri =404;
|
||||||
expires 30d;
|
expires 30d;
|
||||||
@@ -39,26 +73,6 @@ server {
|
|||||||
try_files $uri $uri/ /preview.html;
|
try_files $uri $uri/ /preview.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Proxy backend API requests to the Express backend container
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://backend:3005/api/;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection 'upgrade';
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_cache_bypass $http_upgrade;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy media upload requests to backend
|
|
||||||
location /uploads/ {
|
|
||||||
proxy_pass http://backend:3005/uploads/;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
error_page 500 502 503 504 /50x.html;
|
||||||
location = /50x.html {
|
location = /50x.html {
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ export default function BlogDetailPage({ blog, allBlogs = [], isMobile, onNaviga
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* HERO FEATURED IMAGE */}
|
{/* HERO FEATURED IMAGE */}
|
||||||
{blog.image && (
|
{(blog.image || blog.coverImage || blog.ogImage) && (
|
||||||
<div style={{
|
<div style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: isMobile ? '250px' : '520px',
|
height: isMobile ? '250px' : '520px',
|
||||||
@@ -356,9 +356,24 @@ export default function BlogDetailPage({ blog, allBlogs = [], isMobile, onNaviga
|
|||||||
boxShadow: '0 25px 60px rgba(0, 0, 0, 0.75)'
|
boxShadow: '0 25px 60px rgba(0, 0, 0, 0.75)'
|
||||||
}}>
|
}}>
|
||||||
<img
|
<img
|
||||||
src={assetUrl(blog.image)}
|
src={assetUrl(blog.image || blog.coverImage || blog.ogImage)}
|
||||||
alt={blog.title}
|
alt={blog.title}
|
||||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||||
|
onError={(e) => {
|
||||||
|
const titleLower = (blog.title || '').toLowerCase();
|
||||||
|
const catLower = (blog.category || '').toLowerCase();
|
||||||
|
let fallback = '/assets/arvindh_agentic_ai.jpg';
|
||||||
|
if (titleLower.includes('llm')) fallback = '/assets/arvindh_llm_financial.jpg';
|
||||||
|
else if (titleLower.includes('supply chain')) fallback = '/assets/arvindh_supply_chain.jpg';
|
||||||
|
else if (titleLower.includes('prodmax')) fallback = '/assets/prodmax_dashboard.png';
|
||||||
|
else if (titleLower.includes('vr') || titleLower.includes('incidents')) fallback = '/assets/whyus_vr_man.jpg';
|
||||||
|
else if (titleLower.includes('scada') || titleLower.includes('plc') || titleLower.includes('speed vs')) fallback = '/assets/arvindh_agentic_ai.jpg';
|
||||||
|
else if (catLower.includes('ai')) fallback = '/assets/arvindh_agentic_ai.jpg';
|
||||||
|
const resolvedFallback = assetUrl(fallback);
|
||||||
|
if (e.currentTarget.src !== resolvedFallback) {
|
||||||
|
e.currentTarget.src = resolvedFallback;
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -646,14 +661,12 @@ export default function BlogDetailPage({ blog, allBlogs = [], isMobile, onNaviga
|
|||||||
</ol>
|
</ol>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const imgMatch = block.match(/!\[(.*?)\]\((.*?)\)/);
|
const mdImgMatch = block.match(/!\[(.*?)\]\((.*?)\)/);
|
||||||
if (imgMatch) {
|
const htmlImgMatch = block.match(/<img[^>]+src=["']([^"']+)["'][^>]*>/i);
|
||||||
const caption = imgMatch[1] ? imgMatch[1].trim() : '';
|
if (mdImgMatch || htmlImgMatch) {
|
||||||
let rawImgUrl = imgMatch[2];
|
const caption = mdImgMatch ? (mdImgMatch[1] ? mdImgMatch[1].trim() : '') : '';
|
||||||
let resolvedSrc = assetUrl(rawImgUrl);
|
const rawImgUrl = mdImgMatch ? mdImgMatch[2] : htmlImgMatch[1];
|
||||||
if (rawImgUrl.startsWith('http://localhost:1337/uploads/')) {
|
const resolvedSrc = assetUrl(rawImgUrl);
|
||||||
resolvedSrc = assetUrl(rawImgUrl.replace('http://localhost:1337', ''));
|
|
||||||
}
|
|
||||||
const isFilename = caption && /\.(jpg|jpeg|png|gif|webp|svg|bmp)$/i.test(caption);
|
const isFilename = caption && /\.(jpg|jpeg|png|gif|webp|svg|bmp)$/i.test(caption);
|
||||||
const displayCaption = caption && !isFilename ? caption : null;
|
const displayCaption = caption && !isFilename ? caption : null;
|
||||||
|
|
||||||
@@ -671,9 +684,12 @@ export default function BlogDetailPage({ blog, allBlogs = [], isMobile, onNaviga
|
|||||||
boxShadow: '0 15px 35px rgba(0,0,0,0.5)'
|
boxShadow: '0 15px 35px rgba(0,0,0,0.5)'
|
||||||
}}
|
}}
|
||||||
onError={(e) => {
|
onError={(e) => {
|
||||||
if (rawImgUrl.includes('/uploads/')) {
|
if (rawImgUrl && rawImgUrl.includes('/uploads/')) {
|
||||||
const uploadPath = rawImgUrl.substring(rawImgUrl.indexOf('/uploads/'));
|
const uploadPath = rawImgUrl.substring(rawImgUrl.indexOf('/uploads/'));
|
||||||
e.currentTarget.src = `http://localhost:1337${uploadPath}`;
|
const fallback = assetUrl(uploadPath);
|
||||||
|
if (e.currentTarget.src !== fallback) {
|
||||||
|
e.currentTarget.src = fallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user