Portainer: Client sent an HTTP request to an HTTPS server - despite the URL is https://

I am pretty new for the topic server configuration and now I got a problem with to reach a container with ssl certificate.

What is my setup:

I've got a raspberry pi with docker on it. The container which is connected to port 80 and 443 is a reverse proxy which is directing incoming subdomains to different other container. Example: webserver.my-domain.com is leading to IP 192.168.178.69:8080. I archived this through this config in the folder sites-enabled:

<VirtualHost *:80> ServerName webserver.my-domain.com ProxyPreserveHost On DocumentRoot /var/www/html ProxyPass /.well-known ! ProxyPass / ProxyPassReverse / RewriteEngine on RewriteCond %{SERVER_NAME} =webserver.my-domain.com RewriteRule ^ [END,NE,R=permanent] </VirtualHost> 

I also created a let's encrypt certificate inside of the reverse proxy container. This created an additional file webserver-le-ssl.conf:

<IfModule mod_ssl.c> <VirtualHost *:443> ServerName webserver.my-domain.com ProxyPreserveHost On DocumentRoot /var/www/html ProxyPass /.well-known ! ProxyPass / ProxyPassReverse / SSLCertificateFile /etc/letsencrypt/live/ SSLCertificateKeyFile /etc/letsencrypt/live/ Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule> 

So far so good. My content is available if I try the URL .

What is my Problem

I use Portainer to manage my docker container and I want Portainer to be available through portainer.my-domain.com. So this is the portainer config inside of sites-enabled:

<VirtualHost *:80> ServerName portainer.my-domain.com ProxyPreserveHost On DocumentRoot /var/www/html ProxyPass /.well-known ! ProxyPass / ProxyPassReverse / RewriteEngine on RewriteCond %{SERVER_NAME} =portainer.my-domain.com RewriteRule ^ [END,NE,R=permanent] </VirtualHost> 

And also the ssl config for this:

<IfModule mod_ssl.c> <VirtualHost *:443> ServerName portainer.my-domain.com ProxyPreserveHost On DocumentRoot /var/www/html ProxyPass /.well-known ! ProxyPass / ProxyPassReverse / SSLCertificateFile /etc/letsencrypt/live/ SSLCertificateKeyFile /etc/letsencrypt/live/ Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule> 

If I call 192.168.178.69:9443/ I can reach the container without problems. But if I try to reach the URL portainer.my-domain.com I just got the Message:

Client sent an HTTP request to an HTTPS server. 

But in the URL shows: . So I don't understand why there is an HTTP request, even if my browser shows me that the connection is with https.

Can someone explain this to me and show me how to fix this?

Update: My solution With a lot of tries I found a solution: As I run the reverse proxy and the portainer as docker containers, I put both containers into a network with docker-compose:

version: "3.4" services: apache: build: context: . dockerfile: Dockerfile ports: - "80:80" - "443:443" volumes: - /home/pi/reverse-proxy/:/etc/apache2 networks: - homeserver portainer: image: portainer/portainer-ce:latest ports: - "8000:8000" - "9000:9000" - "9443:9443" volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data networks: - homeserver networks: homeserver: volumes: portainer_data: 

The volume of the apache2 is the complete config folder of /etc/apache2. After that I changed the IP of the ProxyPass to the name of the container:

 ProxyPass / ProxyPassReverse / 

After this changes it worked.

2

4 Answers

I had the same problem with Portainer 2.13.1 behind an Apache2 proxy. I solved it by running the image with the option enabling port 9000 which is Portainer's HTTP port. This assumes that you will block port 9000 externally and access it only via the proxy which is protected by HTTPS. This is my command:

docker run -d -p 9000:9000 -p 8000:8000 -p 9443:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data portainer/portainer-ce:latest 

My VirtualHost file then points to port 9000 like so:

<IfModule mod_ssl.c> <VirtualHost *:443> ProxyPreserveHost On Proxyrequests Off ServerName docker.<domain.tld> ServerAdmin admin@<domain.tld> ProxyPass / ProxyPassReverse / ErrorLog ${APACHE_LOG_DIR}/portainer-error.log CustomLog ${APACHE_LOG_DIR}/portainer-access.log combined SSLCertificateFile /etc/letsencrypt/live/docker.<domain.tld>/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/docker.<domain.tld>/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> 

Make sure ports 8000, 9000 and 9443 are not accessible externally using a tool like ufw in Linux.

3

So based on your question it seems that this works

ProxyPass / 

But this does not:

ProxyPass / 

Note that in both cases a plain http:// protocol is used, even though different port are involved. And a port number of 9443 suggests that you are expected https:// and not http:// here. If this is the case this would explain the error message you got: a plain HTTP request is send because of setting the protocol to http:// instead of

But in the URL shows:

This protocol here is relevant for the connection between client and nginx, not between nginx and the inner server. The latter one depends on the protocol given in the ProxyPass URL.

5

Just access the portainer url via https:yourip:yourport instead of just writing yourip:yourport. After you setup ssl and a proxy manager then you can access it via domain.

I have same message.
After research, I solved it like this:
My old url:
My new url:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like