Docker-letsencrypt-nginx-proxy-companion: 301 Redirect Loop for https:// on Wordpress

Created on 6 Oct 2016  路  3Comments  路  Source: nginx-proxy/docker-letsencrypt-nginx-proxy-companion

Hey there,

first of all thanks a lot for your good work! I really appreciate it!

I just tried a Docker Compose Wordpress Setup with PHP 7, NGINX, PHP FPM and MySQL. This on its own runs perfectly (If I just run docker-compose up). It is served then from the packed nginx service directly.

I now have a server setup which uses multiple docker-compose setups to run different applications. With NGINX-Proxy this works great so far. But here comes the problem:

For my Wordpress site (woocommerce shop) I would like to run it on https://. So I configured this companion (docker-letsencrypt-nginx-proxy-companion) to get it running.

My docker-compose file for nginx with companion looks like this:

version: "2"

services: 
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/www/certificates:/etc/nginx/certs:ro
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt-nginx-proxy-companion
    restart: always
    volumes_from:
      - nginx-proxy
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/var/www/certificates:/etc/nginx/certs:rw"

networks:
  default:
    external:
      name: proxy-network

My app docker-compose.yml looks like this:

version: '2'

services:
  web:
    image: nginx:latest
    container_name: "wp-nginx"
    ports:
      - "80"
    env_file: .env
    environment:
      - VIRTUAL_HOST=XXX.com
      - VIRTUAL_PORT=80
      - VIRTUAL_NETWORK=proxy-network
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
    links:
      - php
    volumes_from:
      - wordpress-data

  # php
  php:  
    build: ./php/
    container_name: "${CONTAINER_PHP}"
    env_file: .env
    expose:
      - 9000
    links:
      - mysql
    volumes_from:
      - wordpress-data

  # mysql
  mysql:
    image: mysql:latest
    volumes_from:
      - mysql-data
    #ports:
    #  - "3306:3306"
    container_name: "${CONTAINER_MYSQL}"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  # wordpress data
  wordpress-data:
    container_name: "${CONTAINER_APP_DATA}"
    image: php:7.0-fpm
    volumes:
      - ${SRC_APP_PERSISTENT}:/var/www/html
    command: "true"

  # mysql data
  mysql-data:
    image: mysql:latest
    container_name: "${CONTAINER_MYSQL_DATA}"
    volumes:
      - ${SRC_DB_PERSISTENT}:/var/lib/mysql
    command: "true"

  # phpmyadmin
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: "phpmyadmin"
    ports:
      - 8080:80
    links:
      - mysql
    environment:
      PMA_HOST: mysql

networks:
  default:
    external:
      name: proxy-network

So basically this works. I can connect to my Wordpress site, it redirects it correctly to https and generated the certificates, but it never stops redirecting. Im stuck in a 301 redirection loop if I update my URL for my Wordpress site from http:// to https:// in de Database. If I leave my settings on http:// it gets also redirected to https:// but I can see the site, but every CSS, JS and Images are blocked because the site tries to load this from http:// instead of https://.

Im wondering if this could be caused by my nginx conf from the wordpress site itself?

The config for the wordpress site looks like this:

server {
  server_name  localhost;
  listen   80;
  # listen for ipv6
  listen   [::]:80 default ipv6only=on; 
  # root
  root   /var/www/html;
  index index.html index.htm index.php;

  client_max_body_size 100M;
  fastcgi_read_timeout 1800;

  #error_page  404        /404.html;

  # error50x.html
  #
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /var/www/html;
  }

  location / {
    # try_files $uri $uri/ /index.php;
    # add permalinks
    try_files $uri $uri/ /index.php?$args;
  }

  # WP Dev permalinks
  location /dev_wordpress {
    try_files $uri $uri/ /dev_wordpress/index.php?$args;
  }

  # Expiration headers
  location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
                  |jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
                  |midi|wav|bmp|rtf)$ {
      expires max;
      log_not_found off;
      access_log off;
    }

  # Disable favicon from root
  location = /favicon.ico {
    log_not_found off;
    access_log off;
  }

  # PHP: php7-fpm
  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;
  }

  #location ~ /\.ht {
  #  deny  all;
  #}
}

But if I understood it correctly, I don't have to change sth in the nginx container from my wordpress site, correct?

So maybe if anyone of you has a clue, Im really stuck here at the moment :(

All 3 comments

You're listening on the wrong port for HTTPS in your server block configuration.

Change your listen lines to use 443 instead of 80, and try again.

If you want to direct traffic from 80 (HTTP) to 443 (HTTPS), you should set up a separate server block, like the one below:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name localhost;
    return 301 https://$host$request_uri;
}

You'll need to provide the paths to the certificate(s) in the main block (where you are listening with 443).

OMG, thank you really much @bddenhartog I completely missed this one.

Thanks for this guys. Was having the exact same problem and this solution fixed it.

I had to share the volume from my nginx-proxy container to my backend nginx container, change the nginx config in sites-enabled to listen on 443 and pass it the ssl certificates.

One thing I also had to do was change the environment variables in my docker-compose file. I had to add VIRTUAL_PROTO=https and VIRTUAL_PORT=443. Just adding this in case it helps anyone else looking at this thread in future!

Was this page helpful?
0 / 5 - 0 ratings