Chris Rogers
Chris Rogers

Reputation: 1522

Struggling To Integrate Nginx Proxy + LetsEncrypt Companion With My Docker Composed Web App

What I am trying to achieve

I am trying to integrate an SSL certificate for my production site, bonus if I could create a self-signed certificate for local development.

The issue I am having

When trying to integrate the nginx-proxy and letsencrypt-companion it always results in a redirect loop or 502 Bad gateway error.

I've looked around at a variety of ways to integrate these 2 companions but I still am stuck about how to integrate this but always ask myself the same questions when attempting to integrate into my environment.

More detail about my environment

I am running a multi-container Docker Compose web app which uses PHP/PHP-FPM 7.2, MySQL & Nginx. The config looks like:

version: '3.1'

networks:
  mywebapp:

services:
  nr_nginx:
    build: ./env/nginx
    networks:
      - mywebapp
    ports:
      - 80:80
      - 443:443
    env_file:
      - ./env/nginx/.env
    depends_on:
      - nr_php72
    tty: true
    volumes:
      - ./src:/home/www/mywebapp/src
      - ./storage:/home/www/storage/mywebapp
      - ./data/nginx/logs:/var/log/nginx
      - ./env/nginx/webserver/nginx.conf:/etc/nginx/nginx.conf
      - ./env/nginx/webserver/conf.d:/etc/nginx/conf.d
      - ./env/nginx/webserver/defaults:/etc/nginx/defaults
      - ./env/nginx/webserver/global:/etc/nginx/global
      - ./env/nginx/ssl/:/etc/letsencrypt/
      - ./env/nginx/share:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  nr_mysql:
    build: ./env/mysql
    networks:
      - mywebapp
    ports:
      - 3306:3306
    env_file:
      - ./env/mysql/.env
    volumes:
      - ./data/mysql:/var/lib/mysql
      - ./env/mysql/conf.d:/etc/mysql/conf.d
      - ./data/dbimport/:/docker-entrypoint-initdb.d

  nr_php72:
    build: ./env/php72
    hostname: php72
    networks:
      - mywebapp
    depends_on:
      - nr_mysql
    ports:
      - 9000:9000
      - 8080:8080
    volumes:
      - ./env/composer:/home/www/.composer
      - ./env/global/bashrc:/home/www/.bashrc
      - ./data/bash/.bash_history:/home/www/.bash_history
      - ~/.ssh:/home/www/.ssh:ro
      - ~/.gitconfig:/home/www/.gitconfig:ro
      - ./storage:/home/www/storage/mywebapp
      - ./src:/home/www/mywebapp/src

Questions

  1. Should the nginx-proxy replace my existing "nr_nginx" container?
  2. Do I have remove the 80:80, 433:433 port mapping for "nr_nginx" and instead assign a random unique port of my choice e.g. 5000?
  3. If yes to question 2, how do I tell the nginx-proxy to proxy pass to my container of port 5000?

Upvotes: 0

Views: 1360

Answers (1)

Chris Rogers
Chris Rogers

Reputation: 1522

Okay, so I think I have solved it:

  1. No it shouldn't replace your own nginx configuration
  2. Yes, remove ports 80 and 443 as this wil be handled by the nginx-proxy, rather expose the ports in your container.
  3. You do not require manually configuring proxy_pass as nginx-proxy does this for you, so long as you specify a VIRTUAL_PORT environment variable.

Here is the boilerplate code that worked for me:

Boilerpalte nginx-proxy-letsencrypt-companion

docker-compose.yml:

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

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt
    volumes:
      - ./env/nginx/certs:/etc/nginx/certs
      - ./env/nginx/vhost.d:/etc/nginx/vhost.d
      - ./env/nginx/share:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - NGINX_PROXY_CONTAINER=nginx-proxy

networks:
  default:
    external:
      name: nginx-proxy

Boilerplate Nginx PHP MySQL Environment

docker-compose.yml

version: '3.1'

services:

  nginx:
    container_name: nginx
    build: ./env/nginx
    ports:
      - 5000:5000
    expose:
      - 80
      - 443
    environment:
      - VIRTUAL_HOST=your.domain.com,www.your.domain.com
      - VIRTUAL_PORT=5000
      - [email protected]
      - LETSENCRYPT_HOST=your.domain.com
    depends_on:
      - php72
    tty: true
    volumes:
      - ./src:/home/www/webapp/src
      - ./storage:/home/www/storage/webapp
      - ./data/nginx/logs:/var/log/nginx
      - ./env/nginx/webserver/nginx.conf:/etc/nginx/nginx.conf
      - ./env/nginx/webserver/conf.d:/etc/nginx/conf.d
      - ./env/nginx/webserver/defaults:/etc/nginx/defaults
      - ./env/nginx/webserver/global:/etc/nginx/global
      - /var/run/docker.sock:/tmp/docker.sock:ro

  mysql:
    container_name: mysql
    build: ./env/mysql
    ports:
      - 3306:3306
    env_file:
      - ./env/mysql/.env
    volumes:
      - ./data/mysql:/var/lib/mysql
      - ./env/mysql/conf.d:/etc/mysql/conf.d
      - ./data/dbimport/:/docker-entrypoint-initdb.d

  php72:
    container_name: php72
    build: ./env/php72
    hostname: php72
    depends_on:
      - mysql
    ports:
      - 9000:9000
    volumes:
      - ./env/composer:/home/www/.composer
      - ./env/global/bashrc:/home/www/.bashrc
      - ./data/bash/.bash_history:/home/www/.bash_history
      - ~/.ssh:/home/www/.ssh:ro
      - ~/.gitconfig:/home/www/.gitconfig:ro
      - ./storage:/home/www/storage/webapp
      - ./src:/home/www/webapp/src

networks:
  default:
    external:
      name: nginx-proxy

/etc/nginx/conf.d/default.conf - inside "nginx" container:

server {

    listen 5000;
    listen [::]:5000;

    server_name www.your.domain.com;

    root /my/web/root/src;
    index index.php;

    include /any/conf/includes/here.conf;

    location / {
        fastcgi_param HTTPS 'on';
        try_files $uri $uri/ /index.php$is_args$args;
    }
}

The fastcgi_param HTTPS 'on'; conf prevents a redirect loop, you can alternatively add $_SERVER['HTTPS'] = 'on'; to your index.php

Upvotes: 2

Related Questions