SSL error behind Nginx proxy #519

Open
opened 2026-02-04 20:07:15 +03:00 by OVERLORD · 21 comments
Owner

Originally created by @satonotdead on GitHub (Jun 1, 2024).

I followed the example (as per the documentation) and verified that the container is running well on localhost. However, I can't connect to it from my domain, even though I've set up the certificates and DNS correctly.

What could be causing this issue? Is there a variable or configuration, such as VIRTUAL_HOSTNAME that I need to set?

Thanks!

Originally created by @satonotdead on GitHub (Jun 1, 2024). I followed the example (as per the documentation) and verified that the container is running well on localhost. However, I can't connect to it from my domain, even though I've set up the certificates and DNS correctly. What could be causing this issue? Is there a variable or configuration, such as `VIRTUAL_HOSTNAME` that I need to set? Thanks!
OVERLORD added the help wanted label 2026-02-04 20:07:15 +03:00
Author
Owner

@dev0T commented on GitHub (Jun 2, 2024):

Same thing here, can't get it to work through https

@dev0T commented on GitHub (Jun 2, 2024): Same thing here, can't get it to work through https
Author
Owner

@Dherlou commented on GitHub (Jun 8, 2024):

I just setup Planka behind an nginx (reverse) proxy with TLS-termination at the proxy-level. Both planka and nginx are containers inside the same docker network. I use letsencrypt certificates created by certbot in another container.

Here are the relevant snippets that I changed. Btw, I setup Planka to be available behind a specific path, i.e. https://{domain}/{path}. As far as I can tell, this setup seems to work, although some optimization regarding the official documentation might be needed, but this should be a good starting point.

nginx.conf

server {
    listen 443 ssl;
    server_name <domain>;

    ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location /<path>/ {
        proxy_pass http://<planka-container>:1337;
        rewrite ^/<path>/(.*)$ /$1 break;
    }

docker-compose.yml

services:
  planka-app:
    container_name: <planka-container>
    ...
    environment:
      - BASE_URL=https://<domain>/<path>
@Dherlou commented on GitHub (Jun 8, 2024): I just setup Planka behind an nginx (reverse) proxy with TLS-termination at the proxy-level. Both planka and nginx are containers inside the same docker network. I use letsencrypt certificates created by certbot in another container. Here are the relevant snippets that I changed. Btw, I setup Planka to be available behind a specific path, i.e. https://{domain}/{path}. As far as I can tell, this setup seems to work, although some optimization regarding the official documentation might be needed, but this should be a good starting point. **nginx.conf** ```conf server { listen 443 ssl; server_name <domain>; ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location /<path>/ { proxy_pass http://<planka-container>:1337; rewrite ^/<path>/(.*)$ /$1 break; } ``` **docker-compose.yml** ```conf services: planka-app: container_name: <planka-container> ... environment: - BASE_URL=https://<domain>/<path> ```
Author
Owner

@satonotdead commented on GitHub (Jun 12, 2024):

I'm still getting a wrong certificate error with that configuration. I'm using a subdomain and have tried both localhost and the container IP.

I suspect the issue is that docs assumes everyone is using a Docker container for Nginx, which isn't true for all of us. I prefer to host Nginx on the host machine to reduce attack vectors.

@satonotdead commented on GitHub (Jun 12, 2024): I'm still getting a `wrong certificate` error with that configuration. I'm using a subdomain and have tried both `localhost` and the `container IP`. I suspect the issue is that docs assumes everyone is using a Docker container for Nginx, which isn't true for all of us. I prefer to host Nginx on the host machine to reduce attack vectors.
Author
Owner

@RustyClanker commented on GitHub (Jun 13, 2024):

I run Planka on my local network behind Nginx on a different host. I could not find good documentation on it and I was running into the cross-site blocking errors, I had also run into the SSL cert error previously but it was due to using rewrite.

Below is my configuration for the proxy serving Planka, it does not give me a cert error and does not give me grief with cross-site origin. You will also need to do the following:

  • Set BASE_URL in docker-compose.yml to https://<proxy_domain> not to the <upstream_host>:<port>
  • Adjust any paths in the configuration to fit your deployment

In the end the BASE_URL was what was giving me grief for the cross-site issue, so some of the header directives could be unnecessary, I just haven't got around to removing them one by one to see if it breaks.

To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>.

upstream <upstream_host> {
        server <upstream_host>:<port>;
        keepalive 32;
}

server {
        listen 443 ssl; # managed by Certbot
        server_name <proxy_domain>;

        ssl_certificate /etc/letsencrypt/live/<proxy_domain>/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/<proxy_domain>/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

        access_log /var/log/nginx/<proxy_domain>_access.log;
        error_log /var/log/nginx/<proxy_domain>_error.log error;

        location / {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $host:$server_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Frame-Options SAMEORIGIN;
                proxy_set_header X-Scheme $scheme;
                proxy_http_version 1.1;
                proxy_pass http://<upstream defined above>;
                proxy_pass_header Server;
                proxy_pass_request_headers on;
        }

        location /socket.io/ {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_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 $host:$server_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Scheme $scheme;
                proxy_http_version 1.1;
                proxy_pass http://<upstream defined above>;
                proxy_pass_header Server;
        }
}

I hope this helps you and anyone else struggling with running Planka behind an external Nginx server.

@RustyClanker commented on GitHub (Jun 13, 2024): I run Planka on my local network behind Nginx on a different host. I could not find good documentation on it and I was running into the cross-site blocking errors, I had also run into the SSL cert error previously but it was due to using `rewrite`. Below is my configuration for the proxy serving Planka, it does not give me a cert error and does not give me grief with cross-site origin. You will also need to do the following: - Set BASE_URL in `docker-compose.yml` to `https://<proxy_domain>` not to the `<upstream_host>:<port>` - Adjust any paths in the configuration to fit your deployment In the end the BASE_URL was what was giving me grief for the cross-site issue, so some of the header directives could be unnecessary, I just haven't got around to removing them one by one to see if it breaks. To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your `<proxy_domain>`. ``` upstream <upstream_host> { server <upstream_host>:<port>; keepalive 32; } server { listen 443 ssl; # managed by Certbot server_name <proxy_domain>; ssl_certificate /etc/letsencrypt/live/<proxy_domain>/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/<proxy_domain>/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 access_log /var/log/nginx/<proxy_domain>_access.log; error_log /var/log/nginx/<proxy_domain>_error.log error; location / { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Frame-Options SAMEORIGIN; proxy_set_header X-Scheme $scheme; proxy_http_version 1.1; proxy_pass http://<upstream defined above>; proxy_pass_header Server; proxy_pass_request_headers on; } location /socket.io/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_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 $host:$server_port; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Scheme $scheme; proxy_http_version 1.1; proxy_pass http://<upstream defined above>; proxy_pass_header Server; } } ``` I hope this helps you and anyone else struggling with running Planka behind an external Nginx server.
Author
Owner

@satonotdead commented on GitHub (Jun 13, 2024):

Hey, thanks for your following up.

I tried your configuration (removing a few headers and adding new ones) and still not working. I renewed the certificates and restarted everything as well.

Please, can you reformulate this?

To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>.

I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template.

@satonotdead commented on GitHub (Jun 13, 2024): Hey, thanks for your following up. I tried your configuration (removing a few headers and adding new ones) and still not working. I renewed the certificates and restarted everything as well. Please, can you reformulate this? > To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>. I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template.
Author
Owner

@RustyClanker commented on GitHub (Jun 13, 2024):

Please, can you reformulate this?

To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>.

I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template.

When you request a certificate from a signing authority it will either be a wildcard certificate, which can be used for any sub-domain and the primary domain, or for a specific (sub-)domain. If you have self-signed the certificate it needs to be, again, a wildcard or for a specific IP address/(sub-domain). You will also need the full chain (your cert -> intermediates -> root) as well as the private key.

So in other words, the certificate you are using needs to be signed in a way that it is valid for the value of <proxy_domain> used in server_name <proxy_domain>.

@RustyClanker commented on GitHub (Jun 13, 2024): > Please, can you reformulate this? > > > To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>. > > I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template. When you request a certificate from a signing authority it will either be a wildcard certificate, which can be used for any sub-domain and the primary domain, or for a specific (sub-)domain. If you have self-signed the certificate it needs to be, again, a wildcard or for a specific IP address/(sub-domain). You will also need the full chain (your cert -> intermediates -> root) as well as the private key. So in other words, the certificate you are using needs to be signed in a way that it is valid for the value of `<proxy_domain>` used in `server_name <proxy_domain>`.
Author
Owner

@michaeledi commented on GitHub (Jun 13, 2024):

I run Planka on my local network behind Nginx on a different host. I could not find good documentation on it and I was running into the cross-site blocking errors, I had also run into the SSL cert error previously but it was due to using rewrite.

Below is my configuration for the proxy serving Planka, it does not give me a cert error and does not give me grief with cross-site origin. You will also need to do the following:

  • Set BASE_URL in docker-compose.yml to https://<proxy_domain> not to the <upstream_host>:<port>
  • Adjust any paths in the configuration to fit your deployment

In the end the BASE_URL was what was giving me grief for the cross-site issue, so some of the header directives could be unnecessary, I just haven't got around to removing them one by one to see if it breaks.

To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>.

upstream <upstream_host> {
        server <upstream_host>:<port>;
        keepalive 32;
}

server {
        listen 443 ssl; # managed by Certbot
        server_name <proxy_domain>;

        ssl_certificate /etc/letsencrypt/live/<proxy_domain>/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/<proxy_domain>/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

        access_log /var/log/nginx/<proxy_domain>_access.log;
        error_log /var/log/nginx/<proxy_domain>_error.log error;

        location / {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $host:$server_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Frame-Options SAMEORIGIN;
                proxy_set_header X-Scheme $scheme;
                proxy_http_version 1.1;
                proxy_pass http://<upstream defined above>;
                proxy_pass_header Server;
                proxy_pass_request_headers on;
        }

        location /socket.io/ {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_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 $host:$server_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Scheme $scheme;
                proxy_http_version 1.1;
                proxy_pass http://<upstream defined above>;
                proxy_pass_header Server;
        }
}

I hope this helps you and anyone else struggling with running Planka behind an external Nginx server.

Thanks! This solved my mix-content issue like a charm.

@michaeledi commented on GitHub (Jun 13, 2024): > I run Planka on my local network behind Nginx on a different host. I could not find good documentation on it and I was running into the cross-site blocking errors, I had also run into the SSL cert error previously but it was due to using `rewrite`. > > Below is my configuration for the proxy serving Planka, it does not give me a cert error and does not give me grief with cross-site origin. You will also need to do the following: > > * Set BASE_URL in `docker-compose.yml` to `https://<proxy_domain>` not to the `<upstream_host>:<port>` > * Adjust any paths in the configuration to fit your deployment > > In the end the BASE_URL was what was giving me grief for the cross-site issue, so some of the header directives could be unnecessary, I just haven't got around to removing them one by one to see if it breaks. > > To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your `<proxy_domain>`. > > ``` > upstream <upstream_host> { > server <upstream_host>:<port>; > keepalive 32; > } > > server { > listen 443 ssl; # managed by Certbot > server_name <proxy_domain>; > > ssl_certificate /etc/letsencrypt/live/<proxy_domain>/fullchain.pem; # managed by Certbot > ssl_certificate_key /etc/letsencrypt/live/<proxy_domain>/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 > > access_log /var/log/nginx/<proxy_domain>_access.log; > error_log /var/log/nginx/<proxy_domain>_error.log error; > > location / { > proxy_set_header Upgrade $http_upgrade; > proxy_set_header Connection "upgrade"; > proxy_set_header Host $http_host; > proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; > proxy_set_header X-Forwarded-Host $host:$server_port; > proxy_set_header X-Forwarded-Proto $scheme; > proxy_set_header X-Frame-Options SAMEORIGIN; > proxy_set_header X-Scheme $scheme; > proxy_http_version 1.1; > proxy_pass http://<upstream defined above>; > proxy_pass_header Server; > proxy_pass_request_headers on; > } > > location /socket.io/ { > proxy_set_header Upgrade $http_upgrade; > proxy_set_header Connection "upgrade"; > proxy_set_header Host $http_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 $host:$server_port; > proxy_set_header X-Forwarded-Proto $scheme; > proxy_set_header X-Scheme $scheme; > proxy_http_version 1.1; > proxy_pass http://<upstream defined above>; > proxy_pass_header Server; > } > } > ``` > > I hope this helps you and anyone else struggling with running Planka behind an external Nginx server. Thanks! This solved my `mix-content` issue like a charm.
Author
Owner

@satonotdead commented on GitHub (Jun 14, 2024):

Please, can you reformulate this?

To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>.

I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template.

When you request a certificate from a signing authority it will either be a wildcard certificate, which can be used for any sub-domain and the primary domain, or for a specific (sub-)domain. If you have self-signed the certificate it needs to be, again, a wildcard or for a specific IP address/(sub-domain). You will also need the full chain (your cert -> intermediates -> root) as well as the private key.

So in other words, the certificate you are using needs to be signed in a way that it is valid for the value of <proxy_domain> used in server_name <proxy_domain>.

Thanks, I'm using Let's Encrypt and signing certificates for each subdomain. I'm hosting ~30 services and that's the only facing this SSL issue.

I'm sadly moving to another service because I tried a lot of modifications without success.

@satonotdead commented on GitHub (Jun 14, 2024): > > Please, can you reformulate this? > > > To note: I run bind on my network for resolving my LAN domains, you will run into issues if your cert is signed against a certain domain and you try to use it with an IP address as your <proxy_domain>. > > > > > > I suspect the issue is related to this and not on the Nginx configuration, which appears to be a commonly used template. > > When you request a certificate from a signing authority it will either be a wildcard certificate, which can be used for any sub-domain and the primary domain, or for a specific (sub-)domain. If you have self-signed the certificate it needs to be, again, a wildcard or for a specific IP address/(sub-domain). You will also need the full chain (your cert -> intermediates -> root) as well as the private key. > > So in other words, the certificate you are using needs to be signed in a way that it is valid for the value of `<proxy_domain>` used in `server_name <proxy_domain>`. Thanks, I'm using Let's Encrypt and signing certificates for each subdomain. I'm hosting ~30 services and that's the only facing this SSL issue. I'm sadly moving to another service because I tried a lot of modifications without success.
Author
Owner

@marigbede commented on GitHub (Jun 24, 2024):

@satoshinotdead

I would suggest you follow the following links one after the other.

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

However, you must ensure that the following have been achieved before you start.

  1. The Host has permissions to allow port 80 and 443
  2. The A Record (and maybe CNAME) for the desired Domain Name (or Sub Domain) has been configured and it is resolving properly.
@marigbede commented on GitHub (Jun 24, 2024): @satoshinotdead I would suggest you follow the following links one after the other. https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04 https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04 https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04 However, you must ensure that the following have been achieved before you start. 1. The Host has permissions to allow port 80 and 443 2. The A Record (and maybe CNAME) for the desired Domain Name (or Sub Domain) has been configured and it is resolving properly.
Author
Owner

@satonotdead commented on GitHub (Jun 25, 2024):

@marigbede Thanks for the information, I prefer to use the official docs and skip hosting providers ones.

I have more than 50 services running. The issue I posted (and few folks around) is related with the Planka architecture and has nothing to do with installing Nginx and/or Docker.

@satonotdead commented on GitHub (Jun 25, 2024): @marigbede Thanks for the information, I prefer to use the official docs and skip hosting providers ones. I have more than 50 services running. The issue I posted (and few folks around) is related with the Planka architecture and has nothing to do with installing Nginx and/or Docker.
Author
Owner

@marigbede commented on GitHub (Jun 25, 2024):

@satoshinotdead Nice going. The documentation does not bind you to Digital Ocean because I have used those steps in all manner of places. I can take a look at your issue if you would like and if for nothing, just another fresh pair of eyes perspective.

@marigbede commented on GitHub (Jun 25, 2024): @satoshinotdead Nice going. The documentation does not bind you to Digital Ocean because I have used those steps in all manner of places. I can take a look at your issue if you would like and if for nothing, just another fresh pair of eyes perspective.
Author
Owner

@satonotdead commented on GitHub (Jun 27, 2024):

@marigbede thanks man, I'm just trying to figure it out.

My configuration is Nginx as Proxy and docker-compose Planka container.

I don't want to containerize Nginx and I usually proxy from it to localhost and port exposed from docker (to localhost or using upstream to container IP).

I understand that's the base for everything else but I see that not everyone host their files and/or manage their own servers. Maybe I'm wrong but I think there are a corporate standard that don't fit with all of us.

I like to be simple when managing my stuff. So, if I have Nginx then I don't want an application bloated with another instance of Nginx.

Tried to use localhost and docker IP like upstream and proxied. Perhaps I need to expose the ports from Planka to localhost?

Planka is asking for Javascript on curl (that's OK, it's working) but there is impossible to proxy to it.

@satonotdead commented on GitHub (Jun 27, 2024): @marigbede thanks man, I'm just trying to figure it out. My configuration is Nginx as Proxy and docker-compose Planka container. I don't want to containerize Nginx and I usually proxy from it to localhost and port exposed from docker _(to localhost or using upstream to container IP)_. I understand that's the base for everything else but I see that not everyone host their files and/or manage their own servers. Maybe I'm wrong but I think there are a _corporate_ standard that don't fit with all of us. I like to be simple when managing my stuff. So, if I have Nginx then I don't want an application ~~bloated~~ with another instance of Nginx. Tried to use localhost and docker IP like upstream and proxied. Perhaps I need to expose the ports from Planka to localhost? Planka is asking for Javascript on curl (that's OK, it's working) but there is impossible to proxy to it.
Author
Owner

@daniel-hiller commented on GitHub (Jul 14, 2024):

Hi,
Planka is working just fine with a normally installed NGINX. 
I do it the same way in the Planka installer. 

Here is the config: https://github.com/plankanban/planka-installer/blob/main/config/nginx-planka.conf.
That configuration is working just fine on a freshly installed nginx (Debian, Ubuntu, and CentOS)

You just need to add a cert (the certbot will be your friend).

I wrote it so often in the issues, but here again: You need to adjust the BASE_URL=https://your.domain.tld

@daniel-hiller commented on GitHub (Jul 14, 2024): Hi, Planka is working just fine with a normally installed NGINX.  I do it the same way in the Planka installer.  Here is the config: https://github.com/plankanban/planka-installer/blob/main/config/nginx-planka.conf. That configuration is working just fine on a freshly installed nginx (Debian, Ubuntu, and CentOS) You just need to add a cert (the certbot will be your friend). I wrote it so often in the issues, but here again: You need to adjust the `BASE_URL=https://your.domain.tld`
Author
Owner

@bkostrowiecki commented on GitHub (Sep 24, 2024):

I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault.

@bkostrowiecki commented on GitHub (Sep 24, 2024): I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault.
Author
Owner

@satonotdead commented on GitHub (Sep 26, 2024):

I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault.

Hey, thanks for your reply. Can you share your Nginx and docker-compose.yml template?

I'm aware that's very probable I'm missing something.

@satonotdead commented on GitHub (Sep 26, 2024): > I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault. Hey, thanks for your reply. Can you share your Nginx and `docker-compose.yml` template? I'm aware that's very probable I'm missing something.
Author
Owner

@Delares commented on GitHub (Dec 29, 2024):

I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault.

Good afternoon. I would be very grateful if you could possibly provide some guidance on how you managed to achieve this. I have attempted to solve the problem of external access to the plan, but unfortunately I have not been successful.

@Delares commented on GitHub (Dec 29, 2024): > I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault. Good afternoon. I would be very grateful if you could possibly provide some guidance on how you managed to achieve this. I have attempted to solve the problem of external access to the plan, but unfortunately I have not been successful.
Author
Owner

@bkostrowiecki commented on GitHub (Jan 9, 2025):

I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault.

Hey, thanks for your reply. Can you share your Nginx and docker-compose.yml template?

I'm aware that's very probable I'm missing something.

Here's my docker-compose.yaml file, but I'm sure it's just the default

version: '3'

services:
  planka:
    image: ghcr.io/plankanban/planka:latest
    restart: on-failure
    volumes:
      - user-avatars:/app/public/user-avatars
      - project-background-images:/app/public/project-background-images
      - attachments:/app/private/attachments
    ports:
      - 3006:1337
    environment:
      - BASE_URL=https://planka.mydomain.com
      - DATABASE_URL=postgresql://postgres@postgres/planka
      - SECRET_KEY=e033fd4aca4217f4c7b18e33d9fd23181126611c525a98d560aaca3d6cc95f883eda67901b32211da77a49e433e9adf961e31b729731d9a36c57523c1ef43a4a

      # - TRUST_PROXY=0
      # - TOKEN_EXPIRES_IN=365 # In days

      # related: https://github.com/knex/knex/issues/2354
      # As knex does not pass query parameters from the connection string we
      # have to use environment variables in order to pass the desired values, e.g.
      # - PGSSLMODE=<value>

      # Configure knex to accept SSL certificates
      # - KNEX_REJECT_UNAUTHORIZED_SSL_CERTIFICATE=false

      - DEFAULT_ADMIN_EMAIL=bartosz@mydomain.com # Do not remove if you want to prevent this user from being edited/deleted
      - DEFAULT_ADMIN_PASSWORD=mypassword
      - DEFAULT_ADMIN_NAME=Bartosz
      - DEFAULT_ADMIN_USERNAME=bartosz

      # - SHOW_DETAILED_AUTH_ERRORS=false # Set to true to show more detailed authentication error messages. It should not be enabled without a rate limiter for security reasons.

      # - ALLOW_ALL_TO_CREATE_PROJECTS=true

      # - OIDC_ISSUER=
      # - OIDC_CLIENT_ID=
      # - OIDC_CLIENT_SECRET=
      # - OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG=
      # - OIDC_USERINFO_SIGNED_RESPONSE_ALG=
      # - OIDC_SCOPES=openid email profile
      # - OIDC_RESPONSE_MODE=fragment
      # - OIDC_USE_DEFAULT_RESPONSE_MODE=true
      # - OIDC_ADMIN_ROLES=admin
      # - OIDC_EMAIL_ATTRIBUTE=email
      # - OIDC_NAME_ATTRIBUTE=name
      # - OIDC_USERNAME_ATTRIBUTE=preferred_username
      # - OIDC_ROLES_ATTRIBUTE=groups
      # - OIDC_IGNORE_USERNAME=true
      # - OIDC_IGNORE_ROLES=true
      # - OIDC_ENFORCED=true

      # Email Notifications (https://nodemailer.com/smtp/)
      # - SMTP_HOST=
      # - SMTP_PORT=587
      # - SMTP_NAME=
      # - SMTP_SECURE=true
      # - SMTP_USER=
      # - SMTP_PASSWORD=
      # - SMTP_FROM="Demo Demo" <demo@demo.demo>

      # Optional fields: accessToken, events, excludedEvents
      # - |
      #   WEBHOOKS=[{
      #     "url": "http://localhost:3001",
      #     "accessToken": "notaccesstoken",
      #     "events": ["cardCreate", "cardUpdate", "cardDelete"],
      #     "excludedEvents": ["notificationCreate", "notificationUpdate"]
      #   }]

      # - SLACK_BOT_TOKEN=
      # - SLACK_CHANNEL_ID=
      # - GOOGLE_CHAT_WEBHOOK_URL=
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:14-alpine
    restart: on-failure
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=planka
      - POSTGRES_HOST_AUTH_METHOD=trust
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d planka"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  user-avatars:
  project-background-images:
  attachments:
  db-data:

Here's my nginx configuration regarding planka:

(...)
server {
      listen       *:443 ssl;
      server_name  planka.mydomain.com;
      ssl_certificate      C:\\cert\\_.mydomain.com-crt.pem;
      ssl_certificate_key  C:\\cert\\_.mydomain.com-key.pem;
      ssl_session_cache    shared:SSL:1m;
      ssl_session_timeout  5m;
      ssl_ciphers  HIGH:!aNULL:!MD5;
      ssl_prefer_server_ciphers  on;

      location / {
         client_max_body_size       256000000m;
         client_body_buffer_size    8m;
         proxy_pass  http://127.0.0.1:3006;
         proxy_set_header Connection $http_connection;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-Host $host;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
   }
}
(...)
@bkostrowiecki commented on GitHub (Jan 9, 2025): > > I successfully configured dockerized Planka and Nginx Reverse Proxy on Windows Host machine, so I think the real problem is how someone configures Nginx and Docker as it seems like it's not Planka fault. > > Hey, thanks for your reply. Can you share your Nginx and `docker-compose.yml` template? > > I'm aware that's very probable I'm missing something. Here's my docker-compose.yaml file, but I'm sure it's just the default ``` version: '3' services: planka: image: ghcr.io/plankanban/planka:latest restart: on-failure volumes: - user-avatars:/app/public/user-avatars - project-background-images:/app/public/project-background-images - attachments:/app/private/attachments ports: - 3006:1337 environment: - BASE_URL=https://planka.mydomain.com - DATABASE_URL=postgresql://postgres@postgres/planka - SECRET_KEY=e033fd4aca4217f4c7b18e33d9fd23181126611c525a98d560aaca3d6cc95f883eda67901b32211da77a49e433e9adf961e31b729731d9a36c57523c1ef43a4a # - TRUST_PROXY=0 # - TOKEN_EXPIRES_IN=365 # In days # related: https://github.com/knex/knex/issues/2354 # As knex does not pass query parameters from the connection string we # have to use environment variables in order to pass the desired values, e.g. # - PGSSLMODE=<value> # Configure knex to accept SSL certificates # - KNEX_REJECT_UNAUTHORIZED_SSL_CERTIFICATE=false - DEFAULT_ADMIN_EMAIL=bartosz@mydomain.com # Do not remove if you want to prevent this user from being edited/deleted - DEFAULT_ADMIN_PASSWORD=mypassword - DEFAULT_ADMIN_NAME=Bartosz - DEFAULT_ADMIN_USERNAME=bartosz # - SHOW_DETAILED_AUTH_ERRORS=false # Set to true to show more detailed authentication error messages. It should not be enabled without a rate limiter for security reasons. # - ALLOW_ALL_TO_CREATE_PROJECTS=true # - OIDC_ISSUER= # - OIDC_CLIENT_ID= # - OIDC_CLIENT_SECRET= # - OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG= # - OIDC_USERINFO_SIGNED_RESPONSE_ALG= # - OIDC_SCOPES=openid email profile # - OIDC_RESPONSE_MODE=fragment # - OIDC_USE_DEFAULT_RESPONSE_MODE=true # - OIDC_ADMIN_ROLES=admin # - OIDC_EMAIL_ATTRIBUTE=email # - OIDC_NAME_ATTRIBUTE=name # - OIDC_USERNAME_ATTRIBUTE=preferred_username # - OIDC_ROLES_ATTRIBUTE=groups # - OIDC_IGNORE_USERNAME=true # - OIDC_IGNORE_ROLES=true # - OIDC_ENFORCED=true # Email Notifications (https://nodemailer.com/smtp/) # - SMTP_HOST= # - SMTP_PORT=587 # - SMTP_NAME= # - SMTP_SECURE=true # - SMTP_USER= # - SMTP_PASSWORD= # - SMTP_FROM="Demo Demo" <demo@demo.demo> # Optional fields: accessToken, events, excludedEvents # - | # WEBHOOKS=[{ # "url": "http://localhost:3001", # "accessToken": "notaccesstoken", # "events": ["cardCreate", "cardUpdate", "cardDelete"], # "excludedEvents": ["notificationCreate", "notificationUpdate"] # }] # - SLACK_BOT_TOKEN= # - SLACK_CHANNEL_ID= # - GOOGLE_CHAT_WEBHOOK_URL= depends_on: postgres: condition: service_healthy postgres: image: postgres:14-alpine restart: on-failure volumes: - db-data:/var/lib/postgresql/data environment: - POSTGRES_DB=planka - POSTGRES_HOST_AUTH_METHOD=trust healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d planka"] interval: 10s timeout: 5s retries: 5 volumes: user-avatars: project-background-images: attachments: db-data: ``` Here's my nginx configuration regarding planka: ``` (...) server { listen *:443 ssl; server_name planka.mydomain.com; ssl_certificate C:\\cert\\_.mydomain.com-crt.pem; ssl_certificate_key C:\\cert\\_.mydomain.com-key.pem; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { client_max_body_size 256000000m; client_body_buffer_size 8m; proxy_pass http://127.0.0.1:3006; proxy_set_header Connection $http_connection; proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } (...) ```
Author
Owner

@jorgecarleitao commented on GitHub (Jul 20, 2025):

This is not Planka - I could configure this as intended following the documentation for Caddy - absolutely no surprises using

BASE_URL: https://example.com
TRUST_PROXY: true

in docker compose.

@jorgecarleitao commented on GitHub (Jul 20, 2025): This is not Planka - I could configure this as intended following the documentation for Caddy - absolutely no surprises using ``` BASE_URL: https://example.com TRUST_PROXY: true ``` in docker compose.
Author
Owner

@brennanag commented on GitHub (Jan 19, 2026):

I have been trying to get planka to work with my nginx install and I guess it's not for me. So frustrating! I wish this was more friendly for people to install. As someone kind of new to this sort of thing, why are some services quite easy to install and some like this quite hard?

@brennanag commented on GitHub (Jan 19, 2026): I have been trying to get planka to work with my nginx install and I guess it's not for me. So frustrating! I wish this was more friendly for people to install. As someone kind of new to this sort of thing, why are some services quite easy to install and some like this quite hard?
Author
Owner

@Dherlou commented on GitHub (Jan 19, 2026):

How does your setup look like?

Generally speaking, setup complexity depends on the use case.

What you always need is some kind of service discovery, so that your proxy knows where the actual app lives, so that it can proxy there:

  • host (always needed)
  • port (needed with nginx, some other proxies like Traefik can infer this from the container's exposed ports)

The application in the container also needs to know under which URL it lives infront of the proxy (e.g. for link generation). Sometimes, it works implicitly if the app reads the X-Forwarded-* or X-Real-IP headers set by the proxy. Sometimes, it needs to be explicitly defined, e.g. if the proxy does not set these headers by default, the app does not read those headers, needs explicit configuration for trusting the proxy's headers or needs to know its URL without user interaction (e.g. during cron execution). However, how you need to define this, depends completely on the application that you want to proxy. Sometimes, an environment variable is enough, sometimes it needs multiple, sometimes it needs changes in a configuration file and sometimes you cannot even configure it (if the application has no support for being proxied at all).

Sometimes, it gets even worse and the application itself does not ship a webserver for asset serving (like media files) and expects that a reverse proxy is used to serve static files, because its own webserver only processes script files. That is what Tandoor did until v2.3.

Depending on your setup (e.g. if you only use one domain for everything), you may want to map the path /path in front of the proxy to the path / behind the proxy, which needs additional configuration, like in my example above.

At the moment, my preferred setup is using docker containers for all my applications, so that I can use traefik as a proxy. Traefik has some nice features like generating and utilizing TLS-Certificates on demand with a very simple configuration. It also allows to define its configuration as container or service tags directly on the services/containers to be proxied, so that all relevant configuration lives in one place.

@Dherlou commented on GitHub (Jan 19, 2026): How does your setup look like? Generally speaking, setup complexity depends on the use case. What you _always_ need is some kind of service discovery, so that your proxy knows where the actual app lives, so that it can proxy there: - host (always needed) - port (needed with nginx, some other proxies like Traefik can infer this from the container's exposed ports) The application in the container also needs to know under which URL it lives infront of the proxy (e.g. for link generation). Sometimes, it works implicitly if the app reads the `X-Forwarded-*` or `X-Real-IP` headers set by the proxy. Sometimes, it needs to be explicitly defined, e.g. if the proxy does not set these headers by default, the app does not read those headers, needs explicit configuration for trusting the proxy's headers or needs to know its URL without user interaction (e.g. during cron execution). However, how you need to define this, depends completely on the application that you want to proxy. Sometimes, an environment variable is enough, sometimes it needs multiple, sometimes it needs changes in a configuration file and sometimes you cannot even configure it (if the application has no support for being proxied at all). Sometimes, it gets even worse and the application itself does _not_ ship a webserver for asset serving (like media files) and expects that a reverse proxy is used to serve static files, because its own webserver only processes script files. That is what [Tandoor](https://github.com/TandoorRecipes/recipes) did until v2.3. Depending on your setup (e.g. if you only use one domain for everything), you may want to map the path `/path` in front of the proxy to the path `/` behind the proxy, which needs additional configuration, like in my [example above](https://github.com/plankanban/planka/issues/775#issuecomment-2156043537). At the moment, my preferred setup is using docker containers for all my applications, so that I can use traefik as a proxy. Traefik has some nice features like generating and utilizing TLS-Certificates on demand with a very simple configuration. It also allows to define its configuration as container or service tags directly on the services/containers to be proxied, so that all relevant configuration lives in one place.
Author
Owner

@jorgecarleitao commented on GitHub (Jan 20, 2026):

With Caddy:

(replace example.com with your domain, and have an A record to your IP)

# Caddyfile
tasks.example.com {
	reverse_proxy tasks:1337 {
		lb_policy cookie api_sticky
		transport http
	}
}

Docker compose:

services:
  proxy:
    image: caddy:2
    container_name: proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"

  tasks:
    image: ghcr.io/plankanban/planka:2.0.0-rc.3
    restart: unless-stopped
    expose:
      - "1337"
    environment:
      BASE_URL: https://tasks.example.com
      TRUST_PROXY: true
      # ... other options you want

deploy:

docker compose up -d
docker cp Caddyfile proxy:/etc/caddy/Caddyfile
docker compose exec -w /etc/caddy proxy caddy reload

if you can't make it work, you need to explain what does not work specifically.

@jorgecarleitao commented on GitHub (Jan 20, 2026): With Caddy: (replace `example.com` with your domain, and have an A record to your IP) ``` # Caddyfile tasks.example.com { reverse_proxy tasks:1337 { lb_policy cookie api_sticky transport http } } ``` Docker compose: ``` services: proxy: image: caddy:2 container_name: proxy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" tasks: image: ghcr.io/plankanban/planka:2.0.0-rc.3 restart: unless-stopped expose: - "1337" environment: BASE_URL: https://tasks.example.com TRUST_PROXY: true # ... other options you want ``` deploy: ```bash docker compose up -d docker cp Caddyfile proxy:/etc/caddy/Caddyfile docker compose exec -w /etc/caddy proxy caddy reload ``` if you can't make it work, you need to explain what does not work specifically.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/planka#519