Modules/businessdev.ALbuild.Containers/Public/Publish-BcContainerToTraefik.ps1

function Publish-BcContainerToTraefik {
    <#
    .SYNOPSIS
        Produces a Traefik v3 dynamic configuration that routes traffic to a BC container.
 
    .DESCRIPTION
        Generates a Traefik v3 file-provider dynamic configuration for the container in one of two
        routing modes - Subdomain (<name>.<domain>) or PathPrefix (<domain>/<name>, with a
        strip-prefix middleware). The configuration object is returned and, when -OutputPath is
        given, written as JSON for Traefik's file provider to pick up (no container recreation
        required).
 
    .PARAMETER Name
        Container name (and the subdomain/path segment).
 
    .PARAMETER Domain
        Base domain (e.g. businesscentral.example.com).
 
    .PARAMETER Routing
        Subdomain or PathPrefix.
 
    .PARAMETER BackendHost
        Backend host Traefik forwards to. Default: the container name (Docker network DNS).
 
    .PARAMETER Port
        Backend port. Default 80.
 
    .PARAMETER Scheme
        Backend scheme (http/https). Default http.
 
    .PARAMETER EntryPoint
        Traefik entry point. Default 'websecure'.
 
    .PARAMETER CertResolver
        Traefik certificate resolver. Default 'letsencrypt'.
 
    .PARAMETER OutputPath
        Optional path to write the dynamic configuration JSON to.
 
    .EXAMPLE
        Publish-BcContainerToTraefik -Name bld -Domain bc.example.com -Routing Subdomain -OutputPath /etc/traefik/dynamic/bld.json
 
    .OUTPUTS
        Hashtable (the Traefik dynamic configuration).
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([hashtable])]
    param(
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [Alias('ContainerName')] [string] $Name,
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Domain,
        [Parameter(Mandatory)] [ValidateSet('Subdomain', 'PathPrefix')] [string] $Routing,
        [string] $BackendHost,
        [int] $Port = 80,
        [string] $Scheme = 'http',
        [string] $EntryPoint = 'websecure',
        [string] $CertResolver = 'letsencrypt',
        [string] $OutputPath
    )

    if (-not $BackendHost) { $BackendHost = $Name }

    $config = Get-BcTraefikConfig -ContainerName $Name -Domain $Domain -Routing $Routing `
        -BackendHost $BackendHost -Port $Port -Scheme $Scheme -EntryPoint $EntryPoint -CertResolver $CertResolver

    if ($OutputPath) {
        if ($PSCmdlet.ShouldProcess($OutputPath, 'Write Traefik dynamic configuration')) {
            $dir = Split-Path -Path $OutputPath -Parent
            if ($dir -and -not (Test-Path -LiteralPath $dir)) {
                New-Item -Path $dir -ItemType Directory -Force | Out-Null
            }
            ($config | ConvertTo-Json -Depth 20) | Set-Content -LiteralPath $OutputPath -Encoding UTF8
            Write-ALbuildLog -Level Success "Wrote Traefik configuration for '$Name' ($Routing) to '$OutputPath'."
        }
    }

    return $config
}