Dockerize PHP Application for Production

In general, both approaches should be avoided in production, but if I compare volume mounting and two processes per container, I will go for two processes per container instead of mounting host code to the container,

There are some cases where the first approach failed, like in the case of Fargate, where there is no host which is a kind of serverless then in this you will definitely go for running two processes per container.

The main issue come with running multiple processes per container is "What if php-fpm is down and the Nginx process is running". but you can handle this case with multiple approach, you can look suggested approach by docker documentation.

docker-multi-service_container

The docker documentation covered this scenario with a custom script or supervisord.

If you need to run more than one service within a container, you can accomplish this in a few different ways.

  • Put all of your commands in a wrapper script, complete with testing and debugging information. Run the wrapper script as your CMD. This is a very naive example. First, the wrapper script:
#!/bin/bash

# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_first_process: $status"
  exit $status
fi

# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_second_process: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds

while sleep 60; do
  ps aux |grep my_first_process |grep -q -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep my_second_process |grep -q -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of the processes has already exited."
    exit 1
  fi
done
  • Use a process manager like supervisord. This is a moderately heavy-weight approach that requires you to package supervisord and its configuration in your image (or base your image on one that includes supervisord), along with the different applications it manages. Then you start supervisord, which manages your processes for you. Here is an example Dockerfile using this approach, that assumes the pre-written supervisord.conf, my_first_process, and my_second_process files all exist in the same directory as your Dockerfile.

But if you are looking for a supervisor you can check shutdown supervisor once one of the programs is killed and other similar approach to monitor the process.