Deploy configuration

- Added tasks for publishing as container image.
- Improvements for deployment: Db migrations on startup, reverse-proxy forward headers, and DataProtect management.
- Added deploy example using docker-compose.
This commit is contained in:
2026-09-09 17:50:27 +02:00
parent fb2e00f06c
commit dcd5bb2aad
8 changed files with 173 additions and 2 deletions
+9
View File
@@ -0,0 +1,9 @@
{
"files.associations": {
"appsettings*.json": "jsonc",
"*_config.json": "jsonc",
"*_config.json.sample": "jsonc"
},
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "modificationsIfAvailable",
}
+36
View File
@@ -0,0 +1,36 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "dotnet",
"task": "build",
"group": "build",
"problemMatcher": [],
"label": "Build Somnia.GuestLog"
},
{
"label": "Publish Container Image",
"type": "shell",
"command": "dotnet",
"args": [
"publish",
"-c",
"Release",
"--os",
"linux",
"--arch",
"x64",
"-p:PublishProfile=DefaultContainer"
],
"options": {
"cwd": "${workspaceFolder}/src/Somnia.GuestLog"
},
"group": "build",
"presentation": {
"reveal": "always"
}
},
]
}
+23
View File
@@ -0,0 +1,23 @@
# Somnia.GuestLog Deployment
## Deploy using docker-compose
Use [docker-compose file](docker-compose.yaml) as example. Configure required enviroment variables.
Notes:
- By default, HTTP-only is deploy. Uncomment required sections to enable HTTPS (and mount required certs).
- Reverse-proxies should work?
[To-Be-Improved]
## Manually update registry
Container images are built by CI/CD pipelines and uploaded to the registry (**not yet!**).
If required, a image can be manually built and uploaded to the registry (for testing or development purposes):
```sh
podman push [IMAGE_ID] [REGISTRY]/somnia/somnia-guestlog:[TAG]
# Example:
podman push localhost/somnia-guestlog:latest gitea.uberelectronnetwork.cc/somnia/somnia-guestlog:devbuild
```
+66
View File
@@ -0,0 +1,66 @@
services:
database:
environment:
POSTGRES_DB: ${POSTGRES_DB:-SomniaGuestLog}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-NotAStrongPassword}
POSTGRES_USER: ${POSTGRES_USER:-somnia}
healthcheck:
retries: 5
start_period: 60s
test:
- CMD
- pg_isready
timeout: 5s
image: postgres:18-alpine
volumes:
- somniaguestlog_database_data:/var/lib/postgresql:rw
somnia-guestlog:
depends_on:
- database
environment:
SOMNIA_ConnectionStrings__DbSomniaGuestLog: Host=database;Port=5432;Username=${POSTGRES_USER:-somnia};Password=${POSTGRES_PASSWORD:-NotAStrongPassword};Database=${POSTGRES_DB:-SomniaGuestLog}
# Configure path for data protection keys. This path must persists between container restarts (use a mount or a volume).
SOMNIA_DataProtectionDir: /SomniaGuestLog/dataprotection
ASPNETCORE_URLS: "http://+:8080"
# Somnia AddressQuery Service - START
SOMNIA_AddressQuery__Provider: "Nominatim"
# Override if required.
# SOMNIA_AddressQuery__ServiceURL: ""
# SOMNIA_AddressQuery__ApiKey: ""
SOMNIA_AddressQuery__UserAgent: Somnia-GuestLog-Dev-Container
SOMNIA_AddressQuery__ResultLang: es
# Somnia AddressQuery Service - END
SOMNIA_StayExport__ExportStorageConnectionString: disk://path=/SomniaGuestLog/StayExportFiles
# Somnia StayExport - SpainParteViajeros Provider - START
# Override vars if required
# SOMNIA_StayExportSpainParteViajeros__InternetAvailable: true
# SOMNIA_StayExportSpainParteViajeros__CodigoEstablecimiento: 123123123
# Somnia StayExport - SpainParteViajeros Provider - END
# Enable for HTTPS - START
# ASPNETCORE_URLS: "https://+:8090;http://+:8080"
# ASPNETCORE_HTTPS_PORTS: 8090
# ASPNETCORE_Kestrel__Certificates__Default__Password: ${CERTIFICATE_CREDENTIAL:-}
# ASPNETCORE_Kestrel__Certificates__Default__Path: /https/aspnetapp.pfx
# Enable for HTTPS - END
image: localhost/somnia-guestlog:latest
# image: gitea.uberelectronnetwork.cc/somnia/somnia-guestlog:devbuild
ports:
- protocol: tcp
published: 8080
target: 8080
# Enable for HTTPS
# - protocol: tcp
# published: 8090
# target: 8090
restart: unless-stopped
volumes:
- somniaguestlog_app_data:/SomniaGuestLog
# Enable for HTTPS and configure path to your certificate.
# - ${HOME}/.aspnet/https:/https/
volumes:
somniaguestlog_database_data: Null
somniaguestlog_app_data: Null
+29
View File
@@ -1,5 +1,7 @@
using FluentStorage; using FluentStorage;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -23,6 +25,7 @@ var builder = WebApplication.CreateBuilder(args);
//Load config files. //Load config files.
builder.Configuration.AddJsonFile("Config/log_Config.json", optional: false, reloadOnChange: false); builder.Configuration.AddJsonFile("Config/log_Config.json", optional: false, reloadOnChange: false);
builder.Configuration.AddEnvironmentVariables("SOMNIA_");
//Create and configure Logger (Serilog) //Create and configure Logger (Serilog)
var serilog = new LoggerConfiguration() var serilog = new LoggerConfiguration()
@@ -34,6 +37,19 @@ var logger = new SerilogLoggerFactory(serilog).CreateLogger<Program>();
logger.LogInformation("\n\n\n -------------- Starting {appName} {appVersion} --------------", AppSettings.AppName, AppSettings.AppVersion); logger.LogInformation("\n\n\n -------------- Starting {appName} {appVersion} --------------", AppSettings.AppName, AppSettings.AppVersion);
if (!builder.Environment.IsDevelopment())
{
string dataProtectionPath = builder.Configuration.GetValue<string>("DataProtectionDir", defaultValue: "/SomniaGuestLog/dataprotection");
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(dataProtectionPath))
.SetApplicationName("SomniaGuestLog");
}
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
});
var connectionStringGuestLog = builder.Configuration.GetConnectionString("DbSomniaGuestLog") var connectionStringGuestLog = builder.Configuration.GetConnectionString("DbSomniaGuestLog")
?? throw new InvalidOperationException("Connection string 'DbSomniaGuestLog' not found."); ?? throw new InvalidOperationException("Connection string 'DbSomniaGuestLog' not found.");
@@ -102,6 +118,8 @@ builder.Services.AddOptions<StayExportSpainParteViajerosConfig>()
var app = builder.Build(); var app = builder.Build();
app.UseForwardedHeaders();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {
@@ -136,4 +154,15 @@ app.MapRazorComponents<App>()
//Activate S3 storage. //Activate S3 storage.
AwsS3Storage.Use(); AwsS3Storage.Use();
//Run database migrations
bool runMigrationsOnStartup = builder.Configuration.GetValue<bool>("RunDatabaseMigrationOnStartup", defaultValue: true);
if (runMigrationsOnStartup)
{
logger.LogInformation("Running database migrations...");
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<GuestLogContext>();
await db.Database.MigrateAsync();
logger.LogInformation("Database migrations OK");
}
app.Run(); app.Run();
@@ -7,6 +7,11 @@
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException> <BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<PublishProfile>DefaultContainer</PublishProfile>
<ContainerImageFormat>OCI</ContainerImageFormat>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentStorage" /> <PackageReference Include="FluentStorage" />
<PackageReference Include="FluentStorage.AWS" /> <PackageReference Include="FluentStorage.AWS" />
@@ -4,5 +4,6 @@
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
} },
"RunDatabaseMigrationOnStartup": false
} }
+2
View File
@@ -2,6 +2,8 @@
"ConnectionStrings": { "ConnectionStrings": {
"DbSomniaGuestLog": "Host=localhost;Port=5432;Username=postgres;Password=P@ssw0rd;Database=SomniaGuestLog" "DbSomniaGuestLog": "Host=localhost;Port=5432;Username=postgres;Password=P@ssw0rd;Database=SomniaGuestLog"
}, },
"RunDatabaseMigrationOnStartup": true,
"DataProtectionDir": "/SomniaGuestLog/dataprotection",
"AllowedHosts": "*", "AllowedHosts": "*",
"AddressQuery": { "AddressQuery": {
"EnableAddressQuery": true, "EnableAddressQuery": true,