0
votes

Does anyone see what I did wrong with my Nginx Reverse Proxy? I am getting a 502 Bad Gateway and I can't seem to figure out where my ports are wrong.

Nginx

/etc/nginx/sites-enabled/default

upstream reverse_proxy {
  server 35.237.158.31:8080;
}

server {
  listen 80;
  server_name 35.237.158.31;

  location / {                                                      
    proxy_pass http://reverse_proxy;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_cache_bypass $http_upgrade;
  }

}

/etc/nginx/sites-enabled/jesse.red [VHOST]

upstream jessered {
    server 127.0.0.1:2600; # <-- PORT 2600
}
server {

  server_name jesse.red;
  #root /var/www/jesse.red/;

    # ---------------------------------------------------------------
    # Location
    # ---------------------------------------------------------------
    location / {
        proxy_pass          http://jessered;
        #proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection 'upgrade';
        proxy_set_header    Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_cache_bypass  $http_upgrade;
        proxy_read_timeout  90;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/jesse.red/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/jesse.red/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = jesse.red) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

  server_name jesse.red;
    listen 80;
    return 404; # managed by Certbot
}                      

Docker

Below it's running on 2600

$ docker ps

9d731afed500        wordpress:php7.0-fpm-alpine   "docker-entrypoint.s…"   3 days ago          Up 17 hours         9000/tcp, 0.0.0.0:2600->80/tcp   jesse.red

/var/www/jesse.red/docker-compose.yml

version: '3.1'
services:
  jessered:
    container_name: jesse.red
    image: wordpress:4-fpm-alpine
    restart: always
    ports:
      - 2600:80 # <-- PORT 2600
    env_file:
      - ./config.env  # Contains .gitignore params

Testing Docker

docker-compose logs

Attaching to jesse.red
jesse.red | WordPress not found in /var/www/html - copying now...
jesse.red | Complete! WordPress has been successfully copied to /var/www/html
jesse.red | [03-Jul-2018 11:15:07] NOTICE: fpm is running, pid 1
jesse.red | [03-Jul-2018 11:15:07] NOTICE: ready to handle connections

System

$ ps aux | grep 2600

Below, port 2600 is in use.

root      1885  0.0  0.1 232060  3832 ?        Sl   Jul02   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 2600 -container-ip 172.20.0.2 -container-port 80

I'm not sure what went wrong, any help is really appreciated. I have scoured many places and haven't figured it out before asking.

1
What is the network request (URL) that returns a 502 Bad Gateway? Is it from your local machine or over the internet?Mike Lippert

1 Answers

0
votes

Nginx request processing chooses a server block like this:

Check listen directive for IP:port exact matches, if no matches then check for IP OR port matches. IP addresses with no port are considered to be port 80.

From those matches it then checks the Host header of the request looking to match a server_name directive in the matched blocks. If it finds a match then that server handles the request, if not then assuming no default_server directive is set the request will be passed to the server listed first in your config.

So you have server_name 35.237.158.31; on port 80, and server_name jesse.red; also on port 80

IP addresses should be part of the listen directive, not the server_name, although this might match for some requests. Assuming this is being accessed from the outside world it's unlikely jesse.red will be in anyone's host headers.

Assuming no matches then it's going to get passed to whatever server Nginx finds first with a port match, I'm assuming Nginx will work alphabetically when including files, so your configs will load like this:

  1. /etc/nginx/sites-enabled/default
  2. /etc/nginx/sites-enabled/jesse.red

and now all your requests on port 80 with no host match, or with the ip address in the host field are getting proxied to:

upstream reverse_proxy {
  server 35.237.158.31:8080;
}

That's my guess anyway, your Nginx logs will probably give you a fairly definitive answer.