microsoft / navcontainerhelper

Official Microsoft repository for BcContainerHelper, a PowerShell module, which makes it easier to work with Business Central Containers on Docker.
MIT License
379 stars 243 forks source link

Suggestion: Parameter -clickonce doesn't work on New-NavContainer with traefik #1833

Closed DanielGoehler closed 3 years ago

DanielGoehler commented 3 years ago

Describe the issue The tcp ports of the service tier client service and sql server are not accessible from outside the docker host. As far as I can tell, traefik seems to have been unable to forward tcp ports to enable this. The urls in the manifest files (Finsql.application and Microsoft.Dynamics.Nav.Client.application) are incorrect, so downloading the apps doesn't work and it doesn't makes any sense since you can't connect anyway.

My suggestion is to add a warning after "ClickOnce Manifest: ...": ClickOnce apps do not work in combination with traefik.

Scripts used to create container and cause the issue

New-NavContainer -accept_eula -containername mydocker -artifactUrl "https://bcartifacts.azureedge.net/onprem/14.17.44663.0/de" -useTraefik -shortcuts None -auth NavUserPassword -Credential $credential -enableSymbolLoading -assignPremiumPlan -clickonce

Full output of scripts

BcContainerHelper is version 2.0.7
BcContainerHelper is running as administrator
Host is Microsoft Windows Server 2019 Standard - ltsc2019
Docker Client Version is 19.03.5
Docker Server Version is 19.03.5
Removing container mydocker
Removing C:\ProgramData\BcContainerHelper\Extensions\mydocker
Fetching all docker images
Fetching all docker volumes
Enabling SSL as otherwise all clients will see mixed HTTP / HTTPS request, which will cause problems e.g. on the mobile and modern windows clients
Using image mcr.microsoft.com/businesscentral:10.0.17763.1817
PublicDnsName is dockerhub.company.com
Creating Container mydocker
Version: 14.17.44663.0-de
Style: onprem
Multitenant: No
Platform: 14.0.44656.0
Generic Tag: 1.0.1.4
Container OS Version: 10.0.17763.1817 (ltsc2019)
Host OS Version: 10.0.17763.1817 (ltsc2019)
Using process isolation
Using locale de-DE
Adding special CheckHealth.ps1 to enable Traefik support
Disabling the standard eventlog dump to container log every 2 seconds (use -dumpEventLog to enable)
Using license file C:\Files\dockerLicenseFiles\dev.flf
Additional Parameters:
--volume C:\Files\dockerBakFiles\:c:\bak
--volume C:\Files\dockerAddIns:c:\addins
--hostname docker
-e webserverinstance=mydocker
-e publicdnsname=dockerhub.company.com
-l "traefik.protocol=https"
-l "traefik.web.frontend.rule=PathPrefix:/mydocker"
-l "traefik.web.port=443"
-l "traefik.soap.frontend.rule=PathPrefix:/mydockersoap;ReplacePathRegex: ^/mydockersoap(.*) /NAV$1"
-l "traefik.soap.port=7047"
-l "traefik.rest.frontend.rule=PathPrefix:/mydockerrest;ReplacePathRegex: ^/mydockerrest(.*) /NAV$1"
-l "traefik.rest.port=7048"
-l "traefik.dev.frontend.rule=PathPrefix:/mydockerdev;ReplacePathRegex: ^/mydockerdev(.*) /NAV$1"
-l "traefik.dev.port=7049"
-l "traefik.snap.frontend.rule=PathPrefix:/mydockersnap;ReplacePathRegex: ^/mydockersnap(.*) /NAV$1"
-l "traefik.snap.port=7083"
-l "traefik.dl.frontend.rule=PathPrefixStrip:/mydockerdl"
-l "traefik.dl.port=8080"
-l "traefik.dl.protocol=http"
-l "traefik.enable=true"
-l "traefik.frontend.entryPoints=https"
--env customNavSettings=PublicODataBaseUrl=https://dockerhub.company.com/mydockerrest/odata,PublicSOAPBaseUrl=https://dockerhub.company.com/mydockersoap/ws,PublicWebBaseUrl=https://dockerhub.company.com/mydocker
Files in C:\ProgramData\BcContainerHelper\Extensions\mydocker\my:
- AdditionalOutput.ps1
- CheckHealth.ps1
- license.flf
- MainLoop.ps1
- prismaSSL2020.PFX
- SetupCertificate.ps1
- SetupNavUsers.ps1
- SetupVariables.ps1
- updatecontainerhosts.ps1
Creating container mydocker from image mcr.microsoft.com/businesscentral:10.0.17763.1817
7767086ff91066da07efa99d59a6c6f1f0210f3ec795268bd7e7dde5b989958c
Waiting for container mydocker to be ready
Using artifactUrl https://bcartifacts.azureedge.net/onprem/14.17.44663.0/de
Using installer from C:\Run\130
Copying Platform Artifacts
Copying Application Artifacts
Copying Database
Copying Installers
Copying TestToolKit
Copying UpgradeToolKit
Copying Extensions
Installing Business Central
Installing Url Rewrite
Installing OpenXML
Installing DotNetCore
Starting Local SQL Server
Starting Internet Information Server
Copying Service Tier Files
Copying Web Client Files
Copying Windows Client Files
Copying PowerShell Scripts
Copying ConfigurationPackages
Copying Test Assemblies
Copying TestToolKit
Copying UpgradeToolKit
Copying Extensions
Copying ClientUserSettings
Copying ReportBuilder
Restoring CRONUS Demo Database
Determining Database Collation
Changing Database Server Collation to Latin1_General_100_CI_AS
Restoring CRONUS Demo Database
Installing C:\NAVDVD\Installers\DE\RTC\RoleTailoredClient.Local.De.msi
Skipping C:\NAVDVD\Installers\DE\WebHelp\WebHelp.Local.De.msi
Modifying Business Central Service Tier Config File for Docker
Creating Business Central Service Tier
Installing SIP crypto provider: 'C:\Windows\System32\NavSip.dll'
Installation took 120 seconds
Installation complete
Initializing...
Setting host.containerhelper.internal to 172.29.208.1 in container hosts file
Starting Container
Hostname is docker
PublicDnsName is dockerhub.company.com
Using NavUserPassword Authentication
Certificate File Thumbprint 6ACA6C1529F27493A8915CD0215D9DA9339EB27E
Import Certificate to LocalMachine\my
Modifying Service Tier Config File with Instance Specific Settings
Modifying Service Tier Config File with settings from environment variable
Setting PublicODataBaseUrl to https://dockerhub.company.com/mydockerrest/odata
Setting PublicSOAPBaseUrl to https://dockerhub.company.com/mydockersoap/ws
Setting PublicWebBaseUrl to https://dockerhub.company.com/mydocker
Starting Service Tier
Registering event sources
Creating DotNetCore Web Server Instance
WARNING: SetupWebClient failed, retrying...
Registering event sources
Creating DotNetCore Web Server Instance
Using license file 'c:\run\my\license.flf'
Import License
Creating http download site
Setting SA Password and enabling SA
Creating admin as SQL User and add to sysadmin
Creating SUPER user
Assign Premium plan for ADMIN
Creating ClickOnce Manifest
Container IP Address: 172.29.219.215
Container Hostname  : docker
Container Dns Name  : dockerhub.company.com
Web Client          : https://dockerhub.company.com/mydocker/
Dev. Server         : https://dockerhub.company.com
Dev. ServerInstance : NAV
ClickOnce Manifest  : http://dockerhub.company.com:8080/NAV

Files:
http://dockerhub.company.com:8080/ALLanguage.vsix

Container Total Physical Memory is 255.9Gb
Container Free Physical Memory is 210.5Gb

Initialization took 114 seconds
Ready for connections!
Reading CustomSettings.config from mydocker
Set SQL Server memory limit to 1024 MB
Container mydocker successfully created
Because of Traefik, the following URLs need to be used when accessing the container from outside your Docker host:
Web Client:        https://dockerhub.company.com/mydocker
SOAP WebServices:  https://dockerhub.company.com/mydockersoap
OData WebServices: https://dockerhub.company.com/mydockerrest
Dev Service:       https://dockerhub.company.com/mydockerdev
Snapshot Service:  https://dockerhub.company.com/mydockersnap
File downloads:    https://dockerhub.company.com/mydockerdl

Use:
Get-BcContainerEventLog -containerName mydocker to retrieve a snapshot of the event log from the container
Get-BcContainerDebugInfo -containerName mydocker to get debug information about the container
Enter-BcContainer -containerName mydocker to open a PowerShell prompt inside the container
Remove-BcContainer -containerName mydocker to remove the container again
docker logs mydocker to retrieve information about URL's again
...
freddydk commented 3 years ago

Correct - as Windows Client doesn't work through traefik, I never bothered to do anything about this.

freddydk commented 3 years ago

Ahh - I saw you suggested to add a warning - I can do that, yes

jonaswre commented 3 years ago

Correct - as Windows Client doesn't work through traefik, I never bothered to do anything about this.

I've tried that before, and must say its not really worth the trouble. You will need to rewrite the whole click once generation. With that you can get the windows client working, but for CSide thats a whole another story. You will need to open up 1433 since the finsql.exe needs direct access to the sql server.

And i think there was even a problem with the traefik version used in the container.

You might find Issue #825 interesting.

DanielGoehler commented 3 years ago

Hi @jonaswre, how did you access the windows client service port 7046 from outside the host? There is no traefik rule for that?

jonaswre commented 3 years ago

@DanielGoehler thats where the trouble begins...

You will need to upgrade traefik to atleast 2.0. I think last time i looked into it there was no docker image for windows in the right verion. (There ist now) [traefik:v2.4-windowsservercore-1809]

The problem is that traefik before version 2 only allows you to route http packages. But since 7046 and 1433 dont use http those will never be reachable over traefik 1.7.

In traefik 2 you can create a tcp router which uses a wildcard domain to route to the right container. So instead of example.com/demo your container would be accessible over demo.example.com. With that your packages dont need to be multiplexed over port 443 but can use all their native ports.

Last time i've had to setup it up manually... (Traefik container and rules)

If guess if one could update the traefik version to the new docker image. That would be a good step in the right direction. Then one would need to get a hook into the new-bccontainer script to be able to create your own rules on container creation.

A easy workaround for your problem would just to find a free tcp port, on the host, when creating the container and then use that as service tier port and open it in the firewall, not a pretty solution but could be automated as well and would be way easier and if you provide the click once you wouldn't need to know these ports.

... And you need to set PublishPorts switch https://github.com/microsoft/navcontainerhelper/blob/0758393e2b222ab1c2e1e5329760c2a3f6721df1/ContainerHandling/New-NavContainer.ps1#L135

DanielGoehler commented 3 years ago

Hi @jonaswre, thanks! I look into that.

freddydk commented 3 years ago

Shipped in 2.0.9