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

Please visit https://github.com/invoiceninja/invoiceninja/releases to get the latest github release of InvoiceNinja from the team. Look closely at what you are downloading, the list also includes recent updates to v4.

  $ cd /usr/share/nginx
  $ sudo mkdir invoiceninja && cd invoiceninja
  $ sudo wget https://github.com/invoiceninja/invoiceninja/releases/download/v5.0.21-release/invoiceninja.zip
  $ sudo unzip invoiceninja.zip

Installing and configuring Invoice Ninja server software and dependencies

  $ sudo php /usr/bin/composer install --no-dev

OR, if you get a memory error you can run:

  $ sudo php -d memory_limit=-1 `which composer` install --no-dev

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.

We use the --no-optional flag to prevent checking for packages we don’t need on our OS, and ignoring associated errors when they fail to install.

  $ sudo npm install --no-optional

You have an automatically generated .env file with preset encryption key and ready to initialize the setup page.

Optionally, populate the .env file with a new genuine encryption key.

  $ 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/invoiceninja/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.

Hello,
i’ve seen this howto. But i have a litte error in nginx. I gat a 403 Forbidden. The log says only
*2 directory index of "/var/www/invoiceninja/" is forbidden
Any hints for me?
Thanks
Carsten

@CKMartens does the webuser have read/write access to that directory?