Maurice
Maurice

Reputation: 1092

Force https on nginx docker container

I have build a website that uses three Docker containers (mysql, nginx and php7.0-fpm). I've set everything up over SSL so connections made directly to https://domain.dev work as they should. The thing is that a connection to http://domain.dev results in a 'refused to connect' error.

Here's my (relevant) setup:

docker-compose.yml

services:
     nginx:
          build: ./nginx/
          ports:
               - 443:443
          volumes:
               - ${APPLICATION_ROOT}:/${WEBROOT}
               - ./ssl:/etc/nginx/ssl
               - ./nginx/config/default.conf:/etc/nginx/conf.d/default.conf
          restart: always
          depends_on:
               - php
          environment:
               ENVIRONMENT: "${APPLICATION_ENV}"
               URL: "${APPLICATION_URL}"
          container_name: nginx

 php:
      build: ./php/
      ports:
           - 8080:80
      volumes:
           - ${APPLICATION_ROOT}:/${WEBROOT}
      restart: always
      depends_on:
           - mysql
      environment:
           ENVIRONMENT: "${APPLICATION_ENV}"
           URL: "${APPLICATION_URL}"
           MYSQL_HOST: "${DB_HOST}"
           MYSQL_DATABASE: "${DB_NAME}"
           MYSQL_USER: "${DB_USERNAME}"
           MYSQL_PASSWORD: "${DB_PASSWORD}"
      container_name: php

The environment variables are storen in a .env file btw

Dockerfile

FROM nginx:latest

# Update package libraries
RUN apt-get update -y && \
     apt-get install -y \
          nano \ 
          curl \
          wget \
          unzip \
          libmcrypt-dev \

default.conf

server {
     listen 80;
     index index.php index.html;
     server_name $URL_from_env;
     return 301 https://$host$request_uri;
}

server{
     listen 443 ssl http2;
     index index.php index.html;
     server_name $URL_from_env;
     error_log  /var/log/nginx/error.log;
     access_log /var/log/nginx/access.log;
     root /var/www/html/public;

     # set max upload
     client_max_body_size 500M;

     ssl    on;
     ssl_certificate    /etc/nginx/ssl/cert.pem;
     ssl_certificate_key    /etc/nginx/ssl/cert.key;

     # use fastcgi for all php files
     location ~ \.php$ {
          try_files $uri =404;
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass php:9000;
          fastcgi_index index.php;

          # include fastcgi parameters
          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_param PATH_INFO $fastcgi_path_info;
     }

     # rewrite url's & parse through index
     location / {
          try_files $uri $uri/ /hub/index.php?$args;

          # set max upload
          client_max_body_size 500M;
     }
}

I expected the first part of the nginx config should force the traffic over https, but apparently it doesn't. What am i missing?

Upvotes: 2

Views: 3998

Answers (1)

samprog
samprog

Reputation: 2634

In your compose file, you still need to give nginx access to port 80, so it can rewire the connection internally. Otherwise you're trying to connect to a closed port, which results in "connection refused".

services:
 nginx:
      build: ./nginx/
      ports:
           - 443:443
           - 80:80
      volumes:
           - ${APPLICATION_ROOT}:/${WEBROOT}
           - ./ssl:/etc/nginx/ssl
           - ./nginx/config/default.conf:/etc/nginx/conf.d/default.conf
      restart: always
      depends_on:
           - php
      environment:
           ENVIRONMENT: "${APPLICATION_ENV}"
           URL: "${APPLICATION_URL}"
      container_name: nginx

Upvotes: 1

Related Questions