Update 5.5.22 -> 5.5.40 failed

Hello
I updated from Version 5.5.22 to 5.5.40 with the provided updateskript from
https://invoice-ninja.readthedocs.io/en/latest/update.html#version-5-4-33

We recommend using this shell script to automate the update process, run it as a daily cron to automatically keep your app up to date.

Base System Data: Debian 10.5, PHP 8.1, Apache/2.4.54 (Debian)

After Upgrade i got the following Error in laravel.log:

[2022-11-17 21:21:55] laravel.ERROR: During inheritance of ArrayAccess: Uncaught ErrorException: Return type of Illuminate\Support\Collection::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1277
Stack trace:
#0 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/Collection.php(11): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError()
#1 /var/www/invoiceninja/vendor/composer/ClassLoader.php(444): include('...')
#2 /var/www/invoiceninja/vendor/composer/ClassLoader.php(322): Composer\Autoload\includeFile()
#3 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/helpers.php(109): Composer\Autoload\ClassLoader->loadClass()
#4 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php(89): collect()
#5 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php(78): Illuminate\Foundation\PackageManifest->config()
#6 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php(26): Illuminate\Foundation\PackageManifest->aliases()
#7 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(219): Illuminate\Foundation\Bootstrap\RegisterFacades->bootstrap()
#8 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(156): Illuminate\Foundation\Application->bootstrapWith()
#9 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(140): Illuminate\Foundation\Http\Kernel->bootstrap()
#10 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#11 /var/www/invoiceninja/public/index.php(53): Illuminate\Foundation\Http\Kernel->handle()
#12 {main} {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 1): During inheritance of ArrayAccess: Uncaught ErrorException: Return type of Illuminate\\Support\\Collection::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1277
Stack trace:
#0 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/Collection.php(11): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 /var/www/invoiceninja/vendor/composer/ClassLoader.php(444): include('...')
#2 /var/www/invoiceninja/vendor/composer/ClassLoader.php(322): Composer\\Autoload\\includeFile()
#3 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/helpers.php(109): Composer\\Autoload\\ClassLoader->loadClass()
#4 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php(89): collect()
#5 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php(78): Illuminate\\Foundation\\PackageManifest->config()
#6 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php(26): Illuminate\\Foundation\\PackageManifest->aliases()
#7 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(219): Illuminate\\Foundation\\Bootstrap\\RegisterFacades->bootstrap()
#8 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(156): Illuminate\\Foundation\\Application->bootstrapWith()
#9 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(140): Illuminate\\Foundation\\Http\\Kernel->bootstrap()
#10 /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#11 /var/www/invoiceninja/public/index.php(53): Illuminate\\Foundation\\Http\\Kernel->handle()
#12 {main} at /var/www/invoiceninja/vendor/laravel/framework/src/Illuminate/Support/Collection.php:11)
[stacktrace]

Have anyone some suggestion how to complete migration?

Hi,

Those are the v4 docs, here are the v5 docs:

Thanks for your reply.

I downloaded the actual Version from Github, extract the Package, Sync the Folders, Reset Permissions and File Owner.

Have you some suggetion for running the Update Command from shell?

Hi @Torsten

This is my update workflow:

  1. Go back to the last working version (without this I could not get a failed update to work afterwards)
  • Delete the invoiceninja folder completely.
  • restore from backup
    rsync --verbose --recursive --links --perms --times --hard-links --acls --xattrs /path/to/backup/invoiceninja/ /var/www/path/to/invoiceninja/
  • restore folder permissions
    restorecon -R /var/www/path/to/invoiceninja/
  • start invoiceninja queue (if available)
  • fix .htaccess (complete files below) if you are on a subdomain
    → /var/www/path/to/invoiceninja/.htaccess
    → /var/www/path/to/invoiceninja/public/.htaccess
  • Ensure that Invoiceninja is working fine

Now the Update…

  1. create a backup of the database
    mysql db_invoiceninja < /var/www/path/to/db_invoiceninja.sql
  2. update to latest version
    → cd /var/www/path/to/invoiceninja
    → git pull
    → git checkout v5-stable
    → composer install
    → php artisan ninja:post-update
  3. correct files (only if you are on a subdomain like business.example.com)
    → /var/www/path/to/invoiceninja/.htaccess
    → /var/www/path/to/invoiceninja/public/.htaccess
  4. Invoiceninja migrations (if neccessary)
    → php artisan migrate --force
  5. call Invoiceninja
    → clear browser cache
    https://business.example.com/update?secret=secret

/var/www/path/to/invoiceninja/.htaccess

<IfModule mod_rewrite.c>
  # Redirect HTTP to HTTPS:
  RewriteCond %{ENV:HTTPS} !=on
  RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  
  # Make InvoiceNinja work in subdomains:
  RewriteBase /
  RewriteRule ^(.*)$ public/$1 [L]
  
  RewriteRule "^.env" - [F,L]
#  RewriteRule "^storage" - [F,L]
  RewriteRule ^(.well-known)($|/) - [L]
  
  RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

# https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess


# ######################################################################
# # INTERNET EXPLORER                                                  #
# ######################################################################

# ----------------------------------------------------------------------
# | Iframes cookies                                                    |
# ----------------------------------------------------------------------

# Allow cookies to be set from iframes in Internet Explorer.
#
# https://msdn.microsoft.com/en-us/library/ms537343.aspx
# http://www.w3.org/TR/2000/CR-P3P-20001215/

<IfModule mod_headers.c>
    Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
</IfModule>


# ######################################################################
# # MEDIA TYPES AND CHARACTER ENCODINGS                                #
# ######################################################################

# ----------------------------------------------------------------------
# | Character encodings                                                |
# ----------------------------------------------------------------------

# Serve all resources labeled as `text/html` or `text/plain`
# with the media type `charset` parameter set to `UTF-8`.
#
# https://httpd.apache.org/docs/current/mod/core.html#adddefaultcharset

AddDefaultCharset utf-8

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Serve the following file types with the media type `charset`
# parameter set to `UTF-8`.
#
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset

<IfModule mod_mime.c>
    AddCharset utf-8 .atom \
                     .bbaw \
                     .css \
                     .geojson \
                     .js \
                     .json \
                     .jsonld \
                     .manifest \
                     .rdf \
                     .rss \
                     .topojson \
                     .vtt \
                     .webapp \
                     .webmanifest \
                     .xloc \
                     .xml
</IfModule>


# ######################################################################
# # WEB PERFORMANCE                                                    #
# ######################################################################

# ----------------------------------------------------------------------
# | Compression                                                        |
# ----------------------------------------------------------------------

<IfModule mod_deflate.c>

    # Force compression for mangled headers.
    # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html

    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Map certain file types to the specified encoding type in order to
    # make Apache serve them with the appropriate `Content-Encoding` HTTP
    # response header (this will NOT make Apache compress them!).

    # If the following file types wouldn't be served without the appropriate
    # `Content-Enable` HTTP response header, client applications (e.g.:
    # browsers) wouldn't know that they first need to uncompress the response,
    # and thus, wouldn't be able to understand the content.

    # http://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Compress all output labeled with one of the following media types.

    # IMPORTANT: For Apache versions below 2.3.7 you don't need to enable
    # `mod_filter` and can remove the `<IfModule mod_filter.c>` & `</IfModule>`
    # lines as `AddOutputFilterByType` is still in the core directives.

    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/opentype" \
                                      "image/svg+xml" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/xml"
    </IfModule>

</IfModule>

/var/www/path/to/invoiceninja/public/.htaccess

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On
	
	# Make InvoiceNinja work with subdomains:
	# If you want to access InvoiceNinja via a subdomain and
	# this rule is missing the browser will see a `500 internal server error`.
	RewriteBase /

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

<IfModule mod_headers.c>
    # Blocks Search Engine Indexing
    Header set X-Robots-Tag "noindex, nofollow"

    # Prevents PDF File Caching
    <FilesMatch ".pdf$">
        Header set Cache-Control no-store
    </FilesMatch>
</IfModule>

/var/www/path/to/invoiceninja/.env (excerpt)

APP_URL="https://business.example.com" //important: no slash at the end

BROADCAST_DRIVER=log
LOG_CHANNEL=stack
CACHE_DRIVER=file
QUEUE_CONNECTION=database
INTERNAL_QUEUE_ENABLED=false
SESSION_DRIVER=file
SESSION_LIFETIME=120

REQUIRE_HTTPS="true"

NINJA_ENVIRONMENT="selfhost"

#options - snappdf / phantom / hosted_ninja
PDF_GENERATOR=snappdf

UPDATE_SECRET=yoursecret

DELETE_PDF_DAYS=60
DELETE_BACKUP_DAYS=60

COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}'

If this doesn’t work, I don’t know what else you could try. Maybe some others can help…

1 Like

I found this match on the forum for the error you’re seeing, in their case it was caused by downloading the v4 release.

It looks like the shell script in the OP is also accessing the old download URL like I was. As mentioned the fact it silently redirects from a v5 version number to a v4 one is unintuitive, an error would be less confusing.

1 Like

thats a nice workflow for update, your source is different from mine, cause my installation is based on the precompiled binary zip file, it looks like you sync your local branch und compile them.

The documention seems a little bit outdated.

I‘be got the system up and running, After zum troubleshooting.

Just do the post-Upgrade an everything seems fine.

1 Like

This do the Trick finaly.

1 Like

@Torsten Thx for the feedback…

Yes, I don’t download the zip… For me, the advantage is that I don’t have to worry about folder permissions, unzip zips and don’t have to copy files. However, I have already done the basic installation with Composer.

There would be another variant for you:
Run the update directly in the GUI and then do

php artisan ninja:post-update

Depending on this, the call via https://business.example.com/update?secret=secret still has to be made on the web.

This should also make an update possible without any problems.