I’m creating a docker-compose file to be able to access different containers over an IP on my machine. My Docker compose file is the following:
version: '3.7'
services:
apache-php8:
build: ./apache-php8
volumes:
- ../webphp8:/var/www/html/web
ports:
- 80:80
networks:
web_net:
ipv4_address: 192.168.100.4
mysql:
image: mysql:5.7
restart: always
volumes:
- ../data:/var/lib/mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
networks:
web_net:
ipv4_address: 192.168.100.3
networks:
web_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 192.168.100.0/24
gateway: 192.168.100.1
I’d expect being able to acces the code on the machine on the 192.168.100.4, as that is the IP that I defined for the server, however, I only access to it in the 0.0.0.0 IP. I’m in an Ubuntu host machine, if that matters.
Do you know why is that, and what I have to do to change it to access the server on 192.168.100.4?
2
Answers
When you define ports in a docker compose file like:
It binds the container’s port 80 to the host’s port 80 on all available interfaces, which typically includes
127.0.0.1
(localhost) and0.0.0.0
(all IP addresses on the local machine).That is why you are able to access your services via
0.0.0.0
orlocalhost
.However, docker does not bind container IPs to the host system directly. IP addresses assigned within a docker compose file via
ipv4_adresses
are internal. to the docker bridge network (web_net
in this case) and not exposed to the host network interface directly.If you really want to access the container using
192.168.100.4
from your host machine, there are a few things you can do:/etc/hosts
file that maps192.168.100.4
back tolocalhost
.Containers within Docker have their own virtual network within your host machine (i.e., the physical laptop or desktop you are using). Within this virtual network, the containers (
mysql
andapache-php8
) talk to each other using the IP addresses you defined (the192.168.100.0/24
subnet). Therefore themysql
container (and any other container you create in the cluster) will reachapache-php8
via either the IP address (192.168.100.4
) or theapache-php8
hostname. These192.168.100.#
IP addresses are not available to you from the host machine, but must be exposed.Exposing your
apache-php8
container’s ports are accomplished as you have already done (ports: - 80:80
), and that allows you to accessapache-php8
port 80 via your laptop’slocalhost
hostname or127.0.0.1
loopback IP address. If you wish to accessapache-php8
via the192.168.100.4
IP address, you would need to first get into a container on that virtual network and then connect to192.168.100.4
as needed (though there are not many human/practical uses for that — it’s generally so that containers/services can talk to each other in the network)On a side note, I have seen instances where a web service (or some other service) was started up in a container, but only listening on
127.0.0.1
or the container IP address. If this is the case, only the container itself (127.0.0.1
) or other containers with access to the virtual network (192.168.100.*
) could talk to that service. The only way to make it available to the host machine is by starting the application/service (Apache, MySQL, etc.) with listen on'*'
or0.0.0.0
, which allows incoming traffic to all of that container’s network addresses.