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?
Answer to "Why are you doing it?": I want to be able to develop with two different versions of PHP in the same machine, and access them with two different urls: http://app1.webserver.es and http://app2.webserver.es. I also want a connection to the database that is accessible locally and for the webservers.
The solution for the problem has been changing the approach: instead of using IPs that expose the network, go for a Nginx reverse proxy that manages the incoming traffic from the host to the containers.
I published the code on this repository: https://github.com/Chocofede/lamps-nginx/tree/master
The key parts are:
In the docker-compose.yml
, let's set the configuration to put all the servers are in the same network:
version: '3'
services:
nginx:
image: nginx
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- my_network <<<< Same Network
depends_on:
- web_server1
- web_server2
- mysql_server
web_server1:
[...]
networks:
- my_network <<<< Same Network
depends_on:
- mysql_server
web_server2:
[...]
networks:
- my_network <<<< Same Network
depends_on:
- mysql_server
mysql_server:
[...]
networks:
- my_network <<<< Same Network
volumes:
- ./mysql-data:/var/lib/mysql
networks:
my_network: <<<< Network name
driver: bridge
The trickiest part of this solution was that I wanted all the servers on the 80 port, and being able to access them from a local address. To do so, we have to configure the nginx.conf
file to send the traffic from the hosts to the containers.
worker_processes 1;
events {
worker_connections 1024;
}
http {
[...]
server {
listen 80;
server_name app1.webserver.es; <<<< Address for webserver 1
location / {
proxy_pass http://web_server1;
[...]
}
}
server {
listen 80;
server_name app2.webserver.es; <<<< Address for Webser 2
location / {
proxy_pass http://web_server2;
[...]
}
}
server {
listen 80;
server_name mysql.webserver.es; <<<< Address for MySql
location / {
proxy_pass http://mysql_server;
[...]
}
}
}
That will let the servers listening in their 80 ports without interfering with the 80 port of the host.
In both web servers, I had to configure the server name to allow access:
<VirtualHost *:80>
ServerName app1.webserver.es <<<< The local name
DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
And last, but not least, adding to /etc/hosts
(I'm in Ubuntu) file the addresses to access them locally:
127.0.0.1 app1.webserver.es
127.0.0.1 app2.webserver.es
127.0.0.1 mysql.webserver.es
With that, when launching the server, it gives you a nice
Thanks to all the people that helped me figuring out the answer.