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.


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
$ npm -v

Done installing things. Let's configure them.

Debian Users

You have different paths for php-fpm's unix socket than Ubuntu users. This guide assumes you spawn /run/php/php-fpm.sock for a socket, but you do not. Other distros based on Debian or Ubuntu should pay attention to php-fpm.sock mentions in the nginx config example below, and change them to match the php-fpm path on your distro.

Check where php-fpm runs its socket with:

 systemctl status php-fpm

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 or other direct IP. Unless it is overridden by this pesky file ;) 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.


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.


To credit the developers of Invoice Ninja, and to reference the original content to refer to for additional troubleshooting, or etc: https://invoiceninja.github.io/selfhost.html

Invoice Ninja Forums: https://forum.invoiceninja.com/

Invoice Ninja Github: https://github.com/invoiceninja/invoiceninja