Install Invoice Ninja v5 on Ubuntu 20.04

I’ve tested these instructions in a VM running Ubuntu 20.04 LTS so it should work for the most part, just the same in Ubuntu 20.04 server as well, I have used Ubuntu server in the past and I can’t imagine why it would be any different unless there are some repository issues.

OK.

First steps: Install dependencies

$ sudo apt update
$ sudo apt dist-upgrade -y

$ sudo apt install gcc g++ make php php-{fpm,bcmath,ctype,fileinfo,json,mbstring,pdo,tokenizer,xml,curl,zip,gmp,gd,mysqli} mariadb-server curl git nginx vim composer -y

$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb
$ mysql_secure_installation

$ mysql -u root -p

$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
$ sudo apt install nodejs

$ node -v
v14.9.0
$ npm -v
v6.14.8

Done installing things. Let’s configure them.

Next we configure Mariadb

$ mysql -u root -p
Enter Password:  ******
MariaDB .. > create database ninjadb;
MariaDB .. > create user 'ninja'@'localhost' identified by 'ninjapass';
MariaDB .. > grant all privileges on ninjadb.* to 'ninja'@'localhost';
MariaDB .. > flush privileges;
MariaDB .. > exit

Now we generate OpenSSL certification - unless you already have letsencrypt or other cert, if so, skip this step, and configure SSL cert path manually later when we configure NGINX .conf file for invoiceninja.

$ sudo mkdir -p /etc/nginx/cert
$ sudo openssl req -new -x509 -days 365 -nodes -out /etc/nginx/cert/ninja.crt -keyout /etc/nginx/cert/ninja.key

Optional, depends on config: the default NGINX install on Ubuntu has a pesky default website located at /etc/nginx/sites-enabled/default - and for our cases, we do not want this default website hosted by nginx. This is for a VM configured just for invoiceninja webhosting, and the “default_server” value will make it the first thing we see at 127.0.0.1 or other direct IP. Unless it is overridden by this pesky file :wink: let’s delete it instead.

$ sudo rm /etc/nginx/sites-enabled/default

There. Now we can configure invoiceninja and test it properly without ‘default’ getting in our way.

$ sudo vim /etc/nginx/conf.d/invoiceninja.conf

press ‘i’ to enter insert mode, and paste this server configuration. Review it line by line, and edit the server name, root path, ssl path, php-fpm socket path, etc, as necessary.

  server {
   listen       443 ssl http2 default_server;
   listen       [::]:443 ssl http2 default_server;
   server_name  invoices.example.ca;
   # Here, enter the path to your invoiceninja directory, in the public dir.
   root         /usr/share/nginx/invoiceninja/public;
   client_max_body_size 20M;

   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;

   index index.php index.html index.htm;

   # Enter the path to your existing ssl certificate file, and certificate private key file
   # If you don’t have one yet, you can configure one with openssl in the next step.
   ssl_certificate "/etc/nginx/cert/ninja.crt";
   ssl_certificate_key "/etc/nginx/cert/ninja.key";
   ssl_session_cache shared:SSL:1m;
   ssl_session_timeout  10m;
   ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
   ssl_prefer_server_ciphers on;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

   charset utf-8;

   # Load configuration files for the default server block.
   include /etc/nginx/default.d/*.conf;

   location / {
       try_files $uri $uri/ /index.php?$query_string;
   }

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

   location ~ \.php$ {
           fastcgi_split_path_info ^(.+\.php)(/.+)$;
           # Here we pass to php-fpm listen socket.  For configuration see /etc/php-fpm.d/*.conf.
           fastcgi_pass unix:/run/php/php-fpm.sock;
           fastcgi_index index.php;
           include fastcgi_params;
           fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
           fastcgi_intercept_errors off;
           fastcgi_buffer_size 16k;
           fastcgi_buffers 4 16k;
   }

   location ~ /\.ht {
       deny all;
   }

   location = /favicon.ico { access_log off; log_not_found off; }
   location = /robots.txt { access_log off; log_not_found off; }

   access_log /var/log/nginx/ininja.access.log;
   error_log /var/log/nginx/ininja.error.log;

   sendfile off;

  }

  server {
      listen      80;
      server_name invoices.example.ca;
      add_header Strict-Transport-Security max-age=2592000;
      rewrite ^ https://$server_name$request_uri? permanent;
  }

That’s great! Hope you remembered to check root, server_name, and SSL certificate paths. Next Steps.

For Ubuntu 20.04, I had to disable apache2 in order to enable nginx to run on ports 80 and 443 without conflict. You might prefer to use apache2, but I am only supporting one web server conf file, and am already using nginx.

  $ sudo systemctl stop apache2
  $ sudo systemctl disable apache2
  $ sudo systemctl start nginx
  $ sudo systemctl enable nginx

Installing Invoice Ninja - if using github clone method, don’t forget to use git checkout v2, to change branch, or you will fail to install dependencies with php composer later.

  $ cd /usr/share/nginx
  $ git clone https://github.com/invoiceninja/invoiceninja
  $ cd invoiceninja && git checkout v2

Only failsafe install from latest github release 5.0.13 - there are bugs with client PDF sending in 5.0.13, that get fixed in the days following its release on the main repository, using git clone to git it, ha. This 5.0.13 still exists as a “stable” for now until the next release is made.

  $ cd /usr/share/nginx
  $ sudo mkdir invoiceninja && cd invoiceninja
  $ sudo wget https://github.com/invoiceninja/invoiceninja/archive/v5.0.13-release.zip
  $ sudo unzip v5.0.13-release.zip
  $ sudo mv invoiceninja-5.0.13-release/* .
  $ sudo mv invoiceninja-5.0.13-release/.* .

Installing and configuring Invoice Ninja server software and dependencies

  $ sudo php `which composer` install

OR this command, just depends on the environment if you already ran install once in this path…

  $ sudo php `which composer` update

When running for the first time only - Follow the link provided to generate github token, then pass to the prompt on the terminal.
Wait while it runs.

npm update will pull software dependencies for Invoice Ninja - using the --unsafe-perm=true option is necessary in order to succesfully download and install the files for chromium headless, which is a PDF dependency. ‘npm audit fix’ should automagically fix all security issues among dependencies without any other extra steps.

  $ sudo npm update --unsafe-perm=true
  $ sudo npm audit fix

First we create fresh .env file to set the environment rules.

  $ sudo cp .env.example .env

Populate the file with encryption key automatically generated.

  $ sudo php artisan key:generate

Run auto configure process, something you must do again if you ever change the values of .env or other files within the invoiceninja directory.

  $ sudo php artisan optimize

Then run command to create a symlink to the storage directory in the public directory, to allow access to other invoices etc for customers you send them to, is used for share functions by email etc.

  $ sudo php artisan storage:link

Finally, set permissions for the directory.

  $ sudo chown -R www-data:www-data /usr/share/nginx/invoiceninja
  $ sudo chmod -R g+s /usr/share/nginx/invoiceninja
  $ sudo chmod -R 775 /usr/share/nginx/storage

Now, there is need to enable cron job that will run some sort of regular maintenance, or you get a nasty red exclamation mark error in InvoiceNinja after logging in. See here for more: https://invoiceninja.github.io/selfhost.html#installing-invoice-ninja

  $ sudo crontab -e

Then copy paste the following into the bottom of your cron file, which will be run for something to do with laravel which InvoiceNinja depends on.

  * * * * * php /usr/share/nginx/invoiceninja/artisan schedule:run >> /dev/null 2>&1

Some users may encounter issues generating PDF, some may not. I do not know why or so on, but you can try to fix the chromium headless dependencies by installing:

  sudo apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

For me this was not an issue in a KVM Ubuntu managed by Virt-manager, but for others with remote VM or container it was.

https://invoiceninja.github.io/selfhost.html

I strongly suggest if you are struggling, to review both this link to original Invoice Ninja install documentation, then there is a readme document included in invoiceninja data files that is also useful.

Done. Enjoy.

If you cannot get it to login or have other errors, fastest support will come from making a NEW thread, or joining InvoiceNinja on Slack, in order to communicate quickly with devs.

This guide is written in my free time, and I do not offer real support for it, but I will try to update it if there are errors in my post that misguide you.

Thanks.

3 Likes

Great Job, thanks. In my case, the only change I did was:
$ php `which composer` install
instead of
$ php `which composer` update

1 Like

Thanks for the positive feedback.

Thanks a lot, you have a small typo error “inatll” :wink:

1 Like

I followed the steps and when submitting the setup form I get a 500 response. Do you have any idea where I should look?

Please check the web server error logs and the app error logs in storage/logs/laravel-error.log for details about the error.