.NET
Kubiy ejecuta aplicaciones .NET usando systemd como process manager. El proceso de deploy compila y publica la aplicación en el servidor, o ejecuta una DLL o binario ya compilado.
Presets disponibles
auto/publish (recomendado)
Kubiy detecta automáticamente el archivo .csproj en el proyecto, ejecuta dotnet publish y luego inicia la aplicación publicada.
| Parámetro | Valor |
|---|---|
startMode | auto |
| Target | Detectado automáticamente |
| Build por defecto | dotnet publish automático |
Este preset es el recomendado para la mayoría de proyectos. No requiere que conozcas el nombre exacto del .csproj o la DLL resultante.
Ejemplo de configuración:
Preset: auto/publish
dotnet [dll]
Ejecuta una DLL ya compilada. Úsalo si haces el build en CI/CD y subes el output ya compilado al repositorio, o si publicas manualmente.
| Parámetro | Valor |
|---|---|
startMode | dll |
| Target | Ruta a la DLL (ej: publish/MiApp.dll) |
Ejemplo de configuración:
Preset: dotnet [dll]
Target: bin/Release/net8.0/MiApp.dll
Si usas este modo y subes código fuente (no el binario compilado), debes compilar primero usando el Build Command. Ver Build Command.
dotnet run
Modo de desarrollo. Compila y ejecuta la aplicación directamente desde el código fuente con dotnet run.
| Parámetro | Valor |
|---|---|
startMode | dotnetrun |
| Target | Directorio del proyecto (por defecto la raíz) |
:::warning Uso en producción
dotnet run no está optimizado para producción. Tarda más en iniciar y no aplica las optimizaciones de dotnet publish. Úsalo solo para testing o demos.
:::
bin (binario self-contained)
Ejecuta un binario self-contained publicado con --self-contained true. No requiere que el runtime de .NET esté instalado en el servidor.
| Parámetro | Valor |
|---|---|
startMode | bin |
| Target | Ruta al binario ejecutable |
Ejemplo de configuración:
Preset: bin
Target: publish/MiApp
Build Command: dotnet publish -c Release --self-contained true -r linux-x64 -o publish
Puerto
Kubiy configura automáticamente la variable ASPNETCORE_URLS con el valor:
http://127.0.0.1:{PORT}
Tu aplicación ASP.NET Core usará esta variable automáticamente para saber en qué puerto y dirección escuchar. No necesitas configurarlo explícitamente.
El puerto por defecto es 5000.
Si tu app usa app.UseHttpsRedirection() y el health check falla, verifica que la app no intenta redirigir la petición HTTP a HTTPS. Kubiy usa HTTP para el health check interno.
ASPNETCORE_URLS y configuración
Para aplicaciones que no usan la detección automática de ASPNETCORE_URLS, puedes leer el puerto explícitamente:
var port = Environment.GetEnvironmentVariable("PORT") ?? "5000";
builder.WebHost.UseUrls($"http://0.0.0.0:{port}");
O en appsettings.json (no recomendado para producción — usa variables de entorno):
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:5000"
}
}
}
}
Build Command
El campo Build Command en .NET funciona como un pre-build hook: se ejecuta antes del dotnet publish automático.
Esto significa que puedes usarlo para:
- Restaurar paquetes NuGet adicionales
- Generar código (Entity Framework migrations, OpenAPI clients, etc.)
- Ejecutar scripts de preparación
# Restaurar herramientas dotnet
dotnet tool restore
# Generar migrations de EF Core antes del publish
dotnet ef migrations bundle --self-contained -r linux-x64
# Instalar herramientas y generar código
dotnet tool restore && dotnet ef dbcontext scaffold ...
:::warning Diferencia con otros runtimes
En .NET, el Build Command es un hook previo al publish, no un reemplazo. El dotnet publish siempre se ejecuta después. Si quieres controlar completamente el proceso de build, usa el preset dotnet [dll] o bin y haz el publish explícitamente en el Build Command.
:::
Ver la referencia completa de Build Command.
Casos de uso comunes
ASP.NET Core Web API
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
// Health check endpoint
app.MapGet("/health", () => Results.Ok(new { status = "ok" }));
app.Run();
Configuración en Kubiy:
Preset: auto/publish
Health: /health
Minimal API
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/health", () => new { status = "ok" });
app.MapGet("/api/hello", () => new { message = "Hello World" });
app.Run();
Configuración en Kubiy:
Preset: auto/publish
Health: /health
Con Entity Framework Core migrations
Si necesitas aplicar migrations antes de que la app inicie, puedes hacerlo en el Build Command o en el startup de la app. El enfoque más robusto es aplicar migrations en el startup:
// Program.cs
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Database.MigrateAsync();
}
Monorepo con múltiples proyectos
Si tu repositorio tiene varios proyectos .NET y quieres desplegar uno específico:
.
├── src/
│ ├── Api/
│ │ ├── Api.csproj
│ │ └── Program.cs
│ └── Worker/
│ └── Worker.csproj
└── MiSolucion.sln
Configuración en Kubiy:
Subdirectorio: src/Api
Preset: auto/publish
Proyecto con múltiples .csproj
Si tu proyecto tiene múltiples .csproj en el mismo directorio y la detección automática elige el equivocado, especifica el proyecto explícitamente en el Build Command:
dotnet publish src/Api/Api.csproj -c Release
Y usa el preset dotnet [dll]:
Preset: dotnet [dll]
Target: src/Api/bin/Release/net8.0/publish/Api.dll
Build Command: dotnet publish src/Api/Api.csproj -c Release
Variables de entorno disponibles
| Variable | Descripción |
|---|---|
PORT | Puerto asignado (default 5000) |
APP_PORT | Alias de PORT |
ASPNETCORE_URLS | Configurado automáticamente a http://127.0.0.1:{PORT} |
ASPNETCORE_ENVIRONMENT | No se configura automáticamente — agrégala si necesitas Production |
KUBIY_DEPLOY_ID | ID del deploy actual |
KUBIY_APP_ID | ID de la aplicación |
Agrega ASPNETCORE_ENVIRONMENT=Production en las variables de entorno de tu app para activar los comportamientos de producción de ASP.NET Core (sin developer exception page, sin hot reload, etc.).
Lectura de variables en C#:
var dbUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
var apiKey = builder.Configuration["API_KEY"]; // también accesible vía IConfiguration
Health Check recomendado
ASP.NET Core tiene soporte nativo para health checks:
// Program.cs
builder.Services.AddHealthChecks();
// ...
app.MapHealthChecks("/health");
O con un endpoint simple:
app.MapGet("/health", () => Results.Ok(new { status = "ok", timestamp = DateTime.UtcNow }));
Configura en Kubiy:
Health Check Path: /health
Troubleshooting
La detección automática de .csproj falla
Si tienes múltiples .csproj en el directorio o la estructura no es estándar, usa el subdirectorio para apuntar al directorio correcto, o usa el preset dotnet [dll] con un Build Command explícito.
"Could not find a part of the path" al publicar
El directorio de output del publish no existe. El dotnet publish lo crea automáticamente, pero si usas un Build Command que mueve archivos, asegúrate de que el directorio destino exista.
La app inicia pero no acepta conexiones externas
Verifica que la app no está escuchando solo en localhost. Con el preset auto/publish, Kubiy configura ASPNETCORE_URLS=http://127.0.0.1:{PORT} — esto es suficiente porque el proxy inverso de Kubiy está en el mismo host.
Si la app tiene configuración hardcodeada de URLs, puede estar sobreescribiendo ASPNETCORE_URLS. Revisa launchSettings.json y appsettings.json.
Redirección HTTPS hace fallar el health check
Si app.UseHttpsRedirection() está activo, el health check de Kubiy (HTTP) recibirá un redirect 301/302 y no lo considerará exitoso. Opciones:
- Desactiva
UseHttpsRedirection()para el endpoint de health (configura la redirección solo para rutas específicas) - O usa un middleware que excluya el path de health del redirect:
app.Use(async (context, next) =>
{
if (context.Request.Path.StartsWithSegments("/health"))
{
await next();
return;
}
// resto del pipeline
await next();
});
app.UseHttpsRedirection();
Timeout en publish para proyectos grandes
Si el dotnet publish tarda mucho, considera:
- Usar
.dockerignoreo.gitignorepara no subir archivos innecesarios al repo - Compilar en modo
--no-restoresi las dependencias NuGet no cambian frecuentemente (agregadotnet restoreen el Build Command primero)