0

I'm trying to set up Symfony 3 in Docker on a Windows machine with NGINX and PHP-FPM. At the moment, I get a 502 bad gateway error. I changed the FPM port from 9000 to 8000 because on my host, port 9000 is already in use by a hyper-v service vmms.exe. I don't know if it's related.

docker-compose.yml

version: "3"

services:

  nginx:
      build: ./nginx
      volumes:
        - ./symfony:/usr/shared/nginx/html
      ports:
        - "80:80"
        - "443:443"
      environment:
        - NGINX_HOST=free-energy.org
      depends_on:
        - fpm

  fpm:
      image: php:fpm
      ports:
          - "8000:8000"
      # It seems like FPM receives the full path from NGINX
      # and tries to find the files in this dock, so it must
      # be the same as nginx.root
      volumes:
          - ./symfony:/usr/shared/nginx/html

Dockerfile NGINX:

FROM nginx:1.13.7-alpine

# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/

EXPOSE 80
EXPOSE 443

default.conf override NGINX:

server {
    listen  80;
    server_name free-energy.org;

    # this path MUST be exactly as docker-compose.fpm.volumes,
    # even if it doesn't exist in this dock.
    root /usr/share/nginx/html;

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

    location ~ ^/.+\.php(/|$) {
        fastcgi_pass fpm:8000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
progonkpa
  • 3,590
  • 9
  • 31
  • 50

3 Answers3

1

Could you please check php-fpm container? As I remember, the php-fpm default port is 9000, not 8000. Change port mapping from inside container from 8000 to 9000

  ports:
      - "8000:9000"

Or if it already to use on your host you can expose the port only between containers.

  expose:
      - "9000"
0TshEL_n1ck
  • 441
  • 3
  • 9
  • Thanks, I changed it back to 9000. Now I get 'FastCGI sent in stderr: “Primary script unknown”'. – progonkpa Dec 25 '17 at 18:26
  • 1
    If you expose the port, did you change fastcgi_pass fpm:8000; to fastcgi_pass fpm:9000; in your NGINX default config? Maybe you forget to rebuild the image? – 0TshEL_n1ck Dec 25 '17 at 18:49
  • I was aware of this and had changed to fastcgi_pass fpm:9000 and used docker-compose up --build – progonkpa Dec 25 '17 at 22:48
0

With the answer of 0TshEL_n1ck the 502 error was solved. I still got 'File not found' in the browser and a related error log in NGINX 'FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream'.

Here is the configuration that turned out to work. The key things that needed to change:

  • the root directive in the NGINX configuration file did not contain /public which is needed in a Symfony project because the front controller index.php is located there
  • I changed the volume destination in docker-compose.yml such that the Symfony project directory is now mapped to /var/www/symfony instead of /usr/shared/nginx/html (not sure why previous didn't work)

These points came to light after using the NGINX configuration from the Symfony docs located at https://symfony.com/doc/current/setup/web_server_configuration.html

Here's the code that worked.

docker-compose.yml:

version: "3"

services:

  nginx:
      build: ./nginx
      volumes:
        - ./symfony:/var/www/symfony

      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - fpm

  fpm:
      image: php:fpm
      ports:
          - "9000"
      volumes:
          - ./symfony:/var/www/symfony

NGINX configuration default.conf:

server {
    listen  80;
    server_name free-energy.org, www.free-energy.org;
    root /var/www/symfony/public;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass fpm:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # 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;
}
progonkpa
  • 3,590
  • 9
  • 31
  • 50
0

We will guess so a week, try to use this: /docker-compose.yml

version: "2"
services:
  nginx:
    build: "./docker/nginx/"
    container_name: "nginx-free-energy"
    volumes_from:
      - php-fpm
    restart: always
    ports:
      - "80:80"
  php-fpm:
    image: php:7.1-fpm
    container_name: "php-fpm-free-energy"
    volumes:
      - ./src/free-energy.org:/var/www/free-energy.org
    restart: always
    expose:
      - "9000"

/docker/nginx/Dockerfile

FROM nginx

COPY config/free-energy.conf /etc/nginx/conf.d/free-energy.conf

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

RUN usermod -u 1000 www-data

EXPOSE 80

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

/docker/nginx/config/free-energy.conf (for symfony3 app)

server {
    listen      80;
    server_name www.free-energy.org free-energy.org;
    root /var/www/free-energy.org/web;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
    }

    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass php-fpm-free-energy:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # 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/app.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/free-energy.org_error.log;
    access_log /var/log/nginx/free-energy.org_access.log;
}

After start, you need to add 127.0.0.1 free-energy.org to your /etc/hosts file for resolving the host, and your app will live on the /src/free-energy.org (entry point is - /src/free-energy.org/web/app.php)

0TshEL_n1ck
  • 441
  • 3
  • 9