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

Installation: Docker
Version: 5.4.1

I uploaded a logo but it is not being displayed at the invoices. When I preview an invoice or when I customize the invoice design, the logo is displayed as a broken image link.

When I customize the invoice design and toggl on “HTML Mode”, then the logo ist displayed correctly.

When I download the pdf, the logo is also missing.

Everytime the logo fails, there is the following error message in the browser console:

Mixed Content: The page at ‘ecomsilio client portal’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ‘http://crm.ecomsilio.de/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/muZDeSzJ471w6UjVO5a5KEMFfiPscJb8XdQIOvAj.png’. This request has been blocked; the content must be served over HTTPS.

However, the logo is available via https: → https://crm.ecomsilio.de/storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/muZDeSzJ471w6UjVO5a5KEMFfiPscJb8XdQIOvAj.png

The logs do not show any errors. Here is the part where the logo is called via a GET call.

Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:25.146641786Z 172.27.0.5 - - [22/Jul/2022:07:09:25 +0000] "POST /api/v1/preview HTTP/1.1" 200 130485 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:26.876962536Z 2022/07/22 07:09:26 [warn] 32#32: *1 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000002, client: 172.27.0.5, server: _, request: "POST /api/v1/preview HTTP/1.1", host: "crm.ecomsilio.de", referrer: "https://crm.ecomsilio.de/"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:29.550211642Z 172.27.0.5 - - [22/Jul/2022:07:09:29 +0000] "POST /api/v1/preview HTTP/1.1" 200 146190 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:41.681100995Z 2022/07/22 07:09:41 [warn] 32#32: *1 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000003, client: 172.27.0.5, server: _, request: "POST /api/v1/preview?html=true HTTP/1.1", host: "crm.ecomsilio.de", referrer: "https://crm.ecomsilio.de/"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:43.697852597Z 172.27.0.5 - - [22/Jul/2022:07:09:43 +0000] "POST /api/v1/preview?html=true HTTP/1.1" 200 25244 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:43.911353011Z 172.27.0.5 - - [22/Jul/2022:07:09:43 +0000] "GET /storage/tzhBf0Vtho0hoDTfsTY6IR3SnwHf6Enj/muZDeSzJ471w6UjVO5a5KEMFfiPscJb8XdQIOvAj.png HTTP/1.1" 200 37373 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:09:53.902144877Z 172.27.0.5 - - [22/Jul/2022:07:09:53 +0000] "POST /api/v1/refresh?current_company=true&updated_at=1658471695&first_load=true HTTP/1.1" 200 176644 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:10:17.732429277Z 172.27.0.5 - - [22/Jul/2022:07:10:17 +0000] "GET / HTTP/1.1" 200 4898 "-" "Uptime-Kuma/1.17.1" "94.31.104.167"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:10:42.621265620Z 2022/07/22 07:10:42 [warn] 32#32: *1 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000004, client: 172.27.0.5, server: _, request: "PUT /api/v1/companies/VolejRejNm HTTP/1.1", host: "crm.ecomsilio.de", referrer: "https://crm.ecomsilio.de/"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:10:42.729041202Z 172.27.0.5 - - [22/Jul/2022:07:10:42 +0000] "PUT /api/v1/companies/VolejRejNm HTTP/1.1" 200 16101 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:10:46.090808083Z 172.27.0.5 - - [22/Jul/2022:07:10:46 +0000] "PUT /api/v1/companies/VolejRejNm HTTP/1.1" 200 16101 "https://crm.ecomsilio.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "91.2.205.13"
Dev-InvoiceNinja-Webserver  | 2022-07-22T07:11:00.202763182Z 2022/07/22 07:11:00 [warn] 32#32: *1 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000005, client: 172.27.0.5, server: _, request: "PUT /api/v1/companies/VolejRejNm HTTP/1.1", host: "crm.ecomsilio.de", referrer: "https://crm.ecomsilio.de/"

Here is my env configuration:

# IN application vars
APP_NAME="ecomsilio client portal"
APP_ENV=production
APP_URL=https://crm.ecomsilio.de
APP_KEY=base64:xxxxxxxxxxx
APP_DEBUG=true
REQUIRE_HTTPS=true
PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
LOCAL_DOWNLOAD=true
IS_DOCKER=true

TRUSTED_PROXIES=*

EXPANDED_LOGGING=true
LOG_PDF_HTML=true

QUEUE_CONNECTION=database

and here is the docker-compose.yml

services:
  db:
    image: mysql:5
    container_name: Dev-InvoiceNinja-Database
    env_file: env
    restart: always
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw,delegated
    networks:
      - traefik_dev

  app:
    image: invoiceninja/invoiceninja:5
    container_name: Dev-InvoiceNinja-App
    env_file: env
    restart: always
    volumes:
      - ./config/hosts:/etc/hosts:ro
      - ./docker/app/public:/var/www/app/public:rw,delegated
      - ./docker/app/storage:/var/www/app/storage:rw,delegated
    depends_on:
      - db
    networks:
      - traefik_dev

  server:
    image: nginx
    container_name: Dev-InvoiceNinja-Webserver
    env_file: env
    restart: always
    volumes:
      - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
      - ./docker/app/public:/var/www/app/public:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dev-ninja-webserver-router.rule=Host(`crm.ecomsilio.de`)"
      - "traefik.http.routers.dev-ninja-webserver-router.entrypoints=web"
      - "traefik.http.routers.dev-ninja-webserver-router.entrypoints=websecure"
      - "traefik.http.routers.dev-ninja-webserver-router.tls.certresolver=letsencrypt"
      - "traefik.http.services.dev-ninja-webserver.loadbalancer.server.port=80"
    depends_on:
      - app
    networks:
      - traefik_dev

networks:
  traefik_dev:
    external: true

I have tried partisan optimize, storage:link etc. I have done all the tricks from this, this and this post.

What else can I check? Any tips or tricks? Any help is much appreciated.

Thanks a lot!
Gijs

Hi,

@david do you have any thoughts?

in the env file can you add

TRUSTED_PROXIES=*

and then restart the container please.

Hi @david

that was already in there. See env file above.

Thanks,
Gijs

@ecomsilio

Can you try reuploading your company logo, my feeling is the path to the company logo is http, not https

Unfortunately that didn’t help. I created a completely new company and even there the same error occurs. When I customize the invoice and activate “HTML mode”, it shows the logo embedded as https.

I have enabled LOG_PDF_HTML in the env file. Where and when does it log the html? I will give that a try to see, if it is embedded http or https.

It works fine on my regular installation but I wanted to try docker and this is my first approach. So far all is good except from the logo not showing up.

Thanks a lot!
Gijs

The html should log in either storage/logs/laravel.log or storage/logs/invoiceninja.log

I don’t think you will find much joy there as we convert the logo into base64.

I note your configuration has Traefik, we’ve seen people report issues about traefiK on the invoiceninja/dockerfiles repo, i myself don’t have much experience but i’ll try and find some time to play around with it to see if i can recreate the issue.

Thanks David.

I just found it in the laravel log. The logo is embedded with an https link.

The logo is shown in the client portal. But the logo is still not shown in the invoice previews or in the pdf file.

Could this be a permission issue?

Do you know, which other logs I can check?

Thanks,
Gijs

Hi,

maybe the current compose files will help

traefik docker-compose.yml
version: "3"

services:
  traefik:
    # The official v2 Traefik docker image
    image: traefik:v2.7
    container_name: traefik
    restart: always
    # env_file: env
    command:
      - --global.sendAnonymousUsage=false
      # Enable Dashboard
      - --api.insecure=false
      - --api.dashboard=true
      - --api.debug=true
      # We are using Docker
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      # Listen on port 8080 (traefik Dashboard)
      - --entrypoints.traefik_https.address=:8080
      # Listen on port 80 (http)
      - --entrypoints.web.address=:80
      # Listen on port 443 (https)
      - --entrypoints.websecure.address=:443
      # Automaticly redirect from http to https
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      - --entrypoints.web.http.redirections.entryPoint.scheme=https
      # Enable LetsEncrypt
      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true
      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
      - --certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      # Enable Access Log
      - --accesslog.filepath=/var/log/www/access.log
    ports:
      # The HTTP port
      - "80:80"
      # The HTTPS port
      - "443:443"
      # The Web UI (enabled by --api.insecure=false)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # LetsEncrypt Configuration Storage
      - ./letsencrypt:/letsencrypt
      # Enable Access Log
      - ./logs/:/var/log/www/
    labels:
      - traefik.enable=true
      - traefik.http.routers.traefik_https.entrypoints=traefik_https
      - traefik.http.routers.traefik_https.rule=Host(`crm.ecomsilio.de`) && PathPrefix(`/api`) || PathPrefix(`/dashboard`)
      - traefik.http.routers.traefik_https.tls=true
      - traefik.http.routers.traefik_https.tls.certResolver=letsencrypt
      - traefik.http.routers.traefik_https.service=api@internal
      - traefik.http.routers.traefik_https.middlewares=traefik-auth
      # Username: username
      # Password: password
      - traefik.http.middlewares.traefik-auth.basicauth.users=username:password
    networks:
      - traefik
      - traefik_dev

networks:
  traefik:
    external: true
  traefik_dev:
    external: true

And additionaly the incoiceninja docker-compose.yml, so you do not need to scroll between the posts :wink:

invoiceninja docker-compose.yml
services:
  db:
    image: mysql:5
    container_name: InvoiceNinja-Database
    env_file: env
    restart: always
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw,delegated
    networks:
      - traefik

  app:
    image: invoiceninja/invoiceninja:5.4.11
    container_name: InvoiceNinja-App
    env_file: env
    restart: always
    volumes:
      - ./config/hosts:/etc/hosts:ro
      - ./docker/app/public:/var/www/app/public:rw,delegated
      - ./docker/app/storage:/var/www/app/storage:rw,delegated
    depends_on:
      - db
    networks:
      - traefik

  server:
    image: nginx
    container_name: InvoiceNinja-Webserver
    env_file: env
    restart: always
    volumes:
      - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
      - ./docker/app/public:/var/www/app/public:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ninja-webserver-router.rule=Host(`crm.ecomsilio.de`)"
      - "traefik.http.routers.ninja-webserver-router.entrypoints=web"
      - "traefik.http.routers.ninja-webserver-router.entrypoints=websecure"
      - "traefik.http.routers.ninja-webserver-router.tls.certresolver=letsencrypt"
      - "traefik.http.services.ninja-webserver.loadbalancer.server.port=80"
    depends_on:
      - app
    networks:
      - traefik

networks:
  traefik:
    external: true

Kind regards
AccessInTech

1 Like

Thanks @Access-InTech ! @ecomsilio can you advise if this corrects the issue you are seeing :slight_smile:

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