HTTP Request not returning result with nginx proxy in front

Describe the issue/error/question

I’ve created a docker-compose based n8n and I’m attempting to test an http request node

What is the error message (if any)?

I don’t see an error but when I execute the node it just spins.
also the endpoint I am attempting to reach, with the http request, does not register that it has been called.

Please share the workflow

  "nodes": [
    {
      "parameters": {
        "url": "https://reqres.in/api/users",
        "options": {}
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        40,
        -140
      ]
    }
  ],
  "connections": {}
}

Hi @pigeonflight, welcome to the community :tada:

I am so sorry to hear you are having trouble with this. I quickly tested this on my end and didn’t run into any trouble with this:

n8n could, however, show this behaviour if it does not get any data from it’s backend. So I am wondering if your docker container stops for any reason here. Is it still healthy? Anything out of the ordinary in the docker container logs?

Just for more context, my setup works with a receiving webhook… so I’m wondering if my configuration is preventing the reliable sending of requests.

1 Like

Further context:
I’m using nginx in front of n8n. Here’s my nginx config (replacing my domain with example.com)

upstream flow {
    server 127.0.0.1:5678;
    keepalive 64;
}
server {
     server_name flow.example.com;
     location / {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        proxy_redirect off;
        proxy_pass http://flow;
        proxy_read_timeout 240s;
}

That’s a good point - is your firewall possibly blocking outgoing traffic?

No the firewall doesn’t, but the docker setup might be an issue. I’ll try it non-dockerised and report back.

Update:
I’ve tested using n8n directly and the http request works.
So it’s definitely my nginx proxy configuration.
I’m a bit surprised, I thought the harder part would have been dealing with incoming requests for webhooks etc…
Not outgoing ones :slight_smile:

Hey @pigeonflight,

It will be interesting to know what it is when you work it out, It looks to me like you are using nginx as a reverse proxy rather than an outbound proxy so it shouldn’t be involved with the outbound request at all.

@Jon,
That makes a lot of sense. :thinking:

So I went ahead and created a new server from scratch to use docker + traefik.
The http request now works as expected.

Now I have a new problem. CORS which worked fine for incoming webhooks on the nginx setup is not working on the new traefik version.

I’m now using this docker-compose.yml file for my setup. I suspect Traefik is what I need to fix for CORS.

version: "3"

services:
  traefik:
    image: "traefik"
    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:
      - "80:80"
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true

    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
    volumes:
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n
      - /local-files:/files

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

Further note. As I’ve been using n8n, I’ve found that executing a part of the workflow sometimes fails, due to some dependency earlier in the workflow.
I think this is what was happening with me. My workflow started with a webhook and I was trying to execute an http request further down in the workflow which just hung.
When I disconnected the http request from the workflow it worked as expected. So it turns out that everything was actually fine with my initial setup.

1 Like