2 Vaadin Apps 1 Traefik
The goal is to setup 2 Vaadin apps on one Ubuntu machine:
- 2 Vaadin apps are running in production mode in docker
- Configure Traefik as ‘reverse proxy’ so that the apps are accessible via
http://app1.myserver.fake
andhttp://app2.myserver.fake
Note: you can alternatively configure the Vaadin apps to run on
/app1
context root, then you can also publish the app at, say,http://myserver.fake/app1
.
Note: you might be tempted to try to configure path rewriting, to have the apps serving
/
context root to be published athttp://myserver.fake/app1
andhttp://myserver.fake/app2
, respectively. It’s not a good idea: see StackOverflow answer for details. In short, I don’t think this is possible (e.g. https://community.traefik.io/t/traefik-2-reverse-proxy-to-a-path/8623/12 ), and also I don’t think it’s a good idea. Remember that you would need to rewrite all links in the response html files; possibly session cookie paths. Rewriting response html is most probably not a good idea since it might not be possible to do so reliably (see Jenkins behind reverse proxy for more details).
Traefik Setup
I assume that docker is installed & configured on your machine. To run Traefik quickly, we’ll just run it according to
Traefik Quick Start. Create a docker-compose.yml
:
version: '3'
networks:
web:
external: true
services:
traefik:
# The official v3 Traefik docker image
image: traefik:v3.1
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
networks:
- web
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
Create a shared docker network named web
, which will be used by Traefik to access your Vaadin apps:
$ docker network create web
To start Traefik:
$ docker-compose up -d
Now browse to localhost and check that you can see the Traefik dashboard.
Faking the DNS addresses
Edit /etc/hosts
and add the following line to the end:
127.0.0.1 app1.myserver.fake app2.myserver.fake
Now when browsing to http://app1.myserver.fake
, the browser will report the hostname as app1.myserver.fake
,
exactly as if the DNS name was provided by an actual DNS server. We can take advantage of this,
to test as if on a real environment.
Alternatively setup a wildcard DNS rules.
Setting up Vaadin apps
We’ll run two Vaadin apps from docker: vaadin-boot-example-gradle and beverage-buddy-vok. To build docker images out of those apps, run the following in your terminal:
git clone https://github.com/mvysny/vaadin-boot-example-gradle
cd vaadin-boot-example-gradle
docker build --no-cache -t test/vaadin-boot-example-gradle:latest .
and
git clone https://github.com/mvysny/beverage-buddy-vok
cd beverage-buddy-vok
docker build --no-cache -t test/beverage-buddy-vok:latest .
Now, create a file named vaadin-boot-example-gradle.docker-compose.yml
:
version: '3'
networks:
web:
external: true
services:
vaadin-boot-example-gradle:
image: test/vaadin-boot-example-gradle
networks:
- web
labels:
- "traefik.http.routers.vaadin-boot-example-gradle.entrypoints=http"
- "traefik.http.routers.vaadin-boot-example-gradle.rule=Host(`app1.myserver.fake`)"
Now, create a file named beverage-buddy-vok.docker-compose.yml
:
version: '3'
networks:
web:
external: true
services:
vaadin-boot-example-gradle:
image: test/beverage-buddy-vok
networks:
- web
labels:
- "traefik.http.routers.vaadin-boot-example-gradle.entrypoints=http"
- "traefik.http.routers.vaadin-boot-example-gradle.rule=Host(`app2.myserver.fake`)"
Run them:
$ docker-compose up -d -f vaadin-boot-example-gradle.docker-compose.yml
$ docker-compose up -d -f beverage-buddy-vok.docker-compose.yml
Traefik will automatically discover those docker containers and will setup proper routing - you can check out Traefik’s Dashboard to see that.
Verify that you can access those apps: app1.myserver.fake and app2.myserver.fake.
https via Let’s Encrypt
To enable https with Let’s Encrypt, you obviously have to set up Traefik on an actual server running somewhere in the internet; then you have to register a bunch of domains and make them point to the IP address where the server is running.
See Traefik: Let’s Encrypt documentation.
Also see DigitalOcean documentation on Traefik.
You do not have to have any account at Let’s Encrypt: the only requirement is to own the DNS domain and to have it pointing to the server’s IP.
DNS Wildcard mode
It’s possible to set up your DNS record to handle wildcard requests, e.g. having your Traefik handle
http://*.yourdomain.com
. For this to work, you need two things:
- Enable wildcard support with your DNS provider. E.g. with GoDaddy, click on the domain, then “Manage Domain”,
the “DNS” tab, then “Add New Record”: Type: A, Name:
*
(an asterisk), Data: the IP address of your server. Hit save - the change will eventually propagate through all DNS servers and you’ll be able toping foo.yourdomain.com
. - Configure Traefik’s Let’s Encrypt integration for a proper wildcard support
https with DNS wildcard is tricky: Let’s Encrypt only supports the DNS-01 challenge type when verifying wildcard DNS. In short, the ACME client needs to briefly add a specific TXT record to your DNS entry. In order to do that, the ACME client needs to go to where your DNS is registered, and temporarily modify the DNS record. In other words, with Traefik:
- You need to use dnsChallenge
- You need to let Traefik know which provider you use, and configure proper access.
Here’s an example of GoDaddy integration.