1

Introduction

I want to create a site that is powered by php-fpm, nginx and docker and I want to have php-fpm and nginx on separate containers. To do this, I followed this tutorial but am stuck now when accessing my web server under localhost:8000. My browser displays a 502 and my /var/log/nginx/project_error.log is full with

[error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: app, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "localhost:8000"

Searched answers

I already searched a bit for this topic and found these threads:

However, none of them solved my problems.

Files

I created a GitHub repository containing all files, so anyone can simply check it out there (I think it's better than having all files dumped in here). To do that, simply do

git clone git@github.com:tzfrs/dockertest.git
mkdir -p citynavigator/public
touch citynavigator/public/index.php

In addition to that, here is the code

General

docker-compose.yml

version: "2"
services:
    db:
        image: mysql:5.6
        ports:
          - "3306:3306"
        environment:
          - MYSQL_ROOT_PASSWORD=citynavigatorrootpass
          - MYSQL_DATABASE=citynavigator
          - MYSQL_USER=citynavigator
          - MYSQL_PASSWORD=citynavigatorpass
        volumes:
          - /var/lib/mysql

    nginx:
        image: nginx:latest
        ports:
            - "8000:80"
        volumes:
            - ../citynavigator:/var/www/app
            - ./nginx/nginx.conf:/etc/nginx/nginx.conf
            - ./nginx/app.conf:/etc/nginx/conf.d/default.conf
            - ./nginx/fastcgi_params:/etc/nginx/fastcgi_params
        links:
            - php
        networks:
            - code-network

    php:
        build: fpm/
        volumes:
            - ../citynavigator:/var/www/app
        networks:
            - code-network

networks:
    code-network:
        driver: bridge

fpm/Dockerfile

FROM php:7.2-fpm

LABEL maintainer="Theo Tzaferis<t.tzfrs@gmail.com>"

USER root

RUN rm /usr/local/etc/php-fpm.d/docker.conf \
    && rm /usr/local/etc/php-fpm.d/www.conf \
    && rm /usr/local/etc/php-fpm.d/www.conf.default \
    && rm /usr/local/etc/php-fpm.d/zz-docker.conf \
    && rm -rf /var/www/html

ADD app.pool.conf /usr/local/etc/php-fpm.d/app.pool.conf

fpm/app.pool.conf

[app]
user = www-data
group = www-data

listen = 127.0.0.1:9000

pm = dynamic
pm.max_children = 20
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

catch_workers_output = yes

nginx/app.conf

upstream php-upstream {
    server 127.0.0.1:9000;
}

server {
    server_name app;
    root /var/www/app/public;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass php-upstream;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # optionally set the value of the environment variables used in the application
        # fastcgi_param APP_ENV prod;
        # fastcgi_param APP_SECRET <app-secret-id>;
        # fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";

        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/index.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    # return 404 for all other php files not matching the front controller
    # this prevents access to other php files you don't want to be accessible.
    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}

nginx/fastcgi_params

fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;

fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
# fastcgi_param   REDIRECT_STATUS         200;

# Allow 10 minute script execution time
fastcgi_read_timeout 600s;

nginx/nginx.conf

user www-data;
worker_processes 4;
pid /run/nginx.pid;

events {
  worker_connections  2048;
  multi_accept on;
  use epoll;
}

http {
  server_tokens off;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 15;
  types_hash_max_size 2048;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  access_log off;
  error_log off;
  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
  include /etc/nginx/conf.d/*.conf;
  open_file_cache max=100;
  client_max_body_size 30m;
}
Community
  • 1
  • 1
Musterknabe
  • 5,763
  • 14
  • 61
  • 117
  • I added the code to the question as well. – Musterknabe Jul 01 '18 at 09:49
  • 1
    I had a quick peek and spotted two things that may need correction: 1. Both `nginx` and `php-fpm` use `127.0.0.1` but this is not the case - separate containers have a separate address given by `code-network` network. 2. In your `app.conf`, using `realpath_root` (IMO) is really suitable when both `nginx and `php-fpm` are running on the same virtual box. Try replacing that with `$document_root` var instead if you want to run this across multiple containers. I may be able to provide more info later today, but this is what I was able to spill out now... – Jovan Perovic Jul 01 '18 at 12:09
  • Hi, I changed `realpath_root` to `document_root`. To your first point: Do you mean that I have to set the ip of the `nginx` container in `fpm/app.pool.conf` and the ip of the `php-fpm` container in `nginx/app.conf`? – Musterknabe Jul 01 '18 at 12:39
  • 1
    I think I fixed it for now. I changed `fastcgi_pass` to `fastcgi_pass php:9000;` and now it works without problems, finally. Thank you for pointing me to the right direction – Musterknabe Jul 01 '18 at 12:58
  • [Creating a simple PHP-FPM, Nginx and MySQL application with docker compose](http://www.inanzzz.com/index.php/post/zpbw/creating-a-simple-php-fpm-nginx-and-mysql-application-with-docker-compose). This is cleaner version than yours. – BentCoder Jul 01 '18 at 22:07
  • It doesn't look that much different. How is it cleaner? :) – Musterknabe Jul 02 '18 at 05:54

1 Answers1

1

This is cause the 127.0.0.1 should be the name of your php service not the localhost

So change

fastcgi_pass php-upstream;

to

fastcgi_pass php:9000;

Or similar in the used upstream directive.

php is reachable from your nginx if its in the same network (which obvously is through code-network)

Jim Panse
  • 2,220
  • 12
  • 34
  • 1
    Gonna accept this answer, since the solution was only in the `comments` and it's probably better for users to see this answer directly. – Musterknabe Jul 03 '18 at 05:43