Docker image - issues with file uploads - Failed to open stream: Operation timed out

I’m fighting the docker install of invoice ninja behind caddy.

The current main issue is files.
If I upload a company logo - it uploads. But pdf generation breaks (if I go to invoice preview in settings it doesn’t show anything)

I can’t upload any files/images with error 500.

So I was thinking to move everything to S3.

Could somebody provide an example env config for S3 in docker?

Currently, I can’t even make to knock on S3 door.

Documentation is lucking straightness.
Using - Free Source Available Invoicing, Expenses & Time-Tracking | Invoice Ninja
And - https://github.com/invoiceninja/invoiceninja/blob/v5-stable/config/filesystems.php
as sources

My logs when trying to upload

storage/logs/laravel.log
[2023-09-02 16:00:55] production.ERROR: file_get_contents(https://invoices."REDUCTED"/storage/jqVyLkEx3rmFjywCD4PZMBDhVzsYt6RX/documents/8VldP0AWUWTrHYxNiuiUQQB592fbg7DTIttbxfQd.png): Failed to open stream: Operation timed out {"userId":1,"exception":"[object] (ErrorException(code: 0): file_get_contents(https://invoices."REDUCTED"/storage/jqVyLkEx3rmFjywCD4PZMBDhVzsYt6RX/documents/8VldP0AWUWTrHYxNiuiUQQB592fbg7DTIttbxfQd.png): Failed to open stream: Operation timed out at /var/www/app/app/Http/Controllers/DocumentController.php:124)
[stacktrace]
#0 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(254): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
#2 /var/www/app/app/Http/Controllers/DocumentController.php(124): file_get_contents()
#3 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(145): App\\Http\\Controllers\\DocumentController->App\\Http\\Controllers\\{closure}()
#4 /var/www/app/vendor/symfony/http-foundation/StreamedResponse.php(102): Illuminate\\Routing\\ResponseFactory->Illuminate\\Routing\\{closure}()
#5 /var/www/app/vendor/symfony/http-foundation/Response.php(423): Symfony\\Component\\HttpFoundation\\StreamedResponse->sendContent()
#6 /var/www/app/public/index.php(61): Symfony\\Component\\HttpFoundation\\Response->send()
#7 {main}
"}

Config

.env
IS_DOCKER=true

APP_NAME="REDUCTED"
APP_ENV=production

APP_URL="REDUCTED"
APP_KEY="REDUCTED"

APP_DEBUG=true
EXPANDED_LOGGING=true
UPDATE_SECRET="REDUCTED"
TRUSTED_PROXIES=*

APP_CIPHER=AES-256-CBC
APP_LOCALE=en

REQUIRE_HTTPS=true
IN_USER_EMAIL="REDUCTED"
IN_PASSWORD="REDUCTED"

QUEUE_CONNECTION=database

DB_TYPE=mysql
DB_STRICT=false
DB_HOST="REDUCTED"
DB_DATABASE="REDUCTED"
DB_USERNAME="REDUCTED"
DB_PASSWORD="REDUCTED"
caddyfile
################################################################################
# invoices
################################################################################
REDUCTED {
    import header_noindex
    import tls_standard_email
  import logerror

    root * /var/www/app/public
    php_fastcgi Invoice_Ninja:9000
    encode zstd gzip
    file_server browse
}

After changing .env i’m doing docker-compose up -d to recreate container and

php artisan optimize

in container shell after.

The worst part is - it doesn’t tell you that the upload was unsuccessful. Quite opposite - the upload is successful according to UI messages (web or android app) but downloading the uploaded file - it’s damaged.

Hi,

Setting local_download=true in the .env properties may help with the logo on the PDF.

Also, I suggest trying the React app to see if it makes a difference. There is a fix pending in the Flutter app related to documents.

1 Like

The actual logo does upload. And Invoices (i guess other documents too) are displayed in preview.

For example

It seems like in React app there is no way to add a file to a task. Or I can’t find it

With logo uploaded, in REACT app - invoice preview breaks without output.

With logo uploaded in Flutter app - invoice preview breaks with following output.

Including

local_download=true

Doesn’t change anything.

And this is what I get when trying to upload a file to a task.
image

Along with

local_download=true

I’ve also tried different combinations of

TRUSTED_PROXIES='*'
FILESYSTEM_DRIVER=public

with no success.

Sorry, I’m not sure. This isn’t a standard app configuration.

@david may have some suggestions.

By not standard you mean docker? I didn’t add or change anything extra to the docker image.
I don’t actually have S3 configured either, it doesn’t accept any configs related to it as far as my attempts went.

So I’m basically fighting a fresh stock docker install.

Docs followed to install - Free Source Available Invoicing, Expenses & Time-Tracking | Invoice Ninja but using the Docker as image source.

Going to start from scratch, will try the hub image vs git clone way and see if any improvement.

So fresh install from hub.docker with env file from github… Like described in Docker with QUEUE_CONNECTION=database - How? - #14 by sdggq
no alterations besides what necessary to env file.

Same issues when trying to upload an image to a task in Flutter app.
image

invoice ninja test

I’ve recorded the screen, maybe it gives a clue.
I did purchase the upgrade license, but didn’t activate it on this particular fresh install. Not sure if it is important for config or not.

When you are creating your Invoice Ninja instance, are you following this guide exactly?

It sounds like you are downloading the image and then manually linking everything up. Using docker-compose avoids all of this.

I’m not linking anything up manually… And not following the guide exactly, since I have all my containers config in yml file. I get the env file from GitHub - invoiceninja/dockerfiles: Docker files for Invoice Ninja and I get the other things like applying chown and chmod.

Using standard approach with pre existing docker-compose.yml, pre-existing env file.
Then following with docker-compose up -d

My files are

dcoker compose
  Invoice_Ninja:
    image: invoiceninja/invoiceninja:5
    container_name: "REDUCTED" 
    env_file: .env_InvNNJ
    networks:
      - "REDUCTED" 
    restart: always
    volumes:
      - ${DOCKER_APPDATA_PATH}/ilr_inv_nnj/public:/var/www/app/public:rw,delegated
      - ${DOCKER_APPDATA_PATH}/ilr_inv_nnj/storage:/var/www/app/storage:rw,delegated
    depends_on:
      - mysql_db
env filel
# IN application vars
APP_URL="REDUCTED - public url" 
APP_KEY="REDUCTED" 

APP_DEBUG=true
EXPANDED_LOGGING=true

REQUIRE_HTTPS=false
PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*'

QUEUE_CONNECTION=database

# DB connection
DB_TYPE=mysql
DB_STRICT=false
DB_HOST=MySQL_DB
DB_DATABASE="REDUCTED" 
DB_USERNAME="REDUCTED" 
DB_PASSWORD="REDUCTED" 

# Create initial user
# Default to these values if empty
# IN_USER_EMAIL=admin@example.com
# IN_PASSWORD=changeme!
IN_USER_EMAIL="REDUCTED" 
IN_PASSWORD="REDUCTED" 

# Mail options
MAIL_MAILER=smtp
MAIL_HOST=smtp-relay.gmail.com
MAIL_PORT=587
MAIL_USERNAME="REDUCTED" 
MAIL_PASSWORD="REDUCTED" 
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="REDUCTED" 
MAIL_FROM_NAME="REDUCTED" 

# MySQL - ommiting, DB already configured above. No mention of these variables in https://invoiceninja.github.io/en/env-variables/
#MYSQL_ROOT_PASSWORD=ninjaAdm1nPassword
#MYSQL_USER=ninja
#MYSQL_PASSWORD=ninja
#MYSQL_DATABASE=ninja
Caddyfile
################################################################################
# REDUCTED
################################################################################
REDUCTED public url{
    import header_noindex
    import tls_standard_email
  import logerror
# import loginfo

    root * /var/www/app/public
    php_fastcgi Invoice_Ninja:9000
    encode zstd gzip
    file_server browse
}

The difference in the configs is that I don’t use nginx as proxy, I use caddy (with many other containers behind it, including two public Wordpress instances). And I already have instance of MySQL for DB.
The caddy config is from https://github.com/invoiceninja/dockerfiles/blob/master/config/caddy/Caddyfile

Can you confirm that image published at Docker is not official? Then I get that there might be a problem in the image.

Unless you are running the exact docker-compose file, it is very difficult to debug what is going on.

The Docker images are built from invoiceninja/dockerfiles so they are certainly “official” in that sense.

So, I should dedicate a standalone VPS be able to run an exact, clean install with docker compose file?
I’m sorry, it doesn’t make sense. I get that it’s opensource, and you are on your own 99% of the time. And I appreciate any kind of help I can get.

But I have a feeling there is not much understanding of what docker configs are… Maybe on both sides.

Even the fact that config is different between docker hub and github… If it is really hard to debug what’s going on - why have debug mod, config examples posted, extra debug variables?

What my configs are lucking so significantly that makes it so difficult to debug this?

You can run multiple docker containers on a single instance, you may need to juggle ports, but it is certainly possible.

We are not experts in Docker at all that is why we can only focus support on the official repo as there are just too many permutations to handle when things deviate from the standard file.

I didn’t say that I can’t run multiple docker containers. Quite opposite. I said that all my docker containers are configured in a single docker-compose.yml. Just like your config on github has it.

I understand that there is an issue with knowledge resources in docker field. It’s ok. But it is not a reason to simply dismiss something because “it doesn’t look like what I see in this other book”.

For example the logo issue - for a file to be uploaded as logo, it has to pass through web server (ngnix in “standard config”, caddy in my case), be accepted and configured by the backend. Clearly this chain is happening and logo is accepted by backend. But then something breaks in the app and it can’t generate the pdf preview anymore.

This fact is dismissed, because - oh, your config is so different it almost like chinese for us? I’m sorry if I come across as an ignorant humang being. But it’s kinda hard to find logic in this.
Doesn’t the error displayed in place of pdf preview hint on something? It doesn’t to me - there is no reasonble and informative log output that I can act upon.

@sdggq

I’m not being dismissive, I’ve laid it out pretty clearly.

We are not docker experts. We provide a standard file which works I’m sorry your customized version does not. But if the application was broken, it would be broken for everybody, in this case, something is happening with your specific configuration.

So… no idea then. Got it :slight_smile:

anybody knows where
uri:/api/v1/documents/
located in filesystem?

Found it with

cd "INV NINJA VOLUME"
find ./ -type d -name "documents"

Further investigation showed that inside the docker container php.ini doesn’t match the github version posted here - https://github.com/invoiceninja/dockerfiles/tree/master/config/php
in many ways.

What should be used?

Conflicting information provided between Docker - where php.ini and php-cli.ini are not getting passed through to the docker.
and https://github.com/invoiceninja/dockerfiles/blob/master/docker-compose.yml where php.ini and php-cli.ini are passed through to docker container.

Confirmed that uploaded to tasks - files are being created in filesystem and I can open them directly without auth by following

https://"domain name"/storage/3nRvxjdaX06fqFrHkPggMHo7cRViWHss/documents/UjZZqILu2aUglDmvetJWlkWRruqux4PwFNjxOHPB.png

However when trying to open same file from Flutter UI (still no clue on how to do that in REACT) I’m getting

in laravellog
[2023-09-04 13:15:15] production.ERROR: file_get_contents(https://invoices."REDUCTED"/storage/3nRvxjdaX06fqFrHkPggMHo7cRViWHss/documents/UjZZqILu2aUglDmvetJWlkWRruqux4PwFNjxOHPB.png): Failed to open stream: Operation timed out {"userId":1,"exception":"[object] (ErrorException(code: 0): file_get_contents(https://invoices."REDUCTED"/storage/3nRvxjdaX06fqFrHkPggMHo7cRViWHss/documents/UjZZqILu2aUglDmvetJWlkWRruqux4PwFNjxOHPB.png): Failed to open stream: Operation timed out at /var/www/app/app/Http/Controllers/DocumentController.php:124)
[stacktrace]
#0 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(254): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
#2 /var/www/app/app/Http/Controllers/DocumentController.php(124): file_get_contents()
#3 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(145): App\\Http\\Controllers\\DocumentController->App\\Http\\Controllers\\{closure}()
#4 /var/www/app/vendor/symfony/http-foundation/StreamedResponse.php(102): Illuminate\\Routing\\ResponseFactory->Illuminate\\Routing\\{closure}()
#5 /var/www/app/vendor/symfony/http-foundation/Response.php(423): Symfony\\Component\\HttpFoundation\\StreamedResponse->sendContent()
#6 /var/www/app/public/index.php(61): Symfony\\Component\\HttpFoundation\\Response->send()
#7 {main}
"}

and

in ui instead of thumbnail
HTTPException: Invalid statusCode: 500, uri = https://invoice."REDUCTED"/api/v1/documents/wMvbmOeYAI/download: https://invoices."REDUCTED"/api/v1/documents/wMvbmOeYAI/download

The logo is being uploaded correctly - that out of the questions, since it’s appearing in invoices and by the company name left top corner. Why previews break in the invoice design settings - still a mistery.

Also, not sure if anybody will pay attention but
image

this is potentially destructive to user data on persistent storage.

Are there API calls that should be routed in a specific way from flutter to backend?