Docker Community Forums

Share and learn in the Docker community.

How to communicate from one PHP container to another

I am new to docker. I would like to create a webapplication that contains of microservices.
To start and experiment, I have created an nginx container, 2 php containers and a mysql container.

The nginx container is accessible from the host on port 8080.
Both php containers are exposed on port 9000 which is only accessible from within the docker network.
All 4 containers are connected to the same docker network.

Now I try to make a call from one php container to the other with the following PHP command:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, “https://rsd_um:9000”);
$output = curl_exec($ch)

The output always returns FALSE.

I have no clue what goes wrong.

If I connect to the db container from the php container, I get connected

$conn = new mysqli(“rsd_db”, “root”, “root_password”, “database”);

Can somebody point me in a direction to what I am doing wrong. Even if my approach to working with these containers is wrong, please let me know.

Thanks.

Use docker-compose to create your services. Then you can use the names of the services as hostnames to connect from one container to another. Notice that you connect to the service itself, not to its published port on the host (for example connect to port 80 for the nginx service).

I have used docker-compose to create the services. They are all in the same docker-compose file. For the mysql container I am able to connect to it with the name of the service.
Also nginx is able to connect to them in the Server Blocks. I have created 2 Server Blocks that are able to connect to the 2 php containers through the name of the service (one on port 8080 and the other one on port 8081).
The only thing that does not work is the communication between the 2 php containers directly.

When I am home this evening, I will post the content of my files. Maybe I did something wrong in there.

Howdy.
What network type are you using? Bulit-in Bridge? or User-Defiend bridge?
To access containers by way of container name, you must attach all your containers to a custom network. Otherwise, the boxes can only be reached by IP address.
Docker networks can be connected to running containers, as well.

Create the user-defined network of bridge type:

docker network create --driver bridge [networkname]

Connect your boxes:

docker network connect [networkname] [containername]

Remove built-in network connection

docker network disconnect bridge [containername]

Check this tut and then try it with your existing boxes:

:whale:

Hi,

My containers are connected to a User-Defined bridge. I will include the files I used to create these containers.

docker-compose.yml:

version: ‘3’
services:

#PHP Services
#============
rsd_um:
build:
context: .
dockerfile: users_module.Dockerfile
container_name: rsd_users_module
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: rsd_um
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- …/…/codebase:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- rsd-network

#----------------------------------------------------------------
rsd_fem:
build:
context: .
dockerfile: frontend_module.Dockerfile
container_name: rsd_frontend_module
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: rsd_fem
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- …/…/codebase:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- rsd-network

#Nginx Service
rsd_web:
image: nginx:alpine
container_name: rsd_webserver
restart: unless-stopped
tty: true
ports:
- “8080:80” #Users Module
- “8081:81” #Frontend Module
- “1443:443”
volumes:
- …/…/codebase:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- rsd-network

#MySQL Service
rsd_db:
image: mysql:5.7.22
container_name: rsd_db
restart: unless-stopped
tty: true
ports:
- “13306:3306”
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: laravel_password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- rsd-db-users:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- rsd-network

#Docker Networks
networks:
rsd-network:
driver: bridge

#Volumes
volumes:
rsd-db-users:
external: true

users_module.Dockerfile & frontend_module.Dockerfile

FROM php:7.3-fpm
COPY composer.lock composer.json /var/www/
WORKDIR /var/www
RUN apt-get update && apt-get install -y
build-essential
mariadb-client
libpng-dev
libjpeg62-turbo-dev
libfreetype6-dev
locales
zip
jpegoptim optipng pngquant gifsicle
vim
unzip
git
curl

RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
&& docker-php-ext-install gd
RUN set -eux; apt-get update; apt-get install -y libzip-dev zlib1g-dev; docker-php-ext-install zip
RUN curl -sS https://getcomposer.org/installer | php – --install-dir=/usr/local/bin --filename=composer
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

COPY . /var/www
COPY --chown=www:www . /var/www
USER www

EXPOSE 9000
CMD [“php-fpm”]

Server Block for rsd_users_module (listen 80) and rsd_frontend_module (listen 81).

server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/rsd-users-module/public;
location ~ .php$ {
try_files uri =404; fastcgi_split_path_info ^(.+\.php)(/.+);
fastcgi_pass rsd_um:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}

I enter the frontend container:

docker exec -it -u root rsd_frontend_module /bin/bash

Run the following command with unexpected result

curl -i rsd_users_module:9000
curl: (56) Recv failure: Connection reset by peer

Maybe someone can spot the mistake I made but I looked for hours and did not find anything.

Thanks to all.

I cite from PHP-FPM on cwiki.apache.org:
“The default pool, [www] , has this configured as listen 127.0.0.1:9000 : it will only respond to requests on the local loopback network interface (localhost), on TCP port 9000”
So you should probably check the config for php-fpm and change the listen address to 0.0.0.0:9000.
I see some more issues with your compose file:

  • If you are in development, use highest available version 2 (2.4 at the moment).
  • Don’t add restart commands. Restarting containers may make it very difficult to find errors.
  • Don’t create a network if you don’t have a very specific reason to do so.
  • Only publish the ports that you need on the frontend.
1 Like

Thanks tekki.

So I have created 3 new containers to try and figure out what could be wrong.
docker-compose.yml

version: ‘2.4’
services:
web:
image: nginx:latest
ports:
- “8080:80”
volumes:
- …/tests:/code
- ./.docker/nginx/conf.d/:/etc/nginx/conf.d
links:
- php1
php1:
build:
context: ./.docker
dockerfile: Dockerfile
volumes:
- …/tests:/code
php2:
build:
context: ./.docker
dockerfile: Dockerfile
volumes:
- …/tests:/code

Dockerfile

FROM php:7.2-fpm
RUN cd /usr/local/etc
&& {
echo ‘[global]’;
echo ‘daemonize = no’;
echo;
echo ‘[www]’;
echo ‘listen = 0.0.0.0:9000’;
} | tee php-fpm.d/zz-docker.conf

site.conf

server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code/public;
location ~ .php$ {
try_files uri =404; fastcgi_split_path_info ^(.+\.php)(/.+);
fastcgi_pass php1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}

I build these 3 containers with

docker-compose up --build -d

If I go to localhost:8080 I get the results of php1:9000, so the container is accessible from the nginx container.
although, If I try to access the container from within container php2, again I get:

curl -i php1:9000
curl: (56) Recv failure: Connection reset by peer

I have tried another configuration where I use 2 php7.3-apache containers and this configuration does not give any errors. These off-course communicate over apache and not directly through the php setup.

Is there a way I can have 1 nginx container with multiple php containers where the php containers are able to communicate with each other?