HTTP Request not returning result with nginx proxy in front

I’ve documented what eventually worked for me.
In summary. This is n8n powered by docker and docker-compose with nginx installed locally using apt.

The Nginx part

My complete nginx configuration looks like this:

upstream myserver {
    server 127.0.0.1:5678;
    keepalive 64;
}
server {
     server_name n8n.example.com;
     location / {
        proxy_pass http://myserver;
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        # note the inclusion of the protocol 'https'
        add_header Access-Control-Allow-Origin https://my.website.example.com;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
     
     }

# this is leftover from another example
# isn't really needed for the cors stuff
 client_max_body_size 25m;


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/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 = myn8n.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


     server_name n8n.example.com;


    listen 80;
    return 404; # managed by Certbot


}

The n8n part

I use the docker-compose from the n8n server setup docs

“misdirect” traefik on purpose

I modified the docker-compose example to have traefik listen on different ports because I want to use nginx as the proxy. It really is my way of removing traefik from ports 80 and 443. I’ll eventually remove it from my setup.

While I was testing I made traefik listen on ports 1080 and 1443 (again, I plan to just remove the traefik service).

version: "3"
  
services:
  traefik:
    image: "traefik:v2.4"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "1080:80"
      - "1443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

Once again, this was a quick fix, very akin to adding a comment in source code, I fully intend to just remove the traefik service.

gotchas

setting headers with the webhook nodes

I know it is possible to set headers (e.g Access-Control-Allow-Origin headers) on the n8n provided webhook nodes themselves, but this caused all sorts of conflicts for me. I had situations where the proxy and the webhook in n8n set the same header (instant conflict). When I removed the headers from the proxy, for some reason, the webhook headers did not show up. In the long run I settled for setting the header using the proxy.

setting blank header will kill you

At one point I was completely stuck, the nginx proxy had the correct header and I thought the webhook node had removed the header. When I inspected the webhook node it had a blank header set. This made requests to the webhook “hang”

Access-Control-Allow-Headers is important

The way CORS works there are some headers that are not allowed, unless the proxy explicitly allows them.
Hence this line in my nginx config

add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'

I know for sure that the Content-Type header was a problem for me. I added the others because they were recommended in tutorials on the internet. I suspect some of them aren’t needed.

2 Likes