ERR_TOO_MANY_REDIRECTS in backoffice when running Prestashop in Docker

Łukasz Zaroda picture Łukasz Zaroda · Apr 3, 2017 · Viewed 10.6k times · Source

I'm trying to make a docker environment for a Prestashop project. I have it almost working but for some reason, the back office is inaccessible - it gives me a ERR_TOO_MANY_REDIRECTS error.

I changed the urls in shop_url table and changed PS_SHOP_DOMAIN and PS_SHOP_DOMAIN_SSL to no vain. I tried to disable friendly URLs, enable/disable SSL - but the problem persists.

I'm using a custom image for a webserver:

luken-wodby-nginx-prestashop Dockerfile:

FROM wodby/nginx:1.10

ENV WODBY_DIR_FILES /mnt/files

RUN rm /etc/gotpl/default-vhost.conf.tpl && \
    mkdir -p $WODBY_DIR_FILES && \
    mkdir -p /var/log/nginx

COPY prestashop.conf.tpl /etc/gotpl/
COPY init/* /docker-entrypoint-init.d/

docker-compose.yml:

version: "2"

services:
  mariadb:
    image: wodby/mariadb:10.1-2.0.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: organic
      MYSQL_USER: prestashop
      MYSQL_PASSWORD: prestashop
    volumes:
      - ./database:/docker-entrypoint-initdb.d
    ports:
      - "33060:3306"

  php:
    image: wodby/php:5.6-2.0.0
    environment:
      PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025
      PHP_XDEBUG: 1
      PHP_XDEBUG_DEFAULT_ENABLE: 1
    volumes:
      - ./:/var/www/html

  nginx:
    image: luken-wodby-nginx-prestashop:latest
    depends_on:
      - php
    environment:
      NGINX_BACKEND_HOST: php
      NGINX_SERVER_NAME: prestashop.docker.localhost
      NGINX_SERVER_ROOT: /var/www/html/public_html
    volumes:
      - ./:/var/www/html
    ports:
      - "8000:80"

  mailhog:
    image: mailhog/mailhog
    ports:
      - "8002:8025"

Nginx virtual host configuration:

server {
    listen 80;
    server_name {{ getenv "NGINX_SERVER_NAME" "prestashop" }};
    root {{ getenv "NGINX_SERVER_ROOT" "/var/www/html/" }};
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    index index.php index.html;

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

    location = /robots.txt {
        auth_basic off;
        allow all;
        log_not_found off;
        access_log off;
    }

    # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 1;
    gzip_buffers 16 8k;
    gzip_http_version 1.0;
    gzip_types application/json text/css application/javascript;

    rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last;
    rewrite ^/([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$1$2$3.jpg last;
    rewrite ^/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$1$2$3$4.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$1$2$3$4$5.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg last;
    rewrite ^/c/([0-9]+)(-[.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+.jpg$ /img/c/$1$2$3.jpg last;
    rewrite ^/c/([a-zA-Z_-]+)(-[0-9]+)?/.+.jpg$ /img/c/$1$2.jpg last;
    rewrite ^/images_ie/?([^/]+).(jpe?g|png|gif)$ /js/jquery/plugins/fancybox/images/$1.$2 last;
    rewrite ^/order$ /index.php?controller=order last;
    location /panel_adm/ {                           #Change this to your admin folder
        if (!-e $request_filename) {
            rewrite ^/.*$ /panel_adm/index.php last; #Change this to your admin folder
        }
    }
    location / {
        if (!-e $request_filename) {
            rewrite ^/.*$ /index.php last;
        }
    }

    location ~ .php$ {
        fastcgi_split_path_info ^(.+.php)(/.*)$;
        try_files $uri =404;
        fastcgi_keep_conn on;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass backend;  #Change this to your PHP-FPM location
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   }
}

Website works just fine, only the back office is inaccessible and gives ERR_TOO_MANY_REDIRECTS error.

Any ideas what can be wrong?

Answer

Łukasz Zaroda picture Łukasz Zaroda · May 4, 2017

I found the cause of the problem. The wodby/nginx nginx container is using a custom fastcgi_params file. This file strangely enough doesn't have fastcgi_param QUERY_STRING $query_string; line (in contrast to the original file that comes with nginx). This makes it incompatible by default with some ready nginx templates that you can find on the internet. It manifests itself by query parameters not getting passed to the script (I created an issue for it here: https://github.com/wodby/nginx/issues/3 ).

Now, Prestashop's back office not having an important controller parameter freaks out, because it doesn't know which controller to run. If there is no controller, it does a redirection to the URL with a default controller as a parameter, but because there is never a "controller" parameter available for Prestashop, it ends in redirection loop causing ERR_TOO_MANY_REDIRECTS.

The fix for this is to add fastcgi_param QUERY_STRING $query_string; in your nginx configuration to pass query parameters to the script.