skip to Main Content

I have a very simple config in docker-compose with php:7-fpm and nginx that I want to use to host simple php websites.

Can someone please tell me what I did wrong?

Here is docker-compose.prod.yml:

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ../nurock/hidden_creste:/code

      - ./site.prod.conf:/etc/nginx/conf.d/default.conf

  php:
    image: php:7-fpm
    volumes:
      - ../nurock/hidden_creste:/code

Here is the site.prod.conf file:

server {
    listen 80;
    index index.php index.html;
    server_name example.com;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /code;

    location ~ .php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+.php)(/.+)$;
            fastcgi_pass php:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
        }
}

I can compose up and the logs appear to be fine and when I run docker ps:

docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                   NAMES
c268a9cf4716   php:7-fpm      "docker-php-entrypoi…"   27 minutes ago   Up 16 seconds   9000/tcp                                example_code-php-1
beaaec39209b   nginx:latest   "/docker-entrypoint.…"   27 minutes ago   Up 16 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   example_code-web-1

Then checking the ports, I think this looks fine:

netstat -tulpn | grep :80
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      204195/docker-proxy 
tcp6       0      0 :::8080                 :::*                    LISTEN      204207/docker-proxy 

2

Answers


    1. You need to expose TCP port 9000 of the PHP container to made other containers able to use it (see What is the difference between docker-compose ports vs expose):
      php:
        image: php:7-fpm
        expose:
          - "9000"
        ...
    
    1. Do you really want your sites to be available on TCP port 8080, not the standard port 80? If not, change "8080:80" to "80:80".
    2. Besides the PHP handler, use a default location (although your site should be workable even without it, it is a bad practice to not add it to your nginx config):
    location / {
        try_files $uri $uri/ =404;
    }
    
    Login or Signup to reply.
  1. You must check the logs to find out the error. https://docs.docker.com/engine/reference/commandline/logs/

    These issues can happen :

    1. A php module is missing
    2. user / permission are not correct. Is www-data defined in your nginx and php-fpm config ?
    3. Use HTTPS and port 443 instead of HTTP and port 80. HTTP may be blocked by your browser. You can define a free SSL certificate with Let’s Encrypt Docker image.
    4. PHP 7.0 is EOL (end or life) since January 10, 2019. Please use PHP 8.0 or PHP 8.1. https://endoflife.date/php
    5. Do not use use tag nginx:latest on production. You may have serious issues when you update your container, because last version will be downloaded.
    6. Do not mount directory on production. Please use COPY in your Dockerfile.
    7. Check the firewall on your server

    Here is Docker Docker best practices : https://docs.docker.com/develop/dev-best-practices/

    https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

    Here, I suggest this docker-compose.prod.yml

    version: '3.8'
    services:
      web:
        image: nginx:1.21
        depends_on:
          - my-php-container-name
        container_name: my-nginx-container-name
        working_dir: /code
        ports:
            - '80:80'
            - '443:443'
        volumes:
          - ../nurock/hidden_creste:/code
          - ./site.prod.conf:/etc/nginx/conf.d/default.conf
        restart: always
    
      php:
        build: php-fpm
        container_name: my-php-container-name
        working_dir: /code
        volumes:
          - ../nurock/hidden_creste:/code
        restart: always
    

    In the same directory as this docker-compose.prod.yml file, create a php-fpm directory: mkdir php-fpm (or directory architecture written under build in docker-compose.prod.yml file.)

    In php-fpm directory, please add this Dockerfile called Dockerfile

    FROM php:8.1-fpm
    COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
    WORKDIR "/code"
    RUN apt-get update && apt-get install -y --no-install-recommends 
            libfreetype6-dev 
            libjpeg62-turbo-dev 
            libpng-dev 
            libicu-dev
        && docker-php-ext-configure gd --with-freetype --with-jpeg 
        && docker-php-ext-install -j$(nproc) gd pdo_mysql bcmath mysqli intl
    

    Of course, add the PHP extensions that you need for your project. Here you have an example how to install gd, pdo_mysql, bcmatch, mysqli, intl. But there are others extension as curl, xml, xdebug, mcrypt, memcache, etc… https://github.com/mlocati/docker-php-extension-installer

    In your nginx configuration, you should define config for HTTPS with port 443. Please also update this line fastcgi_pass php:9000;. Replace php by the container name. Of course, container name must be unique.

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+.php)(/.+)$;
                fastcgi_pass my-php-container-name:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
            }
    

    Then, build your set-up

    docker-compose -f docker-compose.prod.yml build && docker-compose -f docker-compose.prod.yml up
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search