Add Docker NGINX https revproxy after initial setup in docker environment

Hi together,

after finally managing (with kind help of Zellte) to set up n8n in a docker environment …
( Noob: Completely Lost - #14 by wos )

I’m now at the point, that N8N is running, but without https access at the moment. I think i must modify my existing docker-compose to add that support?

Here’s my existing docker-compose.yml …

version: ‘3.8’
services:
n8n:
image: docker.n8n.io/n8nio/n8n
ports:
- “5678:5678”
environment:
- TZ=Europe/Berlin
volumes:
- n8n_data:/home/node/.n8n
restart: unless-stopped
volumes:
n8n_data:

Without NGINX revproxy support. How to add it here?

1 Like

@wos You’re exactly on point. Adding HTTPS with NGINX is the next step and it’s much easier.

1 Like

Updated docker-compose.yml with NGINX

version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    environment:
      - TZ=Europe/Berlin
      - N8N_HOST=n8n.yourdomain.com  # ← Your public domain
      - N8N_PROTOCOL=https           # ← Force HTTPS
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
    networks:
      - n8n_network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs  # ← Your SSL certificates go here
    depends_on:
      - n8n
    restart: unless-stopped
    networks:
      - n8n_network

volumes:
  n8n_data:

networks:
  n8n_network:
    driver: bridge

In the same directory as your docker-compose.yml, create nginx.conf

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        server_name n8n.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl;
        server_name n8n.yourdomain.com;

        # SSL certificates (you'll place these in ./ssl/)
        ssl_certificate /etc/ssl/certs/fullchain.pem;
        ssl_certificate_key /etc/ssl/certs/privkey.pem;

        # Security headers
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        location / {
            proxy_pass http://n8n:5678;
            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;
        }
    }
}

Hmmm. It seemed so simple. But i can’t get it to work. And have no Idea whats wrong, where to look for errors.
Under IP:5678 i have the connect, so docker and n8n is running.
Unter my.domain.de (how its also defined in docker-compose.yml) it is not working:

Maybe the PEM files have to be in a special format?! But the Keyfile is only the key. The Fullchain is startig with the Ceritifikate from the Server, then the Intermediate CA and then the Root CA.

Could it be a problem, that’s a wildcard certficate?

@wos Yes a wildcard certificate could absolutely be the problem if it’s not being properly recognized by the Docker/NGINX setup.

Compare your certificate with this

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: XXXX
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=R3
        Validity
            Not Before: Jan  1 00:00:00 2024 GMT
            Not After : Apr  1 00:00:00 2024 GMT
        Subject: CN=*.yourdomain.de
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:*.yourdomain.de, DNS:yourdomain.de

Thy “style” of how it’s being formatted, i guessed that the information must placed in docker-compose.yml, which I’ve did (not in nginx.conf). The complete file file looks now like this:

version: ‘3.8’
services:
n8n:
image: docker.n8n.io/n8nio/n8n
ports:

  • “5678:5678”
    environment:
  • TZ=Europe/Berlin
    volumes:
  • n8n_data:/home/node/.n8n
    restart: unless-stopped
    volumes:
    n8n_data:

nginx:
image: nginx:alpine
ports:

  • “80:80”
  • “443:443”
    volumes:
  • ./nginx.conf:/etc/nginx/nginx.conf
  • ./ssl:/etc/ssl/certs # ← Your SSL certificates go here
    depends_on:
  • n8n
    restart: unless-stopped
    networks:
  • n8n_network

volumes:
n8n_data:

networks:
n8n_network:
driver: bridge

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 039034b533a86829472ac87eff3d2de1
Signature Algorithm: sha256RSA
Issuer: C=US, O=DigiCert Inc, CN=RapidSSL TLS RSA CA G1
Validity
Not Before: Aug 22 02:00:00 2025 GMT
Not After : Aug 30 01:59:59 2026 GMT
Subject: CN=*.mydomain.de
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:*
.mydomain.de, DNS:mydomain.de

Of course the mydomain is other than here typed, in my real config the real domain name is in.

The “Signature Algorithm” is per Certificate “sha256”. I’ve tried also with “sha256WithRSAEncryption” (which means, other than the certificate itself its showing me …

… maybe the keyword must be typed like this, dont know.
But every time i reboot the machine (dont know how to come up docker with the new configuration), its not working. No matter if sha256RSA or sha256WithRSAEncryption.
Or must there typed in a command that the new config is going to affect?! Thats why I’m rebooting all the time :grin:
Btw, i find it also strange to define the starting date of the certificate, and the encryption? I would assume the config reads the certificate and know all those parameter and is using them accordingly. Dont understand why i need manual configuration (eg. the exact starting time or ending time for the certificate) for this. But of course, you know better that it must be.

From my Client i can also see (Powershell test-netconnection), that there is no Port 80/443 open. Only 5678.

I wanted to give you the config … as it is … but a automatic mechanism change formatting. Spaces now ar not visible and so on.

Ahhh, i used the ““ in the toolbar … better to use </> … and now it looks better:

version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      - TZ=Europe/Berlin
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
volumes:
  n8n_data:

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs  # ← Your SSL certificates go here
    depends_on:
      - n8n
    restart: unless-stopped
    networks:
      - n8n_network

volumes:
  n8n_data:

networks:
  n8n_network:
    driver: bridge

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 039034b533a86829472ac87eff3d2de1
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=DigiCert Inc, CN=RapidSSL TLS RSA CA G1
        Validity
            Not Before: Aug 22 02:00:00 2025 GMT
            Not After : Aug 30 01:59:59 2026 GMT
        Subject: CN=*.mydomain.de
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:*.mydomain.de, DNS:mydomain.de

Also tried to look at /var/lib/docker/containers/LongHexIDOfTheContainer hoping to get ther something like a error log, or something what brings me further. Google says it has the format LongHexIDOfTheContainer-json.log

And such a file is there:

{"log":"Permissions 0644 for n8n settings file /home/node/.n8n/config are too wide. This is ignored for now, but in the future n8n will attempt to change the permissions automatically. To automatically enforce correct permissions now set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true (recommended), or turn this check off set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false.\n","stream":"stdout","time":"2025-08-28T07:49:41.16395Z"}
{"log":"Initializing n8n process\n","stream":"stdout","time":"2025-08-28T07:49:43.9021874Z"}
{"log":"n8n ready on ::, port 5678\n","stream":"stdout","time":"2025-08-28T07:49:44.3659892Z"}
{"log":"\n","stream":"stdout","time":"2025-08-28T07:49:44.3831228Z"}
{"log":"There are deprecations related to your environment variables. Please take the recommended actions to update your configuration:\n","stream":"stdout","time":"2025-08-28T07:49:44.3831553Z"}
{"log":" - DB_SQLITE_POOL_SIZE -\u003e Running SQLite without a pool of read connections is deprecated. Please set `DB_SQLITE_POOL_SIZE` to a value higher than zero. See: https://docs.n8n.io/hosting/configuration/environment-variables/database/#sqlite\n","stream":"stdout","time":"2025-08-28T07:49:44.3831587Z"}
{"log":" - N8N_RUNNERS_ENABLED -\u003e Running n8n without task runners is deprecated. Task runners will be turned on by default in a future version. Please set `N8N_RUNNERS_ENABLED=true` to enable task runners now and avoid potential issues in the future. Learn more: https://docs.n8n.io/hosting/configuration/task-runners/\n","stream":"stdout","time":"2025-08-28T07:49:44.3831621Z"}
{"log":"\n","stream":"stdout","time":"2025-08-28T07:49:44.3831652Z"}
{"log":"Initializing AuthRolesService...\n","stream":"stdout","time":"2025-08-28T07:49:44.4640842Z"}
{"log":"AuthRolesService initialized successfully.\n","stream":"stdout","time":"2025-08-28T07:49:44.4807509Z"}
{"log":"[license SDK] Skipping renewal on init: license cert is not initialized\n","stream":"stdout","time":"2025-08-28T07:49:44.4885622Z"}
{"log":"Version: 1.108.1\n","stream":"stdout","time":"2025-08-28T07:49:46.8083057Z"}
{"log":"\n","stream":"stdout","time":"2025-08-28T07:49:46.8912391Z"}
{"log":"Editor is now accessible via:\n","stream":"stdout","time":"2025-08-28T07:49:46.8912684Z"}
{"log":"http://localhost:5678\n","stream":"stdout","time":"2025-08-28T07:49:46.8912714Z"}

Unfortunaly i can’t see anything there, whats going wrong. Anything what would give me a hint, where the problem ist located.

@wos I think I hv found what’s wrong. Your docker-compose.yml has a critical formatting error that’s preventing the nginx service from starting at all.

Your file has the nginx service inside the volumes section instead of the services section.

Here’s a correct version for you @wos

version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      - TZ=Europe/Berlin
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
    networks:
      - n8n_network  # ← Add this!

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs
    depends_on:
      - n8n
    restart: unless-stopped
    networks:
      - n8n_network

volumes:
  n8n_data:

networks:
  n8n_network:
    driver: bridge

Your file has the nginx service inside the volumes section instead of the services section.

Here’s a correct version for you @wos

Ok, understand. I changed it exact to this version, like you suggested:

version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      - TZ=Europe/Berlin
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
    networks:
      - n8n_network  # ← Add this!

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs
    depends_on:
      - n8n
    restart: unless-stopped
    networks:
      - n8n_network

volumes:
  n8n_data:

networks:
  n8n_network:
    driver: bridge

Just, because I’m unsure … where to place the certificate information now. Also inside the docker-compose.yml (at which exact location) … or musst this happen inside the nginx.conf ?

I mean this part:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 039034b533a86829472ac87eff3d2de1
        Signature Algorithm: sha256
        Issuer: C=US, O=DigiCert Inc, CN=RapidSSL TLS RSA CA G1
        Validity
            Not Before: Aug 22 02:00:00 2025 GMT
            Not After : Aug 30 01:59:59 2026 GMT
        Subject: CN=*.mydomain.de
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:*.mydomain.de, DNS:mydomain.de

From the look and feel I guess in the docker-compose.yml … and this leads me to the next question: Where exactly there?!

Must this part, a part of the nginx section there? Or can i add it just at the end?

From the practical side, its as it is. http://123.123.123.123:5678 works (showing that i should use ssl). If i try https://n8n.mydomain.de nothing happens. Ends in ERR_CONNECTION_REFUSED. The Ports 80/443 are also not open.

root@linux:~# ss -t -a -l
State                     Recv-Q                    Send-Q                                         Local Address:Port                                         Peer Address:Port
LISTEN                    0                         4096                                                 0.0.0.0:5678                                              0.0.0.0:*
LISTEN                    0                         128                                                  0.0.0.0:ssh                                               0.0.0.0:*
LISTEN                    0                         4096                                               127.0.0.1:ipp                                               0.0.0.0:*
LISTEN                    0                         4096                                                    [::]:5678                                                 [::]:*
LISTEN                    0                         4096                                                   [::1]:ipp                                                  [::]:*
LISTEN                    0                         128                                                     [::]:ssh                                                  [::]:*

It makes no difference, if the “certificate:” block in docker-compose.yml is not included …

… or included inside the “ningx section”, which would i assume could be right (don’t know if the term is correct):

version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      - TZ=Europe/Berlin
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
    networks:
      - n8n_network  # ← Add this!

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs
    depends_on:
      - n8n
    restart: unless-stopped
    networks:
      - n8n_network
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 039034b533a86829472ac87eff3d2de1
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: C=US, O=DigiCert Inc, CN=RapidSSL TLS RSA CA G1
            Validity
                Not Before: Aug 22 02:00:00 2025 GMT
                Not After : Aug 30 01:59:59 2026 GMT
            Subject: CN=*.mydomain.de
            X509v3 extensions:
                X509v3 Subject Alternative Name:
                    DNS:*.mydomain.de, DNS:mydomain.de

volumes:
  n8n_data:

networks:
  n8n_network:
    driver: bridge

Or if i use the keyword “sha256WithRSAEncryption” (which came from your example), or using “sha256RSA” like its real named in my cert … (only the Certificate: Part):

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 039034b533a86829472ac87eff3d2de1
            Signature Algorithm: sha256RSA
            Issuer: C=US, O=DigiCert Inc, CN=RapidSSL TLS RSA CA G1
            Validity
                Not Before: Aug 22 02:00:00 2025 GMT
                Not After : Aug 30 01:59:59 2026 GMT
            Subject: CN=*.mydomain.de
            X509v3 extensions:
                X509v3 Subject Alternative Name:
                    DNS:*.mydomain.de, DNS:mydomain.de

Seemed to be a hard Job, to get that to work. And in the Docker logs i cant find any helpful Information, which points me in the right direction.

After 20 times new installation of debian and docker, forward and backward, left and right, trying to set this up, I finally got it to work, with an alternative Howto, which is (unfortunately for englisch speakers) in german!

But better than nothing:

There you will get N8N with POSTGRE SQL DB and NGINX RevProxy as a Docker Solution! This Approach was far easier for me to set up.

Maybe for others, who have the same problems like me, this could be the solution!

1 Like

Hey @wos im glad you found a solution to the issue, kindly your response as the solution to help others who might face this same thing in the future.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.