I would like to use Traefik with Docker Swarm, every proxy node gets a Traefik instance with the same common configuration.
To be able to see if all Traefik reverse proxies are available behind the load balancer, I would like every Traefik instance to add their hostname in the response header.
I found the Traefik configuration for headers , but it seems there is no way to access local settings like $HOSTNAME.
So something like this is not possible?
labels:
- "traefik.http.middlewares.testHeader.headers.customresponseheaders.proxy-host=$HOSTNAME"
cakiwi
August 10, 2021, 3:20pm
2
That is not a traefik issue rather a docker one. See this for why and workaround.
opened 02:44PM - 05 Dec 16 UTC
kind/enhancement
area/swarm
area/stack
To test `docker stack deploy --compose-file` function, I load one of my sample `… docker-compose.yml`:
```yaml
version: '3'
services:
nginx:
image: "${DOCKER_USER}/lnmp-nginx:v1.2"
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- "80:80"
networks:
- frontend
depends_on:
- php
php:
image: "${DOCKER_USER}/lnmp-php:v1.2"
build:
context: .
dockerfile: Dockerfile.php
networks:
- frontend
- backend
environment:
MYSQL_PASSWORD: Passw0rd
depends_on:
- mysql
mysql:
image: mysql:5.7
volumes:
- mysql-data:/var/lib/mysql
environment:
TZ: 'Asia/Shanghai'
MYSQL_ROOT_PASSWORD: Passw0rd
command: ['mysqld', '--character-set-server=utf8']
networks:
- backend
volumes:
mysql-data:
networks:
frontend:
backend:
```
In the `image` section of service `nginx` and `php`, I used `${DOCKER_USER}` to get the docker id from environment variables. And if I use `docker-compose up`, it will load `.env` file as default envvar files, which content is:
```bash
DOCKER_USER=twang2218
```
However, if I use `docker stack` to deploy this `docker-compose.yml`, I will got following errors:
```bash
$ docker stack deploy --compose-file docker-compose.yml lnmp
Ignoring unsupported options: build
Creating network lnmp_frontend
Creating network lnmp_backend
Creating network lnmp_default
Creating service lnmp_php
Error response from daemon: rpc error: code = 3 desc = ContainerSpec: "/lnmp-php:v1.2" is not a valid repository/tag
```
As you can see, as `docker stack deploy` command didn't load `.env` file, the `${DOCKER_USER}` was replaced by empty string, which cause image name become invalid.
If `.env` file was loaded, the final image name should be `twang2218/lnmp-php:v1.2`.
The environment substitution is actually working, if I run the command this way:
```bash
$ DOCKER_USER=twang2218 docker stack deploy --compose-file docker-compose.yml lnmp
Ignoring unsupported options: build
Creating network lnmp_frontend
Creating network lnmp_backend
Creating network lnmp_default
Creating service lnmp_mysql
Creating service lnmp_nginx
Creating service lnmp_php
```
And we can verify it's working by `docker service inspect` command:
```bash
$ docker service inspect lnmp_php | grep Image
"Image": "twang2218/lnmp-php:v1.2@sha256:4f1aef1350aeef3f757f6b6da8f2e1a79ff849f61382320e4b668bfe2b0d1c5a",
```
The image name is `twang2218/lnmp-php:v1.2`, which is correct.
I tested this feature on Digtial Ocean droplet, which installed docker 1.13.0-rc2 via `docker-machine`.
Here is the version:
```bash
$ docker version
Client:
Version: 1.13.0-rc2
API version: 1.25
Go version: go1.7.3
Git commit: 1f9b3ef
Built: Wed Nov 23 06:32:39 2016
OS/Arch: linux/amd64
Server:
Version: 1.13.0-rc2
API version: 1.25
Minimum API version: 1.12
Go version: go1.7.3
Git commit: 1f9b3ef
Built: Wed Nov 23 06:32:39 2016
OS/Arch: linux/amd64
Experimental: false
```
Here is the `docker info`:
```bash
root@d1:~/docker-lnmp# docker info
Containers: 7
Running: 1
Paused: 0
Stopped: 6
Images: 4
Server Version: 1.13.0-rc2
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 43
Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: active
NodeID: vyf3mgcj3uonrnh5xxquasp38
Is Manager: true
ClusterID: jb8rxvd6ptrn3psfkiixxed7r
Managers: 1
Nodes: 3
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Node Address: 138.197.195.206
Manager Addresses:
138.197.195.206:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 03e5862ec0d8d3b3f750e19fca3ee367e13c090e
runc version: 51371867a01c467f08af739783b8beafc154c4d7
init version: 949e6fa
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.4.0-51-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 488.5 MiB
Name: d1
ID: E6UB:PHX6:I2KY:Q35T:PCCI:MFDQ:ZMMN:2X7K:DEOZ:PAP7:4BUC:FP6X
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Labels:
provider=digitalocean
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
```
Thanks for your reply.
My understanding is that the link shows how to include ENV when executing docker stack deploy command. That way I can include the management server $HOSTNAME in the docker stack deploy file, but it will be the same on every node the Traefik instance is started.
I am looking for a way the Traefik instance can read it's local ENV and place the local $HOSTNAME
value in the customresponseheaders
header.
cakiwi
August 11, 2021, 1:22am
4
Yes you're correct
I don't think this is possible. Running multiple traefik will be of limited benefit, particularly if you want to use LetsEncrypt.
I have a managed Cloud Load Balancer in front, but it does not support domain-based routing.
The Cloud Load Balancer forwards round-robin plain TCP/IP (80/443) to 3 Traefik instances (for failover).
Those are in a Docker Swarm and do the routing to the registered services on separate nodes.
So if I do multiple requests via LB, it would be interested to see which Traefik instances are involved.
Maybe I just setup the Traefik instances manually, they probably don't need to be scaled up and down.
PS: Letsencrypt is great, but for serious paid business I prefer paid certificates.
cakiwi
August 11, 2021, 1:22pm
6
Really in swarm though you only need one. As the swarm routing mesh will take care of getting it to traefik.
For a more robust solution TraefikEE is the way to go.
While testing with whoami I found that traefik is automatically including its container hostname in the X-Forwarded-Server
header.
And Docker Swarm will set a containers hostname to the nodes hostname when using
--hostname='{{.Node.Hostname}}'
system
Closed
September 12, 2022, 4:27pm
8
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.