We have the following setup:

We host multiple website on an Ubuntu server, most of them running PHP 5.6. One of them, runs inside a Docker container with PHP 7.1.

The nginx conf for this website has the following line:

fastcgi_pass 172.17.0.4:9000;

which points to the IP of the docker container, which we get from

docker inspect <container>|grep IP

The problem is whenever the system restarts, the container gets a new IP assigned and we have to copy it into the nginx conf again and restart nginx. How could we do this automatically?

Thank you!

BR, Peter

  • are the containers running nginx and php two different containers? (as best practice dictates) – Luca Gibelli May 8 at 22:52

Docker creates an entry in /etc/hosts to map the new IP address of the container to its name. Unfortunately nginx ignores /etc/hosts and only relies on its DNS resolver to resolve IPs, so this doesn't help you in this specific case.

There are a few alternative solutions. The two easiest solutions to implement are:

  1. if you are running nginx and php in the same container (you should not), just use 127.0.0.1:9000 in php-fpm and nginx
  2. if you are running nginx and php-fpm in different containers, or if you are running php-fpm inside the container and nginx on the host, add -p 9000:9000 to the php container and then configure nginx container to use fastcgi_pass 172.17.42.1:9000 (or whatever static IP is used by your host docker0 interface)
  3. if you prefer to have static IP addresses, create a separated network and assign a static ip to your php container, e.g.:

    docker network create --subnet=172.18.0.0/16 mynet123

    docker run --net mynet123 --ip 172.18.0.22 -d --rm php-image-name

Cleaner solutions would involve using orchestration solutions, here I'm just going for the quick and dirty way.

  • 1
    Hi! There is only 1 container for PHP. Nginx runs directly on the server, not in a container. I was thinking maybe some kind of hook exists so we can run a bash script when a docker container starts up. – Illes Peter May 9 at 8:16
  • in that case just go with solution #2, it's the easiest. – Luca Gibelli May 9 at 10:46
  • added another option: use static IPs – Luca Gibelli May 9 at 10:53

I would map the container port 9000 to an open port on the host, and you can setup nginx to proxy straight to the host and port. This way it doesn't matter what IP address is assigned to the docker instance.

docker run -p 127.0.0.1:9001:9000

Then you can change the nginx conf:

fastcgi_pass 127.0.0.1:9001;

Are you able to use a socket? You can bypass this issue given...

  • The php-fpm container is listening on a socket
  • You have sudo capabilities to create a directory

I don't know the specifics of your environment, but this should get you on the right track:

[host]# sudo mkdir -p /var/run/my_app/ [host]# docker run -d -v /var/run/my_app:/var/run/php-fpm my_org/my-php-fpm-container

Your container should put a socket under /var/run/php-fpm such as /var/run/php-fpm/php-fpm.sock.

Then in the corresponding nginx config, you can use fastcgi_pass unix:/var/run/my_app/php-fpm.sock;

This allows you to not even expose the port at all.

This works because if you expose an entire directory to docker it doesn't create any files, only the directory. If you put a file into that directory inside the container, it is exposed on the host. Sockets are just special files, so they get exposed the same as anything else. :)

You could technically do the reverse here too, which would be running php-fpm on the host and running nginx in a container (I don't suggest this, though)!

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.