feat: Añadir configuración de Nginx para el API de LMS y ajustar las rutas en el frontend de OpenCCB
This commit is contained in:
@@ -20,6 +20,7 @@ services:
|
||||
- html:/usr/share/nginx/html
|
||||
- ./nginx/proxy.conf:/etc/nginx/conf.d/proxy.conf:ro
|
||||
- ./nginx/studio.conf:/etc/nginx/vhost.d/studio.norteamericano.com:ro
|
||||
- ./nginx/learning.conf:/etc/nginx/vhost.d/learning.norteamericano.com:ro
|
||||
restart: always
|
||||
networks:
|
||||
- openccb-network
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Custom nginx configuration for OpenCCB Learning
|
||||
# Keep the learning frontend on port 3003 and expose LMS API via same-origin /lms-api.
|
||||
|
||||
location /lms-api/ {
|
||||
rewrite ^/lms-api/(.*)$ /$1 break;
|
||||
proxy_pass http://openccb-experience:3002;
|
||||
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 $http_x_forwarded_proto;
|
||||
proxy_set_header Connection "";
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
+41
-2
@@ -15,6 +15,17 @@ location /cms-api/ {
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location /lms-api/ {
|
||||
rewrite ^/lms-api/(.*)$ /$1 break;
|
||||
proxy_pass http://openccb-experience:3002;
|
||||
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 $http_x_forwarded_proto;
|
||||
proxy_set_header Connection "";
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
# Auth pages like GET /auth/login and GET /auth/register must be served by Next.js (3000),
|
||||
# while the auth API endpoints (POST /auth/login, POST /auth/register, /auth/me, /auth/sso/*)
|
||||
# must continue to go to the CMS backend (3001).
|
||||
@@ -222,8 +233,28 @@ location /grading/ {
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location = /question-bank {
|
||||
proxy_pass http://openccb-studio:3000;
|
||||
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 $http_x_forwarded_proto;
|
||||
proxy_set_header Connection "";
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location = /question-bank/ {
|
||||
proxy_pass http://openccb-studio:3000/question-bank;
|
||||
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 $http_x_forwarded_proto;
|
||||
proxy_set_header Connection "";
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location /question-bank/ {
|
||||
proxy_pass http://openccb-studio:3001;
|
||||
proxy_pass http://openccb-studio:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
@@ -252,8 +283,16 @@ location = /admin/ {
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location = /admin/organizations {
|
||||
return 302 /admin;
|
||||
}
|
||||
|
||||
location = /admin/organizations/ {
|
||||
return 302 /admin;
|
||||
}
|
||||
|
||||
location /admin/ {
|
||||
proxy_pass http://openccb-studio:3001;
|
||||
proxy_pass http://openccb-studio:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
@@ -10,7 +10,12 @@ const getApiBaseUrl = (defaultPort: string, envVar?: string) => {
|
||||
return `http://localhost:${defaultPort}`;
|
||||
};
|
||||
|
||||
export const getLmsApiUrl = () => getApiBaseUrl("3002", process.env.NEXT_PUBLIC_LMS_API_URL);
|
||||
export const getLmsApiUrl = () => {
|
||||
if (typeof window !== 'undefined' && window.location.hostname === 'learning.norteamericano.com') {
|
||||
return `${window.location.protocol}//learning.norteamericano.com/lms-api`;
|
||||
}
|
||||
return getApiBaseUrl("3002", process.env.NEXT_PUBLIC_LMS_API_URL);
|
||||
};
|
||||
export const getCmsApiUrl = () => getApiBaseUrl("3001", process.env.NEXT_PUBLIC_CMS_API_URL);
|
||||
|
||||
export const getImageUrl = (path?: string) => {
|
||||
|
||||
@@ -25,7 +25,12 @@ const nextConfig = {
|
||||
],
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
// Using `fallback` ensures Next.js pages (including dynamic routes like
|
||||
// /courses/[id]) are matched BEFORE these proxy rewrites. Without this,
|
||||
// `afterFiles` rewrites (the default for arrays) would intercept RSC
|
||||
// prefetch requests to dynamic pages and proxy them to Rust instead.
|
||||
return {
|
||||
fallback: [
|
||||
{
|
||||
source: '/assets/:path*',
|
||||
destination: 'http://localhost:3001/assets/:path*',
|
||||
@@ -143,7 +148,8 @@ const nextConfig = {
|
||||
source: '/health',
|
||||
destination: 'http://localhost:3001/health',
|
||||
},
|
||||
];
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function AdminLayout({ children }: { children: React.ReactNode })
|
||||
|
||||
const menuItems = [
|
||||
{ icon: LayoutDashboard, label: "Dashboard", href: "/admin" },
|
||||
{ icon: Building2, label: "Organizations", href: "/admin/organizations" },
|
||||
{ icon: Building2, label: "Organizations", href: "/admin" },
|
||||
{ icon: Users, label: "Users", href: "/admin/users" },
|
||||
{ icon: Mic, label: "Audio Evaluations", href: "/admin/audio-evaluations" },
|
||||
{ icon: ClipboardList, label: "Audit Logs", href: "/admin/audit" },
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function AuthHeader() {
|
||||
<div className="flex items-center gap-4">
|
||||
{user?.role === 'admin' && (
|
||||
<>
|
||||
<Link href="/admin/organizations" className="text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-white transition-colors flex items-center gap-2" title="Organizations">
|
||||
<Link href="/admin" className="text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-white transition-colors flex items-center gap-2" title="Organizations">
|
||||
<Building2 size={16} /> <span className="hidden md:inline">Org</span>
|
||||
</Link>
|
||||
<Link href="/admin/audit" className="text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-white transition-colors flex items-center gap-2" title="Audit Logs">
|
||||
|
||||
@@ -26,7 +26,14 @@ const getApiBaseUrl = (defaultPort: string, envVar?: string) => {
|
||||
};
|
||||
|
||||
export const API_BASE_URL = getApiBaseUrl("3001", process.env.NEXT_PUBLIC_CMS_API_URL);
|
||||
export const LMS_API_BASE_URL = getApiBaseUrl("3002", process.env.NEXT_PUBLIC_LMS_API_URL);
|
||||
const getLmsBaseUrl = (envVar?: string) => {
|
||||
if (typeof window !== 'undefined' && window.location.hostname === 'studio.norteamericano.com') {
|
||||
return `${window.location.protocol}//studio.norteamericano.com/lms-api`;
|
||||
}
|
||||
return getApiBaseUrl("3002", envVar);
|
||||
};
|
||||
|
||||
export const LMS_API_BASE_URL = getLmsBaseUrl(process.env.NEXT_PUBLIC_LMS_API_URL);
|
||||
|
||||
// Polyfill for crypto.randomUUID() for non-HTTPS contexts
|
||||
export function generateUUID(): string {
|
||||
|
||||
Reference in New Issue
Block a user