Install Invoice Ninja v5 on Ubuntu 20.04

I ran into an issue with this command using the composer.json file included in the 5.1.24 download. It appears that the dacastro4/laravel-gmail dependency now requires PHP 8.0 but the Invoice Ninja composer.json file requires 7.3 or 7.4.

Checking the releases on GitHub it looks like this changed recently.

I was able to get composer to successfully run by changing the following line

“dacastro4/laravel-gmail”: “dev-master”,


“dacastro4/laravel-gmail”: “^5.1”,


thanks for the catch, i’ll push a new release shortly.

1 Like

Hey everyone

I just finished an installation with a little bit simpler configuration. I have not tested it beyond the setup and the status page yet, so don’t hate me if it does not work :slight_smile:
PhantomJS for PDFs is missing in my installation. I am unsure if I need it and PhantomJS is a project no longer supported. I am sure the current state is great, it is just that I personally don’t like to install abandoned software.

Install what we need:
sudo apt install php-{fpm,bcmath,ctype,fileinfo,json,mbstring,pdo,tokenizer,xml,curl,zip,gmp,gd,mysqli}
apt install php mariadb-server nginx

Remove default NGINX sites:
sudo rm /var/www/html/index.nginx-debian.html
sudo rm /etc/nginx/sites-enabled/default

Configure your site here:
sudo nano /etc/nginx/sites-available/invoiceninja.conf
ls /etc/nginx/sites-available/invoiceninja.conf /etc/nginx/sites-enabled/
I am planning on putting it behind a NGINX Proxy so I have a pretty simple configuration:

# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# link not allowed
#  link not allowed
#  link not allowed
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.

# Default server configuration
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        # Note: You should disable gzip for SSL traffic.
        # See: link not allowed
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: link not allowed
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        # include snippets/snakeoil.conf;

        root /var/www/invoiceninja/public;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm;
        client_max_body_size 50M;
        gzip on;
        gzip_types      application/javascript application/x-javascript text/javascript text/plain application/xml application/json;
        gzip_proxied    no-cache no-store private expired auth;
        gzip_min_length 1000;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;

        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?q= last;

        # pass PHP scripts to FastCGI server
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #       # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        location ~ /\.ht {
                deny all;

# Virtual Host configuration for
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#server {
#       listen 80;
#       listen [::]:80;
#       server_name;
#       root /var/www/;
#       index index.html;
#       location / {
#               try_files $uri $uri/ =404;
#       }

Configure Mysql:
sudo mysql_secure_installation
sudo mysql -p

You should be logged in and can create the db and the user:
create database ninjadb;
create user ‘ninja’@‘localhost’ identified by ‘HERE IS YOUR PASSWORD’;
grant all privileges on ninjadb.* to ‘ninja’@‘localhost’;
flush privileges;
Next time I would use the default db and user name that the setup recommends. Unfortunately I did not write that down. Maybe someone else can help here?

Create the folders and download the files:
sudo mkdir /var/www/invoiceninja
cd /var/www/invoiceninja
Here you should get the latest zipfile from Just right click on it and copy the download path.

Unpack and delete
sudo apt install unzip
sudo unzip
sudo rm
sudo chown -R www-data:www-data /var/www
sudo -u www-data crontab -e
* * * * * cd /var/www/invoiceninja/ && php artisan schedule:run >> /dev/null 2>&1
sudo rm -r /var/www//html/

reboot the machine. Visit http://ip/setup

1 Like

SQLSTATE[HY000] [1045] Access denied for user ‘ninja’@‘localhost’ (using password: YES) (SQL: insert into jobs (queue, attempts, reserved_at, available_at, created_at, payload) values (default, 0, ?, 1615986392, 1615986392, {“uuid”:“4fe1fe7e-32f7-42ee-8718-723dd97533d3”,“displayName”:“App\Listeners\Mail\MailSentListener”,“job”:“Illuminate\Queue\CallQueuedHandler@call”,“maxTries”:null,“maxExceptions”:null,“backoff”:null,“timeout”:null,“retryUntil”:null,“data”:{“commandName”:“Illuminate\Events\CallQueuedListener”,“command”:“O:36:“Illuminate\Events\CallQueuedListener”:18:{s:5:“class”;s:35:“App\Listeners\Mail\MailSentListener”;s:6:“method”;s:6:“handle”;s:4:“data”;a:1:{i:0;O:34:“Illuminate\Mail\Events\MessageSent”:2:{s:7:“message”;O:13:“Swift_Message”:23:{s:28:”\u0000Swift_Message\u0000headerSigners";a:0:{}s:26:"\u0000Swift_Message\u0000bodySigners";a:0:{}s:27:"\u0000Swift_Message\u0000savedMessage";a:0:{}s:13:"\u0000*\u0000userFormat";N;s:14:"\u0000*\u0000userCharset";s:5:“utf-8”;s:12:"\u0000*\u0000userDelSp";N;s:33:"\u0000Swift_Mime_MimePart\u0000nestingLevel…

this is the error i get since v5 stable version was released…the beta version worked fine

i just installed v4.5 using the same nginx vhost i used for copied from this tutorial for the v5 and it works. is there a bug in the v5 that triggers the error i have posted above …the error i posted above happens when i input my smtp credentials for gmail.

Try to set mail config to Log only and edit .env file directly with email config after.

I don’t recommend using any kind of default credentials for your database for security

This I suspect is a bug I have seen where the application attempts to run setup with some default credentials, ignoring your manually configured SQL credentials. I don’t recommend trying to configure your server to accommodate this, it is less secure.

Start over or use php artisan optimize, to start setup again, and skip SMTP mail config with the LOG option. You can always change SMTP later in the .env file manually and easily.

My English is not that great, maybe there is a language barrier.

MySQL works, it is just that because you and I did not use the default db name and the default username that the setup suggested, we had to change this during the setup. I think it is a little less work, if I would have used the default. In that case I would only needed to insert the password.

The second part is not directed at my I guess :slight_smile:

I don’t know what causes the bug, only that I can retry and it will work with custom DB credentials.

I always skip setup SMTP and choose log, so I suggest it only to be consistent with my successes.

the issue i faced was regarding v5.1.14. i now went to the list of versions to use v5.1.26 and i got it to work. the android app too, you need to install the one for ninja v5, the older version of the cannot connect to v5.1.26

1 Like

FWIW… I had issue after issue. I tried multiple different install instructions for Ubuntu 20.04. Here is what got mine up and running. (Patched together using others instructions and a few of mine)

sudo curl -sL | sudo -E bash -
sudo add-apt-repository ppa:ondrej/php
add-apt-repository ppa:ondrej/apache2
sudo apt update
sudo apt upgrade -y
sudo apt install gcc g++ make php7.4 php7.4-{fpm,cli,common,bcmath,ctype,fileinfo,json,mbstring,pdo,tokenizer,xml,curl,zip,gmp,gd,mysqli,mysql,intl,imagick,apcu,exif,imap,ldap,ftp,bz2} mariadb-server curl git composer unzip clamav clamav-daemon wget fail2ban nodejs python3-certbot-apache software-properties-common phantomjs -y

sudo systemctl enable php7.4-fpm
sudo a2enmod proxy_fcgi setenvif
sudo systemctl restart apache2
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation
sudo mysql -u root -p
create database ninjadb;
create user ‘ninja’@‘localhost’ identified by ‘supersecretpassword’;
grant all privileges on ninjadb.* to ‘ninja’@‘localhost’;
flush privileges;

sudo nano /etc/apache2/sites-available/webserver.conf

<VirtualHost *:80>
DocumentRoot /var/www/ninja/public
ServerName FQDN
ServerAdmin workingemail
<Directory /var/www/ninja/public/>
DirectoryIndex index.php
Options +FollowSymlinks
AllowOverride All
Require all granted

ErrorLog ${APACHE_LOG_DIR}/ninja-error.log
CustomLog ${APACHE_LOG_DIR}/ninja-access.log combined

sudo a2ensite webserver.conf
sudo a2dissite 000-default
sudo rm /etc/apache2/sites-available/000-default.conf
sudo systemctl reload apache2
sudo mkdir /var/www/ninja && cd /var/www/ninja
sudo wget
sudo unzip
sudo rm
sudo chown -R www-data:www-data /var/www/ninja
sudo chmod -R g+s /var/www/ninja
sudo php /usr/bin/composer install --no-dev
sudo php artisan key:generate
sudo php artisan optimize
sudo sudo -u www-data crontab -e

          • php /var/www/ninja/artisan schedule:run >> /dev/null 2>&1

sudo apt remove composer
cd ~
curl -sS http-s:// -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/bin --filename=composer
sudo a2enmod rewrite
sudo php artisan migrate:fresh --seed
sudo certbot

(Change http-s to https - it would only allow me TWO links per post)

1 Like

Following this guide i kinda complicated with all the patches, changes on replies, (suggesting changes) i been trying all different ones, so far i get to the error of composer update command, (Your requirements could not be resolved to an installable set of packages.) , it requires composer 2.0, the guide somehow install composer v1, the update command wont go through, it just get killed. trying with find the the right guide that works for me. anyways thanks for the guide.

1 Like

User this…

sudo apt remove composer
cd ~
curl -sS http-s:// -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/bin --filename=composer

sudo php artisan key:generate
Could not open input file: artisan

Yes this sounds right now. I also had that issue with older versions of the app.

If you cannot find the artisan file you are doing something wrong. It is a core component of the app and found in the root directory of the extracted files, regardless of what version you download. Ensure you have downloaded the latest version and are running in the right directory where files are located.

There shouldn’t be any reason to source composer from other locations, the version in the Ubuntu default repositories works fine. I have run the default version of composer on Ubuntu in VM, on bare metal, and I’ve installed with it multiple times.

Whatever gets you to the end though I suppose… you can get composer however you like.

It was v1.x in a default 20.04 install and wouldnt work. I would get the composer require 2.0 error

Perhaps the developers have changed a dependency. 1.1 is a long term release for composer, it is still very much current and supported as far as composer goes.

My RHEL guide calls for composer 2.0, so I might as well make them both consistent.

Thanks for bringing this up. I also removed the step for installing NPM / Node since it is no longer a dependency for installation (on Ubuntu)

All good. It only took me 7 wipe and reinstalls before I caught on to what was wrong. :smile:

1 Like