I had recently written about the usage of traefik as reverse proxy for multiple Business Central containers on an Azure VM. While I tried to make that setup quite easy, as always there was room for improvement. With the help of Freddy Kristiansen I therefore implemented two additions to navcontainerhelper and the NAV ARM templates (the technology driving https://aka.ms/getbc and similar offerings) which Freddy was kind enough to accept.
When you use one of the ARM templates, you now have a switch „use Traefik“. If you enable that and also provide a Let’s encrypt contact email, the VM will automatically be set up with the necessary config files and also run traefik in a container.
The second part is navcontainerhelper which now also has a switch -useTraefik. When that is used, the labels needed for traefik are automatically added when your container is started. You just do the same as always and add -useTraefik, e.g. New-NavContainer -accept_eula -containerName imau -imageName mcr.microsoft.com/businesscentral/onprem:de -useTraefik
. The output will let you know how to reach your traefik endpoints, e.g. as follows:
Host is Microsoft Windows Server 2019 Datacenter - ltsc2019 Docker Client Version is 18.09.4 Docker Server Version is 18.09.4 Using image mcr.microsoft.com/businesscentral/onprem:de-ltsc2019 PublicDnsName is traef-test10.westeurope.cloudapp.azure.com Creating Nav container imau ... Nav container imau successfully created Because of Traefik, the following URLs need to be used when accessing the container from outside your Docker host: Web Client: https://traef-test10.westeurope.cloudapp.azure.com/imau/ SOAP WebServices: https://traef-test10.westeurope.cloudapp.azure.com/imausoap OData WebServices: https://traef-test10.westeurope.cloudapp.azure.com/imaurest Dev Service: https://traef-test10.westeurope.cloudapp.azure.com/imaudev File downloads: https://traef-test10.westeurope.cloudapp.azure.com/imaudl
I have explained the workings of traefik together with Business Central already in the blog post mentioned above and the mechanism used now is exactly the same. Check the New-NavContainer implementation here and here for the main parts of the actual code, but it should work straight forward. Still, there are a couple of things to note:
Just kidding, of course you can also try this at home, i.e. on premise. It works the same with one exception: In the configuration provided through navcontainerhelper, traefik will try to get an SSL certificate from Let’s Encrypt. That means that your Docker host needs to be accessible from the internet with the same public DNS name and traefik needs to own port 80. If that is the case, you can just do the exact same thing on premise: First call Setup-TraefikContainerForNavContainers once and then call New-NavContainer with -useTraefik every time you need a new container.
If your host is not reachable from the internet with the same name or port 80 can’t be used by traefik, you can use your own certificate (publicly valid or self-signed). The first step also is Setup-TraefikContainerForNavContainers. Assuming that my host is called t00-dev-tfe05.axians-infoma.de, the command is something like the following. Note that I am not giving it a valid email address as Let’s Encrypt won’t work anyways.
Setup-TraefikContainerForBCContainers -PublicDnsName t00-dev-tfe05.axians-infoma.de -ContactEMailForLetsEncrypt noneed
If you check the logs of the traefik container afterwards, you will see something like this as is to be expected:
2019/05/31 12:46:29 Using high precision timer time="2019-05-31T12:46:33+02:00" level=error msg="Unable to obtain ACME certificate for domains \"t00-dev-tfe05.axians-infoma.de\" : cannot get ACME client acme: error: 400 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-acct :: urn:ietf:params:acme:error:invalidEmail :: Error creating new account :: not a valid e-mail address, url: "
I assume that you have a valid certificate called traefik.crt and a key file traefik.key for the public DNS name of your Docker host. To use them, you need to do the following:
[entryPoints.https.tls] [[entryPoints.https.tls.certificates]] certFile = "c:/etc/traefik/traefik.crt" keyFile = "c:/etc/traefik/traefik.key"
With that in place, the traefik.toml file should look similar to this:
debug = false defaultEntryPoints = ["https","http"] [web] address = ":8080" [docker] domain = "t00-dev-tfe05.axians-infoma.de" watch = true endpoint = "npipe:////./pipe/docker_engine" [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [[entryPoints.https.tls.certificates]] certFile = "c:/etc/traefik/traefik.crt" keyFile = "c:/etc/traefik/traefik.key"
2019/05/31 12:54:07 Using high precision timer
With that in place, the traefik endpoints should just work as expected