Try 1550
This commit is contained in:
		| @@ -2,25 +2,20 @@ | |||||||
| FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build | FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
|  |  | ||||||
| # Copiar archivos de proyecto y restaurar dependencias primero para aprovechar el caché de Docker |  | ||||||
| COPY backend/src/Titulares.Api/Titulares.Api.csproj backend/src/Titulares.Api/ | COPY backend/src/Titulares.Api/Titulares.Api.csproj backend/src/Titulares.Api/ | ||||||
| RUN dotnet restore backend/src/Titulares.Api/Titulares.Api.csproj | RUN dotnet restore backend/src/Titulares.Api/Titulares.Api.csproj | ||||||
|  |  | ||||||
| # Copiar el resto del código fuente del backend |  | ||||||
| COPY backend/src/ ./backend/src/ | COPY backend/src/ ./backend/src/ | ||||||
|  |  | ||||||
| # Publicar la aplicación en modo Release |  | ||||||
| RUN dotnet publish backend/src/Titulares.Api/Titulares.Api.csproj -c Release -o /app/publish | RUN dotnet publish backend/src/Titulares.Api/Titulares.Api.csproj -c Release -o /app/publish | ||||||
|  |  | ||||||
| # --- Etapa 2: Imagen Final (Final) --- | # --- Etapa 2: Imagen Final (Final) --- | ||||||
| FROM mcr.microsoft.com/dotnet/aspnet:9.0 | FROM mcr.microsoft.com/dotnet/aspnet:9.0 | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
|  |  | ||||||
| # Copiar solo los artefactos compilados desde la etapa de build |  | ||||||
| COPY --from=build /app/publish . | COPY --from=build /app/publish . | ||||||
|  |  | ||||||
| # Exponer el puerto interno que ASP.NET Core usará por defecto en Docker |  | ||||||
| EXPOSE 8080 | EXPOSE 8080 | ||||||
|  | # Añade esta línea para asegurar que Kestrel escuche en el puerto 8080 | ||||||
| # Comando para iniciar la aplicación | ENV ASPNETCORE_URLS=http://+:8080 | ||||||
| ENTRYPOINT ["dotnet", "Titulares.Api.dll"] | ENTRYPOINT ["dotnet", "Titulares.Api.dll"] | ||||||
| @@ -4,6 +4,7 @@ using Titulares.Api.Hubs; | |||||||
| using Titulares.Api.Models; | using Titulares.Api.Models; | ||||||
| using Titulares.Api.Services; | using Titulares.Api.Services; | ||||||
| using Titulares.Api.Workers; | using Titulares.Api.Workers; | ||||||
|  | using Microsoft.AspNetCore.HttpOverrides; | ||||||
|  |  | ||||||
| var builder = WebApplication.CreateBuilder(args); | var builder = WebApplication.CreateBuilder(args); | ||||||
|  |  | ||||||
| @@ -23,19 +24,27 @@ builder.Services.AddScoped<CsvService>(); | |||||||
| builder.Services.AddSingleton<ConfiguracionRepositorio>(); | builder.Services.AddSingleton<ConfiguracionRepositorio>(); | ||||||
| builder.Services.AddSingleton<EstadoProcesoService>(); | builder.Services.AddSingleton<EstadoProcesoService>(); | ||||||
|  |  | ||||||
| // Añadimos la política de CORS | var frontendUrl = "http://192.168.5.128:8905"; | ||||||
|  |  | ||||||
| builder.Services.AddCors(options => | builder.Services.AddCors(options => | ||||||
| { | { | ||||||
|     options.AddPolicy("AllowReactApp", builder => |     options.AddPolicy("AllowReactApp", policyBuilder => | ||||||
|     { |     { | ||||||
|         //builder.WithOrigins("http://localhost:5173") |         policyBuilder.WithOrigins(frontendUrl) | ||||||
|         builder.AllowAnyOrigin() |                      .AllowAnyHeader() | ||||||
|                .AllowAnyHeader() |                      .AllowAnyMethod() | ||||||
|                .AllowAnyMethod() |                      .AllowCredentials(); | ||||||
|                .AllowCredentials(); |  | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | builder.Services.Configure<ForwardedHeadersOptions>(options => | ||||||
|  | { | ||||||
|  |     options.ForwardedHeaders = | ||||||
|  |         ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; | ||||||
|  |     options.KnownNetworks.Clear(); | ||||||
|  |     options.KnownProxies.Clear(); | ||||||
|  | }); | ||||||
|  |  | ||||||
| builder.Services.AddSignalR(); | builder.Services.AddSignalR(); | ||||||
|  |  | ||||||
| builder.Services.AddHostedService<ProcesoScrapingWorker>(); | builder.Services.AddHostedService<ProcesoScrapingWorker>(); | ||||||
| @@ -47,6 +56,16 @@ builder.Services.AddAuthorization(); | |||||||
| // ========================== | // ========================== | ||||||
| var app = builder.Build(); | var app = builder.Build(); | ||||||
|  |  | ||||||
|  | // DEBE IR ANTES DE UseRouting, UseCors, UseAuthorization, etc. | ||||||
|  | app.UseForwardedHeaders(); | ||||||
|  |  | ||||||
|  | // Configure the HTTP request pipeline. | ||||||
|  | if (app.Environment.IsDevelopment()) | ||||||
|  | { | ||||||
|  |     app.UseSwagger(); | ||||||
|  |     app.UseSwaggerUI(); | ||||||
|  | } | ||||||
|  |  | ||||||
| // 3. Configurar el pipeline de peticiones HTTP. | // 3. Configurar el pipeline de peticiones HTTP. | ||||||
| // ============================================ | // ============================================ | ||||||
|  |  | ||||||
| @@ -72,5 +91,4 @@ app.UseAuthorization(); | |||||||
| app.MapControllers(); | app.MapControllers(); | ||||||
| app.MapHub<TitularesHub>("/titularesHub"); | app.MapHub<TitularesHub>("/titularesHub"); | ||||||
|  |  | ||||||
|  |  | ||||||
| app.Run(); | app.Run(); | ||||||
| @@ -7,6 +7,6 @@ | |||||||
|   }, |   }, | ||||||
|   "AllowedHosts": "*", |   "AllowedHosts": "*", | ||||||
|   "ConnectionStrings": { |   "ConnectionStrings": { | ||||||
|     "DefaultConnection": "Server=db-sqlserver;Database=TitularesDB;User Id=titularesApi;Password=PTP847Titulares;Trusted_Connection=True;TrustServerCertificate=True;" |     "DefaultConnection": "Server=db-sqlserver;Database=TitularesDB;User Id=titularesApi;Password=PTP847Titulares;TrustServerCertificate=True;" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -17,6 +17,8 @@ services: | |||||||
|     build: |     build: | ||||||
|       context: ./frontend |       context: ./frontend | ||||||
|       dockerfile: Dockerfile |       dockerfile: Dockerfile | ||||||
|  |       args: | ||||||
|  |         - VITE_API_BASE_URL=http://192.168.5.128:8905 | ||||||
|     container_name: titulares-frontend |     container_name: titulares-frontend | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|     expose: |     expose: | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								frontend/.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								frontend/.env
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | VITE_API_BASE_URL=http://192.168.5.128:8905 | ||||||
| @@ -1,21 +1,37 @@ | |||||||
|  | # /frontend/proxy/nginx.conf | ||||||
|  |  | ||||||
| server { | server { | ||||||
|     listen 80; |     listen 80; | ||||||
|  |     server_name localhost; | ||||||
|  |  | ||||||
|     # Pasa todas las peticiones a la API al servicio del backend |  | ||||||
|     location /api/ { |  | ||||||
|         proxy_pass http://titulares-api:8080/api/; |  | ||||||
|         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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     # Pasa el resto de las peticiones al servicio del frontend |  | ||||||
|     location / { |     location / { | ||||||
|         proxy_pass http://titulares-frontend:80; |         proxy_pass http://titulares-frontend:80; | ||||||
|         proxy_set_header Host $host; |         proxy_set_header Host $host; | ||||||
|         proxy_set_header X-Real-IP $remote_addr; |         proxy_set_header X-Real-IP $remote_addr; | ||||||
|         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||||
|         proxy_set_header X-Forwarded-Proto $scheme; |         proxy_set_header X-Forwarded-Proto $scheme; | ||||||
|  |         proxy_set_header X-Forwarded-Host $host; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     location /api/ { | ||||||
|  |         proxy_pass http://titulares-api:8080; | ||||||
|  |         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_set_header X-Forwarded-Host $host; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     location /titularesHub/ { | ||||||
|  |         proxy_pass http://titulares-api:8080; | ||||||
|  |         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_set_header X-Forwarded-Host $host; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -3,8 +3,10 @@ | |||||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||||
| import * as signalR from '@microsoft/signalr'; | import * as signalR from '@microsoft/signalr'; | ||||||
|  |  | ||||||
|  | // Construye la URL completa del Hub | ||||||
|  | const HUB_URL = `${import.meta.env.VITE_API_BASE_URL}/titularesHub`; | ||||||
| //const HUB_URL = 'http://localhost:5174/titularesHub'; | //const HUB_URL = 'http://localhost:5174/titularesHub'; | ||||||
| const HUB_URL = '/titularesHub'; |  | ||||||
|  |  | ||||||
| // Definimos un tipo para el estado de la conexión para más claridad | // Definimos un tipo para el estado de la conexión para más claridad | ||||||
| export type ConnectionStatus = 'Connecting' | 'Connected' | 'Disconnected' | 'Reconnecting'; | export type ConnectionStatus = 'Connecting' | 'Connected' | 'Disconnected' | 'Reconnecting'; | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import axios from 'axios'; | |||||||
| import type { Configuracion, Titular } from '../types'; | import type { Configuracion, Titular } from '../types'; | ||||||
|  |  | ||||||
| //const API_URL = 'http://localhost:5174/api'; | //const API_URL = 'http://localhost:5174/api'; | ||||||
| const API_URL = '/api'; | const API_URL = `${import.meta.env.VITE_API_BASE_URL}/api`; | ||||||
|  |  | ||||||
| const apiClient = axios.create({ | const apiClient = axios.create({ | ||||||
|   baseURL: API_URL, |   baseURL: API_URL, | ||||||
|   | |||||||
| @@ -1,7 +1,22 @@ | |||||||
| import { defineConfig } from 'vite' | import { defineConfig } from 'vite' | ||||||
| import react from '@vitejs/plugin-react' | import react from '@vitejs/plugin-react' | ||||||
|  |  | ||||||
| // https://vite.dev/config/ | // https://vitejs.dev/config/ | ||||||
| export default defineConfig({ | export default defineConfig({ | ||||||
|   plugins: [react()], |   plugins: [react()], | ||||||
|  |   server: { | ||||||
|  |     proxy: { | ||||||
|  |       // Redirige cualquier petición que empiece con '/api' al backend | ||||||
|  |       '/api': { | ||||||
|  |         target: 'http://localhost:5174', // <-- Usa el puerto HTTP del backend | ||||||
|  |         changeOrigin: true, | ||||||
|  |       }, | ||||||
|  |       // Redirige cualquier petición a '/titularesHub' al backend (para SignalR) | ||||||
|  |       '/titularesHub': { | ||||||
|  |         target: 'http://localhost:5174', // <-- Usa el mismo puerto | ||||||
|  |         ws: true, // <-- Habilita el proxy para WebSockets (crucial para SignalR) | ||||||
|  |         changeOrigin: true, | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
| }) | }) | ||||||
		Reference in New Issue
	
	Block a user