1

I have a Laravel application which I plan to deploy on a Docker Swarm. The problem is that no matter what I do I get a blank page when calling localhost/index.php.

I'm using 2 separate services for:

  1. Laravel App (php-fpm)
  2. Nginx

Some notes which might be helpful to you helping me.

  • The containers don't share anything but a volume for static files
  • I can verify that requests are being received by php-fpm
  • There is no error in any of the logs and all I get is 200 response codes both in my nginx logs and php-fpm
  • Even a simple <?php phpinfo(); yields the same result so it's not a laravel problem

These are the Dockerfiles from which I build my images.

// Dockerfile for `Nginx`
FROM nginx

ADD ./api.conf /etc/nginx/conf.d/

RUN rm /etc/nginx/conf.d/default.conf

CMD ["nginx", "-g", "daemon off;"]

And this is the nginx config file:

server {
    listen 80;
    server_name _;
    root /app/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass api:9000;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

And this will be the Dockerfile for my laravel image:

FROM ubuntu:bionic

RUN apt update
RUN apt install -y software-properties-common
RUN add-apt-repository -y ppa:ondrej/php

RUN apt install -y php7.2-fpm
RUN apt install -y php7.2-pgsql
RUN apt install -y php7.2-mongodb
RUN apt install -y php7.2-redis
RUN apt install -y php7.2-mbstring
RUN apt install -y php7.2-xml
RUN apt install -y php7.2-zip
RUN apt install -y php7.2-curl
RUN apt install -y ffmpeg

RUN mkdir /run/php

COPY . /app

RUN chmod 0777 /app/storage -R

RUN sed  -i 's/pm.max_children = 5/pm.max_children = 10/g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's/pm.start_servers = 2/pm.start_servers = 4/g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 3/g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 5/g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's/;pm.max_requests = 500/pm.max_requests = 500/g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's|;access.log = log/$pool.access.log|access.log = /proc/self/fd/2|g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's|;php_admin_value[error_log] = /var/log/fpm-php.www.log|php_admin_value[error_log] = /proc/self/fd/2|g' /etc/php/7.2/fpm/pool.d/www.conf && \
    sed  -i 's|error_log = /var/log/php7.2-fpm.log|error_log = /proc/self/fd/2|g' /etc/php/7.2/fpm/php-fpm.conf && \
    sed  -i 's|listen = /run/php/php7.2-fpm.sock|listen = "9000"|g' /etc/php/7.2/fpm/pool.d/www.conf

WORKDIR /app

EXPOSE 9000

CMD ["php-fpm7.2", "-F"]

And the last think is my docker-compose.yml file:

version: "3"
services:
  nginx:
    image: hamed/nginx
    ports: 
      - 80:80
    volumes:
      - my-files:/app/public/files
  api:
    image: hamed/api
    volumes:
      - my-files:/app/public/files

Update: The result of lsof -Pn | grep LISTEN | grep ':80 ' as requested by @GerardH.Pille:

nginx      13     root    6u     IPv4             206078      0t0    TCP *:80 (LISTEN)

Update 2: These are the logs from my nginx service:

10.255.0.2 - - [21/Aug/2018:12:27:32 +0000] "GET /index.php HTTP/1.1" 200 5 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0" "-"

And from my php-fpm service:

10.0.0.2 -  21/Aug/2018:12:27:32 +0000 "- " 200
2hamed
  • 479
  • 1
  • 5
  • 23
  • in "fastcgi_pass api:9000", is nginx capable of resolving "api" ? – Gerard H. Pille Aug 20 '18 at 11:57
  • @GerardH.Pille Yes. It is able to resolve `api`. – 2hamed Aug 21 '18 at 04:58
  • So, if you run "lsof -Pn | grep LISTEN | grep ':80 '" as root, what do you get? (add output to your question). – Gerard H. Pille Aug 21 '18 at 07:27
  • @GerardH.Pille Done. – 2hamed Aug 21 '18 at 07:43
  • Can you also add what you get in nginx and laravel logs when you request localhost/index.php ? Nothing special in the error logs, even on restart? – Gerard H. Pille Aug 21 '18 at 07:52
  • There is no logs in laravel.log and for Nginx as I have mention in the question all I get is the 200 response log. Which is the same as the logs from php-fpm. – 2hamed Aug 21 '18 at 09:09
  • Can you add the line from the nginx access log to your question? I'd like to see the size of the response. Also, what does "wget -S h t t p ://localhost/index.php" give you? (http without spaces) – Gerard H. Pille Aug 21 '18 at 09:15
  • Added the logs to question. And `index.php` returns a complete blank page. No content. – 2hamed Aug 21 '18 at 12:32
  • What does "php /app/public/index.php" give ? (you may need to add php7.2-cli to your docker). – Gerard H. Pille Aug 21 '18 at 13:55
  • @GerardH.Pille It successfully prints the default Laravel page. – 2hamed Aug 22 '18 at 15:06
  • In your laravel dockerfile, I doubt very much that sed commands 6 and 7 work. Please check the resulting www.conf. Are you sure it's a good idea logging to /proc/self/fd/2 ? I wonder what you would get if you'd replace the contents of index.php by some simple html or even pure text. – Gerard H. Pille Aug 22 '18 at 19:53
  • Also, have a look at first answer here: https://stackoverflow.com/questions/8677493/php-fpm-doesnt-write-to-error-log – Gerard H. Pille Aug 22 '18 at 20:03
  • Just realized why it wasn't working. Will post it as an answer. – 2hamed Aug 23 '18 at 05:22
  • BTW, Thanks @GerardH.Pille for the patience you have shown. I appreciate your input without which I might have never found the solution. – 2hamed Aug 23 '18 at 05:39

1 Answers1

1

Ok after many hours of debugging and searching, found out the the following 2 lines inside my nginx configuration was why is wasn't working and why no errors was being displayed:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;

The nginx container wasn't passing the requested filename to php-fpm. Keep in mind that for it to work without actually putting index.php in the url you need to have index.php file inside the nginx root folder. It just needs to exists. It's ok if it's empty.

2hamed
  • 479
  • 1
  • 5
  • 23