Despliegue
IZ-CentralForms puede publicarse en un servidor Windows como una aplicación ASP.NET Core hospedada en IIS. La base de datos debe ejecutarse en una instancia real de SQL Server. LocalDB queda reservado únicamente para desarrollo local.
El despliegue productivo requiere:
Windows Server + IIS + .NET Hosting Bundle + SQL Server real + SMTP externo + HTTPSAlcance
Sección titulada «Alcance»| Campo | Valor |
|---|---|
| Proyecto | IZ-CentralForms |
| Tipo de aplicación | ASP.NET Core Web API |
| Target framework | net10.0 |
| Hosting recomendado | IIS |
| Base de datos | SQL Server real |
| SMTP | Mailtrap, Resend, SMTP corporativo u otro proveedor autorizado |
| Ambiente actual | Local |
| Producción | Pendiente de implementación |
Prerrequisitos
Sección titulada «Prerrequisitos»Antes de desplegar se debe contar con:
- Windows Server.
- IIS habilitado.
- .NET Hosting Bundle compatible con
net10.0. - SQL Server Express, Standard o Enterprise.
- Acceso para crear base de datos y ejecutar scripts SQL.
- Proveedor SMTP o sandbox autorizado.
- Certificado SSL válido para QA/Staging/Producción.
- Permisos para crear Application Pool.
- Permisos para publicar en la carpeta IIS.
- Acceso a logs IIS y Event Viewer.
Flujo general de despliegue
Sección titulada «Flujo general de despliegue»- Preparar servidor Windows.
- Instalar IIS.
- Instalar .NET Hosting Bundle.
- Confirmar acceso a SQL Server real.
- Crear base de datos con scripts de
sql/deploy. - Publicar la API con
dotnet publishoscripts/publish-iis.ps1. - Copiar publicación a IIS.
- Crear Application Pool.
- Configurar
appsettings.Production.json. - Registrar origins autorizados.
- Validar
/health, Swagger si aplica, GET formulario, POST submission y endpoints admin. - Entregar evidencias del despliegue.
Scripts SQL
Sección titulada «Scripts SQL»Ejecutar en orden:
sql/deploy/00-create-database.sqlsql/deploy/01-create-schema.sqlsql/deploy/02-seed-demo.sqlsql/deploy/03-add-demo-destinations.sqlsql/deploy/04-verify-deploy.sqlScript opcional para pruebas desde Swagger en IIS local:
sql/deploy/05-add-localhost-iis-origins.sqlConnection string
Sección titulada «Connection string»Recomendada para servidor
Sección titulada «Recomendada para servidor»{ "ConnectionStrings": { "DefaultConnection": "Server=SERVIDOR_SQL;Database=CentralFormsDb;User Id=centralforms_user;Password=PASSWORD_SEGURO;TrustServerCertificate=True;MultipleActiveResultSets=true" }}Demo con SQL Express
Sección titulada «Demo con SQL Express»{ "ConnectionStrings": { "DefaultConnection": "Server=.\\SQLEXPRESS;Database=CentralFormsDb;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true" }}No usar en IIS
Sección titulada «No usar en IIS»{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=CentralFormsDb;Trusted_Connection=True;MultipleActiveResultSets=true" }}Permisos SQL
Sección titulada «Permisos SQL»Si se usa usuario SQL, se recomienda asignar permisos mínimos necesarios sobre CentralFormsDb.
Si se usa Trusted_Connection=True, se debe crear login para el Application Pool:
USE master;
IF NOT EXISTS ( SELECT 1 FROM sys.server_principals WHERE name = 'IIS APPPOOL\CentralForms.Api')BEGIN CREATE LOGIN [IIS APPPOOL\CentralForms.Api] FROM WINDOWS;END;
USE CentralFormsDb;
IF NOT EXISTS ( SELECT 1 FROM sys.database_principals WHERE name = 'IIS APPPOOL\CentralForms.Api')BEGIN CREATE USER [IIS APPPOOL\CentralForms.Api] FOR LOGIN [IIS APPPOOL\CentralForms.Api];END;
ALTER ROLE db_datareader ADD MEMBER [IIS APPPOOL\CentralForms.Api];ALTER ROLE db_datawriter ADD MEMBER [IIS APPPOOL\CentralForms.Api];Para una demo controlada puede usarse temporalmente:
ALTER ROLE db_owner ADD MEMBER [IIS APPPOOL\CentralForms.Api];Publicar API
Sección titulada «Publicar API»Desde la raíz del proyecto:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass.\scripts\publish-iis.ps1Alternativa manual:
dotnet publish .\CentralForms.Api\CentralForms.Api.csproj -c Release -o .\publish\CentralForms.ApiCopiar el contenido generado desde:
publish/CentralForms.Apihacia:
C:\inetpub\wwwroot\CentralForms.ApiConfiguración productiva
Sección titulada «Configuración productiva»Crear o editar:
C:\inetpub\wwwroot\CentralForms.Api\appsettings.Production.jsonPlantilla base:
{ "ConnectionStrings": { "DefaultConnection": "Server=SERVIDOR_SQL;Database=CentralFormsDb;User Id=centralforms_user;Password=PASSWORD_SEGURO;TrustServerCertificate=True;MultipleActiveResultSets=true" }, "Swagger": { "Enabled": false }, "Seed": { "DemoData": false }, "Email": { "Host": "smtp.proveedor.com", "Port": 587, "EnableSsl": true, "UserName": "USUARIO_SMTP", "Password": "PASSWORD_SMTP", "FromEmail": "no-reply@interzone.net", "FromName": "CentralForms" }, "Admin": { "ApiKeyHash": "HASH_SHA256_DE_LA_ADMIN_KEY" }, "AllowedHosts": "*"}Variables de entorno en IIS
Sección titulada «Variables de entorno en IIS»Como alternativa a appsettings.Production.json, la configuración sensible puede definirse mediante variables de entorno. ASP.NET Core lee claves jerárquicas usando doble guion bajo __.
ASPNETCORE_ENVIRONMENT=ProductionConnectionStrings__DefaultConnection=Server=SERVIDOR_SQL;Database=CentralFormsDb;User Id=USUARIO_SQL;Password=PASSWORD_SQL;TrustServerCertificate=True;MultipleActiveResultSets=trueAdmin__ApiKeyHash=HASH_SHA256_DE_LA_ADMIN_KEYEmail__Host=smtp.proveedor.comEmail__Port=587Email__EnableSsl=trueEmail__UserName=USUARIO_SMTPEmail__Password=PASSWORD_SMTPEmail__FromEmail=no-reply@interzone.netEmail__FromName=CentralFormsSwagger__Enabled=falseSeed__DemoData=falseConfigurar IIS
Sección titulada «Configurar IIS»Application Pool
Sección titulada «Application Pool»| Campo | Valor |
|---|---|
| Nombre | CentralForms.Api |
| .NET CLR Version | No Managed Code |
| Managed Pipeline Mode | Integrated |
| Identity | ApplicationPoolIdentity |
Sitio o aplicación
Sección titulada «Sitio o aplicación»| Campo | Valor recomendado |
|---|---|
| Physical Path | C:\inetpub\wwwroot\CentralForms.Api |
| Application Pool | CentralForms.Api |
| Binding HTTP | Solo para pruebas internas |
| Binding HTTPS | Obligatorio fuera de local |
| URL pública | Pendiente según ambiente |
Origins autorizados
Sección titulada «Origins autorizados»El valor en AllowedOrigins.OriginUrl debe coincidir exactamente con el header Origin enviado por el navegador. En el código actual, Origin se valida cuando viene informado; para ambientes reales se recomienda exigirlo en los flujos públicos de navegador.
Ejemplos válidos:
http://localhosthttps://localhosthttps://localhost:7122https://app.interzone.netEjemplos incorrectos:
http://localhost/CentralForms.Apihttps://app.interzone.net/formularioSwagger en IIS
Sección titulada «Swagger en IIS»Si la aplicación se publica bajo una ruta virtual, por ejemplo:
http://localhost/CentralForms.ApiSwagger debe usar una ruta relativa para el JSON:
options.SwaggerEndpoint("v1/swagger.json", "CentralForms API v1");No usar ruta absoluta:
options.SwaggerEndpoint("/swagger/v1/swagger.json", "CentralForms API v1");porque buscaría el JSON en la raíz del sitio IIS y no dentro de /CentralForms.Api.
Validación del despliegue
Sección titulada «Validación del despliegue»Validar en este orden:
GET /healthGET /swaggerGET /api/forms/demo/contactoPOST /api/forms/demo/contacto/submitGET /api/admin/submissionsGET /api/admin/integration-logsHeaders de prueba
Sección titulada «Headers de prueba»GET formulario:
X-Api-Key: demo-api-keyOrigin: http://localhostPOST submit:
X-Api-Key: demo-api-keyX-CSRF-Token: TOKEN_DEL_GETOrigin: http://localhostContent-Type: application/jsonAdmin:
X-Admin-Key: demo-admin-keyValidaciones SQL posteriores
Sección titulada «Validaciones SQL posteriores»Después de un POST exitoso, validar persistencia e integraciones:
USE CentralFormsDb;
SELECT TOP 20 *FROM SubmissionsORDER BY CreatedAt DESC;
SELECT TOP 20 Type, Target, Status, StatusCode, ErrorMessage, StartedAt, CompletedAtFROM IntegrationLogsORDER BY StartedAt DESC;Checklist post-despliegue
Sección titulada «Checklist post-despliegue»| Validación | Resultado esperado |
|---|---|
/health responde | API disponible |
| Swagger carga | Solo si está habilitado para el ambiente |
| GET formulario responde | 200 OK con definición y csrfToken |
| POST submit responde | 200 OK con submissionId |
| Submission se guarda | Registro visible en Submissions |
| Email se ejecuta | Registro visible en IntegrationLogs |
| Webhook se ejecuta | Registro visible en IntegrationLogs |
| HTTPS activo | Certificado válido |
| Swagger producción | Deshabilitado o restringido |
| Seed demo producción | Desactivado |
Diagnóstico rápido
Sección titulada «Diagnóstico rápido»| Síntoma | Causa probable | Acción |
|---|---|---|
500.19 | Hosting Bundle no instalado o web.config no reconocido | Instalar o reparar Hosting Bundle y ejecutar iisreset. |
/health OK pero GET formulario devuelve 500 | Problema SQL o connection string | Revisar base de datos, permisos y appsettings.Production.json. |
GET formulario devuelve 404 | consumerCode o formCode incorrecto | Usar demo/contacto o revisar tablas. |
POST devuelve 403 Origin | Falta Origin exacto en AllowedOrigins | Insertar Origin exacto, sin path. |
POST devuelve 403 CSRF | Token vencido, reutilizado o de otro formulario | Ejecutar GET nuevamente y usar nuevo token. |
POST devuelve 200 pero no llega correo | SMTP o destino email mal configurado | Revisar FormDestinations, configuración Email e IntegrationLogs. |
| Swagger no carga JSON | Ruta Swagger absoluta bajo ruta virtual | Usar v1/swagger.json como ruta relativa. |
Rollback
Sección titulada «Rollback»- Detener sitio o aplicación IIS.
- Restaurar carpeta publicada anterior.
- Restaurar
appsettings.Production.jsonanterior si cambió. - Restaurar backup de base de datos si hubo migración destructiva.
- Iniciar sitio IIS.
- Validar
/health. - Validar GET formulario.
- Validar POST submit.
Evidencia requerida
Sección titulada «Evidencia requerida»El responsable del despliegue debe entregar:
- URL publicada.
- Fecha y hora de publicación.
- Versión, commit o paquete publicado.
- Resultado de
/health. - Evidencia de Swagger si aplica.
- Evidencia de GET formulario.
- Evidencia de POST submit.
- Evidencia de submission en base de datos o admin endpoint.
- Evidencia de
IntegrationLogs. - Observaciones y errores encontrados.