Logo error: Mixed Content: The page at 'https:....' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http:....png'. This request has been blocked; the content must be served over HTTPS

Hi @david

@Access-InTech is my colleague who set up the server and Traefik. So the posted yml files are the ones we are already using. I hope you are anyone else can suggest what could be the issue here.

The logo is displayed:

  • at the top left corner where you can select the company
  • in the settings
  • in the client portal
  • in the invoice at the “customize” setting while “HTML Mode” is activated.

The logo is missing:

  • in the invoice at the “customize” setting while “HTML Mode” is deactivated.
  • in the pdf files
  • in the pdf preview when creating an invoice.

Thanks for any help.
Gijs

Hi @david

I have changed the env file and set PDF_GENERATOR=snappdf to PDF_GENERATOR=phantom.
Now the logo is visible. So the error has to come from a wrong setting or permission with snappdf. Do you have any idea, where to start looking? I would love to stay with snappdf as it is the recommended way to go. It also works great on a server I tested with a regular installation. But in future we would like to use docker.

Thanks,
Gijs

Ok, this is a big hint.

What this means is the container cannot resolve itself correctly, have you configured in the hosts file the IP address and domain name?

Hi @david

besides the env file, we’ve modified nothing else.

Has the container to be resolved from within the docker (local) network, or from the internet?

Kind regards
@Access-InTech

Snappdf works by using a local, headless instance of chromium to load the invoice html and generate the pdf. If that chromium instance can’t access the logo url (i.e. DNS not set up etc, or something in your infrastructure is preventing it from connecting to its own external ip, such as a modem/router/firewall that doesn’t support nat loopback) it will be blank.

I’m not familiar with docker, but see if there is a way for you to add your app url to /etc/hosts and resolve to 127.0.0.1 it would look something like subdomain.app.domain 127.0.0.1

If you are using a self signed cert you may also try adding the following to .env SNAPPDF_CHROMIUM_ARGUMENTS="--headless --ignore-certificate-errors "

From what I understand it will overwrite all existing arguments snappdf runs chromium with. You must have --headless in there or chromium with crash.

--ignore-certificate-errorswill allow chromium to ignore cert errors when loading the logo url.
@ben is the maintainer of snappdf he might pitch in and let you know if any other arguments might need to be added when overwriting default chromium behaviour.

The above variable and it’s arguements doesn’t seem to be well documented, dug it up somewhere from the source when was trying to resolve the same issue we were having hosting on a vm.
In our case just adding the app url to hosts and setting it to resolve to 127.0.0.1 seemed to fix it. And snapdf/chromium didn’t seem to have any issues with our self signed cert without overwriting default arguments.

Don’t forget to run php artisan optimize as web user after modifying .env.
The instructions may need to be tweaked to suit docker, as simply making changes to /etc/hosts will probably not survive a reboot/update, not very familiar with docker.

1 Like

Hi @strider27

thank you for your response.

This already has been added to the docker-compose.yml file and the hosts file seemed to be modified while the init process, because we haven’t touched it so far and it looks like you’ve described above:
image

This hosts file is mounted into the app service only. So I guess there should be no need to add it to the server service (aka nginx) as well?

Inside the app container, I am receiving a Failed to connect to xxx port yyy after 0 ms: Connection refused, no matter how I try to curl the logo ressource.

Inside the App container

~ $ uri='/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png'
~ $
~ $ for domain in crm.ecomsilio.de localhost; do for port in 80 443 9000; do echo "Trying ${domain}:${port}${uri}..."; curl -sSLI ${domain}:${port}${uri};
 done; done
Trying crm.ecomsilio.de:80/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (7) Failed to connect to crm.ecomsilio.de port 80 after 0 ms: Connection refused
Trying crm.ecomsilio.de:443/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (7) Failed to connect to crm.ecomsilio.de port 443 after 0 ms: Connection refused
Trying crm.ecomsilio.de:9000/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (56) Recv failure: Connection reset by peer
Trying localhost:80/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (7) Failed to connect to localhost port 80 after 0 ms: Connection refused
Trying localhost:443/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (7) Failed to connect to localhost port 443 after 0 ms: Connection refused
Trying localhost:9000/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/OW0xzlNjPoXbiJCEG94MX5yeRaSYjnVSr3lA6eye.png...
curl: (56) Recv failure: Connection reset by peer
~ $

Btw:

Those steps has been done, as well:

To ensure folder permissions are correct when the container comes up for the first time it is important that you set the correct folder permissions on the docker folder.

From the terminal run

chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/app

Inside the server service(nginx), I am able to curl the logo via http (Port 80)
Well, that should make sense, because the nginx is the “Webserver” who should be able to serve the app’s files. Due to the Traefik edge service, port 443 is bound to traefik instead of the nginx container.


Sorry for multi posting, but I am only allowed to post 1 media per post :smiley:

Sorry the docker side of things is over my head as am not familiar enough with it.

Hi @strider27

thanks so mich for your input.

We are not using a self signed certificate but I tried your suggestion anyway. But after that change, I get an error 500 when I try to create an invoice. There is no preview anymore and nothing else.

@ben and @hillel or @david What is the big difference between the pdf generation processes?
In my case snappdf still does not show the logo. But phantomjs and hosted_ninja work fine. So I am almost thinking of switching to either phantomjs or hosted_ninja.

Although I still would like to get snappdf working.

Thanks a lot,
Gijs

Don’t think it’s an ssl issue in your case so no need to troubleshoot this, just revert.

SnapPDF runs on the same host (in your case inside the container I guess) as Invoiceninja, it takes the html generated by invoice ninja, opens it in an instance of headless (means no visual output to user) chromium browser, which renders the html and stores it as a PDF file. All this is done without any info/data leaving your server. Your problem is that the chromium browser instance that runs within your container, can’t access the url that has the image, from within that container, (it could be on a different port internally which is then forwarded to 443 externally etc)

In case of PhantomJS and Hosted, the generated html is forwarded to another server (phantomJS Cloud or InvoiceNinja) rendered there and a PDF file is returned to you.
The only difference is where the html is rendered and pdf is compiled, in this case on somebody else’s server. This is theoretically slower (especially for large files etc.)
It seems that that server can access the jpg from outside your host/container.

As you are in Germany this may also be an issue from the GDPR compliance perspective, as you are sending your clients data to a third party for processing. If you decide to go this route you would need to obtain GDPR policy statements from the data processor, make sure they are compliant, disclose that info to clients etc. etc. etc. (it’s a pain in the ass)

Had Another look at this:

The only docker I use is on UNRAID for personal use and rarely if ever stray past UI. Like docker for dummies, but will try to help.

Can you try figuring out what the IP of your app is within the docker network?

docker ps -a to get the container ID

docker ps | tail -n +2 | while read cid b; do echo -n "$cid\t"; docker inspect $cid | grep IPAddress | cut -d \" -f 4; done

Look for the ID from step 1 it should have the IP underneath.

Can you try changing config/hosts or /etc/hosts (whichever it is in docker) so crm.ecomsilio.de resolves to the docker network container IP (alternatively you can also try host LAN IP, or external IP.)

This seems to have helped the guy below:

1 Like

So the curl issue would most likely be the same reason the app is not displaying the logo as it cannot reach itself to pull in the image.

Could this be a networking issue itself with Traefik?

Here’s how the internal docker network is resolving the container names:

So I guess the loopback address has to be set to traefik, because that’s the service which is reachable “from the outside”?
Or has it to be set to app, because that’s the service where the headless Chrome is executed?

Well, the less hops it has to do the better/faster it would be.

I would try app first, if that doesn’t work try server, then traefik.

You may have to adjust the hosts files for the server container as well as I don’t know if snappdf is running under app or server. As mentioned not familiar with docker structure at all.

2 Likes

Just as a follow up, I’ve seen this pop up a few times, so I’ve reworked the logo retrieval from docker containers to inject the base64 version, so this should be resolved in the next release.

2 Likes

Thanks David,

we will wait for the update and give it another try.

Thanks,
Gijs

Hi @david,

I just updated to 5.5.0 and the logo is now instantly displayed. From my feeling, the whole application also got a bit faster.

Thank you for all you effort! Also big thanks to @strider27 and @hillel. And to my admin @Access-InTech for trying out all this stuff.

Thanks :beers:
Gijs

2 Likes

@ecomsilio

Thanks for the update, I am glad we resolved this. I think this solution is better than trying to get the containers resolving themselves.

Interesting to hear that the app feels faster, it may be the PHP 8.1 upgrade :slight_smile:

1 Like

Hey there. I also have this problem now. I wanted to have both or switch from HTTP to HTTPS.

Mixed Content: The page at 'https://invoice.int.domain.de/#/dashboard' was loaded over HTTPS, but requested an insecure image 'http://192.168.178.29:8002/storage/9qxkACbh3hvxSufnxsQJIO9j1AcLNxbE/0I1OfmD0NGCfFCNzIcdHNM8o4PI3HERLDB122wbj.png'. This request has been blocked; the content must be served over HTTPS.

The image is also available over HTTPS. I’m using the Docker example setup just without the hosts part. On top of it, I run NGINX Proxy Manager as a reverse proxy. Did I miss the solution? It’s an internal proxy host I want to have.

Another question. Logos in e-mails are not loading as well. Is it because InvoiceNinja is not externally available?

The URL looks like this but even if I change it to the internal HTTPS variant it does not work.
https://ci3.googleusercontent.com/meips/ADKq_Nb_ERuGazKSKYjZTtTWGovWFp7Fz4XsqJ4ylj6GfVSCfS7qmhFvi16VW_UE1zYpGfLW1E9-iGC-tlXTd-mrJ7ATl36bDyqA6A=s0-d-e1-ft#http://192.168.178.29:8002/images/emails/forum.png