Setting Hostname in Docker Compose
Wondering how to set hostname in Docker Compose? I'll show you that.
You may define it under the service like this:
...
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
hostname: ledocker
...
But do you really need that? The general goal of the hostname is that computers on the network know each other and thus communicate between themselves.
Similarly, the main goal here is to ensure that containers can communicate with each other successfully within a Docker network.
I'm going to discuss two ways on how to make this possible:
Method 1: Non-explicit Communication
Within a Docker network, service names defined within a Docker Compose file can be used to test whether containers can communicate with each other.
Take for example the following reverse proxy config:
version: '3.7'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/usr/share/nginx/html
- ./dhparam:/etc/nginx/dhparam
- ./vhost:/etc/nginx/vhost.d
- ./certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./client_max_upload_size.conf:/etc/nginx/conf.d/client_max_upload_size.conf
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
restart: always
networks:
- net
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./letsencrypt.env
depends_on:
- nginx-proxy
volumes:
- ./certs:/etc/nginx/certs:rw
- ./vhost:/etc/nginx/vhost.d
- ./html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
networks:
- net
networks:
net:
external: true
Note that the two service names are nginx-proxy
and letsencrypt
. You can use these names to test whether containers can communicate with each other or not. This can become very helpful during troubleshooting situations.
First, install ping inside the Nginx Reverse Proxy container:
avimanyu@iborg-desktop:~/nginx-proxy$ docker-compose exec nginx-proxy bash -c "apt update && apt install -y iputils-ping"
Now, you can use the ping command inside this container to check whether it can communicate with the Let's Encrypt Container (used for SSL).
avimanyu@iborg-desktop:~/nginx-proxy$ sudo docker-compose exec nginx-proxy ping letsencrypt
PING letsencrypt (172.18.0.3) 56(84) bytes of data.
64 bytes from nginx-proxy_letsencrypt_1.net (172.18.0.3): icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from nginx-proxy_letsencrypt_1.net (172.18.0.3): icmp_seq=2 ttl=64 time=0.057 ms
^C
--- letsencrypt ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 37ms
As you can see above, the reverse proxy container "sees" the second SSL container that sends a response back! In nginx-proxy_letsencrypt_1.net
, nginx-proxy_letsencrypt_1
is the SSL container name and net
is our custom network.
Let's quickly verify it:
avimanyu@iborg-desktop:~/nginx-proxy$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9ef56e22f58 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 7 minutes ago Up 7 minutes nginx-proxy_letsencrypt_1
563133f5d039 jwilder/nginx-proxy "/app/docker-entrypo…" 7 minutes ago Up 7 minutes nginx-proxy_nginx-proxy_1
To verify the network, you can use the docker network ls
command.
avimanyu@iborg-desktop:~/nginx-proxy$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
018c50dc4fdc bridge bridge local
27fd2370e735 net bridge local
38ce8d11227b host host local
2440210d0fc5 none null local
Method 2: Explicit Communication
Say, for some reason, you want to explicitly specify a hostname to a container. Docker Compose lets you do that too!
Using the hostname
configuration option, you can set a different hostname to any service defined within a Docker Compose file, as I have done for the Let's Encrypt service below:
version: '3.7'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/usr/share/nginx/html
- ./dhparam:/etc/nginx/dhparam
- ./vhost:/etc/nginx/vhost.d
- ./certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./client_max_upload_size.conf:/etc/nginx/conf.d/client_max_upload_size.conf
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
restart: always
networks:
- net
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
hostname: ledocker
env_file:
- ./letsencrypt.env
depends_on:
- nginx-proxy
volumes:
- ./certs:/etc/nginx/certs:rw
- ./vhost:/etc/nginx/vhost.d
- ./html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
networks:
- net
networks:
net:
external: true
Here, note that I have explicitly added hostname: ledocker
inside the Let's Encrypt service definition. I want to use ledocker
as the hostname for the SSL container.
But wait, can we recheck again using the ping command?
avimanyu@iborg-desktop:~/nextcloud$ sudo docker-compose exec nginx-proxy ping ledocker
PING ledocker (172.18.0.3) 56(84) bytes of data.
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=2 ttl=64 time=0.079 ms
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=3 ttl=64 time=0.061 ms
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=4 ttl=64 time=0.093 ms
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=5 ttl=64 time=0.078 ms
64 bytes from nginx-proxy_nginx-proxy_1.net (172.18.0.3): icmp_seq=6 ttl=64 time=0.075 ms
^C
--- ledocker ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 129ms
rtt min/avg/max/mdev = 0.034/0.070/0.093/0.018 ms
Indeed, yes. It works!
Hungry for more knowledge in this regard? Check out this extremely informative GitHub thread.
Hope you enjoyed this quick tip! You can leave any queries, doubts or suggestions in the comment section below.