Install Invoice Ninja v5 on Enterprise Linux 8

Installing InvoiceNinja v5 Beta on Enterprise Linux 8 (RHEL, AlmaLinux, Rocky Linux)

I do not reccomend installing on this distro family.

I will start by saying I reccomend installing on Ubuntu. On rpm-based distros you cannot automatically update the package, and must do it manually, increasing the risk of user error and data loss, and increasing demand on manual labour. You must backup your .env file, and the contents of the public/storage directory, to preserve your data before updating. Updating must be done manually by downloading the source code, and installing with composer and node, which are unnecessary for you on Ubuntu also. This guide will be preserved mostly for reference, educational purposes, freedom of choice, etc. I initially tried hosting on CentOS 8 before any other distro, which led me into all of this.

This guide is also going to be updated and supported more slowly now than the Ubuntu guide, so expect the Ubuntu guide to be more up to date, and effectively written.

Until support improves for the RHEL based distros, I would reccomend trying to run the application instead through a container with podman. There is an official Invoice NInja container available, with thorough documentation on Docker Hub here.

Install PHP7.4, and MariaDB server.

Update OS, and enable repo for latest version of PHP 7.4

$ sudo yum update
$ sudo yum install yum-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm
$ sudo yum module reset php
$ sudo yum module enable php:remi-7.4

Dependencies for invoiceninja, npm, etc.

$ sudo yum install gcc-c++ make php php-{fpm,bcmath,ctype,fileinfo,json,mbstring,pdo,tokenizer,xml,curl,zip,gmp,gd,mysqli} mariadb-server -y

Dependencies for chromium, which is used by npm/puppeteer for rendering PDF.

$ sudo yum install libXcomposite libXcursor libXdamage libXext libXi libXtst libmng libXScrnSaver libXrandr libXv alsa-lib cairo pango atk at-spi2-atk gtk3

Start, enable, and configure mariadb/mysql

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

Set the password for the root user of the SQL database. Make sure to keep record of this and do not lose it. You will need it in the next step, and for future maintenance of DB

Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Create and configure the SQL database we will be using later with InvoiceNinja.

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

Install nodejs/npm, to support Email, and PDF with puppeteer/chromium.

$ curl -sL https://rpm.nodesource.com/setup_14.x | sudo -E bash
$ sudo yum install nodejs -y

verify that npm and node are installed correctly.

$ node -v 
v14.7.0

$ npm -v 
6.14.7

Optionally configure SSL with OpenSSL, in lieu of an existing letsencrypt or other cert

I will not be giving instructions on other SSL certification methods. You can find and change the appopriate lines in the NGINX config step after this, if you plan to use another cert of your own.

Create a directory to store your ssl for nginx to access

$ sudo mkdir -p /etc/nginx/cert/

Generate SSL certificate, and follow the prompts to configure it appropriately.

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

Install and configure nginx

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

Settings for a TLS enabled server.

You may specify your own SSL certificate in this file if you are not using openssl above.
You will also specify your own domain name below, as per your DNS records or etc.

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:/var/run/php-fpm/www.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;
}

Create the invoiceninja directory we will be installing to later, and start and enable NGINX

$ sudo mkdir -p /usr/share/nginx/invoiceninja
$ sudo chown -R nginx:nginx /usr/share/nginx/invoiceninja
$ sudo systemctl start nginx
$ sudo systemctl enable nginx

Optionally, for testing or maintenance etc;

This is only for testing before deployment situations, or for setting up pointers to local instances of InvoiceNinjav4 that you want to migrate your data from (Both instances v4 and v5 must be running on separate environments with resolvable domain names to successfully migrate data from within the InvoiceNinja v4 web UI, on the latest patched versions of v4 only).

modify hosts file to point at server IP with given domain name in nginx, if you do not yet have DNS pointed at the server, or do not yet want to point your DNS at it.

$ sudo vi /etc/hosts

and simply add your domain to the end of this list for localhost, as seen here, or add the remote IP, followed by a space, and the domain name to point at it, all on a new line, like seen below again. NGINX should reroute any http request on the domain (not the direct IP or localhost) name to https.

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 invoices.example.ca
192.168.0.88  invoices2.example.ca

Configure firewalld

Below steps will open ports 80 and 443 to the public on firewalld permanently.

$ sudo firewall-cmd --zone=public --add-service=http --permanent
$ sudo firewall-cmd --zone=public --add-service=https --permanent
$ sudo firewall-cmd --reload

Now you need to properly configure php-fpm.

$ sudo vim /etc/php-fpm.d/www.conf

And change each of the following lines by either editing the values, or uncommenting the lines:

user = nginx
group = nginx
listen = /var/run/php/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Next we need to create a directory for the php session, and enable the php session to run at startup.

$ sudo mkdir -p /var/lib/php/session
$ sudo mkdir -p /var/run/php/
$ sudo chown -R nginx:nginx /var/lib/php/session/
$ sudo chown -R nginx:nginx /var/run/php/

Often the php/session directory changes ownership and breaks functions, like when php restarts. This ACL permission change will guaruntee persistent functionality. These policies set default permissions for these folders with nginx as ‘another’ owner of the directory and any new contents of it.

 $ sudo setfacl -dm u:nginx:rwx /var/lib/php/session
 $ sudo setfacl -dm u:nginx:rwx /var/lib/php

Start, and enable php-fpm. We won’t need to configure it here, but be mindful of it as it is a strong dependency of InvoiceNinja.

$ sudo systemctl start php-fpm
$ sudo systemctl enable php-fpm

Installing InvoiceNinja v5!

$ cd /usr/share/nginx/invoiceninja

Fedora, and RedHat based users will need to install source code to run the program, because npm pulls different dependencies for some systems. So use git to download the latest code, and pull the v5-stable branch for the best current release available.

$ sudo git clone https://github.com/invoiceninja/invoiceninja
$ sudo rsync -av invoiceninja/ ./
$ sudo rm -rf invoiceninja
$ git checkout v5-stable

First time install only, setup .env file and db encryption key:

Generate your .env file.

$ sudo cp .env.example .env

Back this up!!

Remember, this key you generated just now is an encryption key for the contents of the database entries. You need this to access any of the data on the SQL database. The artisan key:generate command populates the .env file with your encryption key. after you run this and finish setting up your db and logging into the web client, you really should backup the working .env file somewhere secure, in case you ever clobber it.

Install composer

If you don’t have Composer installed on your server yet, you will install it now, so you can download dependencies for PHP stuff with it.

$ curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/bin --filename=composer

Running Composer to install InvoiceNinja Dependencies

As pointed out by another user, we can install the same versions of software that the developers intended by running composer option ‘install’ instead of ‘update’. ‘Update’ option would update the software dependencies to new versions (not standardized versions) and update the .lock file included in the package as well. The ‘–no-dev’ option stops composer from installing dependencies for the developers only.

$ sudo -u nginx php -d memory_limit=-1 `which composer` i --no-dev

Optionally

increase PHP memory limit yourself, and no longer forced to workaround memory limmit issue, get better PHP performance too, as long as you have good amount of RAM to use. Use your text editor of choice.

$ sudo vim /etc/php.ini

You will find and edit the line beginning with memory_limit = and change the following value to 1024M. In vim, remember you can find fast with the ‘/’ key in command mode.

memory_limit = 1024M

From then on you can run the following instead of this especially long elaborate php command above:

 $ sudo -u nginx php composer i --no -dev

Run npm commands to install dependencies, especially for headless chrome, necessary for PDF generation

Running npm install as opposed to npm update again has the same intended purpose of standardization of dependencies. The ‘–no-optional’ argument will instruct npm to ignore dependencies for other OS and you won’t see the errors when those cannot install.

$ sudo chown -R nginx:nginx ./
$ sudo -u nginx npm install --no-optional

Now we a assign a randomly generated application encryption key to the software.

$ sudo -u nginx php artisan key:generate

And then auto-configure the server. Run php artisan optimize again anytime you edit the files or make changes in the invoiceninja installation directory.

$ sudo -u nginx php artisan optimize

SELINUX CHOICES: Ongoing maintenance, or disable completely - READ CAREFULLY

I’ve summarized the best I know how, to configure SELINUX appropriately for all the features in the current release of invoiceninja v5, but I might not be able to update this or support you in the future if the codebase changes a bit, or you uncover new behaviours that demand new permissions from SELinux. If you do not want to support SELinux, you can permanently set it to permissive mode or disabled. This is a personal choice, and I cannot reccomend either or for you.

IF you do not want to be bothered with SELINUX at all, disable it permanently.

Change the following line from ‘enforcing’ to or ‘disabled’ to permanently change SELINUX state. The Gentoo wiki has a nice page for more reading about the difference between these states: SELinux/Tutorials/Permissive versus enforcing - Gentoo Wiki

$ sudo vim /etc/selinux/config
...
SELINUX=disabled

The above command typically only takes affect after reboot.

Permissive Mode

Under permissive mode, some context rules will still be applied, but those rules can be pre-emptively allowed with the commands below. First though, we must enable SELinux permissive mode, in order to effectively complete the InvoiceNinja setup, especially for PDF rendering and Chrome/Puppeteer, which requires special permissions that I am not smart enough to allow in advance yet.
To temporarily set SELINUX to permissive mode, until the next reboot, run the following:

$ sudo setenforce 0

Initial SELINUX permission setup - These commands will mostly allow you to run invoiceninja, make sure the path in quotes is accurate for your environment:

$ sudo yum install policycoreutils-python-utils

$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/public(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/storage(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/app(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/bootstrap(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/config(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/database(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/resources(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/vendor(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/tests(/.*)?'
$ sudo restorecon -Rv '/usr/share/nginx/invoiceninja/'

For you lazy people with ctrl + c fingers :wink:

$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/public(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/storage(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/app(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/bootstrap(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/config(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/database(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/resources(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/vendor(/.*)?'; sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/invoiceninja/tests(/.*)?'; sudo restorecon -Rv '/usr/share/nginx/invoiceninja/'

Some more known SELINUX policies required during the setup phase, EVEN while in SELINUX permissive mode:

$ sudo setsebool -P httpd_unified 1
$ sudo setsebool -P httpd_execmem 1
$ sudo setsebool -P httpd_can_network_connect 1

And for users in a VM, you will have an additional policy to set I believe, for example, while testing myself, I use VMware Workstation Player on Windows, and must set the policy:

$ setsebool -P use_virtualbox 1

Managing SELINUX with cockpit

I cannot provide a full instruction set on explicitly and cleanly setting SELINUX permissions with InvoiceNinja. Depending on your environment, (VM, bare metal, etc), you may have different daemons requesting different permissions also. What I can suggest, is enabling Cockpit web console, and using the SELINUX tab to manage SELINUX permission requests with. The most effective method, is to set SELINUX to permissive mode in cockpit before attempting invoiceninja setup on web page and after testing PDF, email, and logging in after completing setup, address any SELINUX conflicts reported in cockpit, and then re-enable SELINUX enforcing mode. Also note, this will probably be an ongoing thing to monitor, so as you test features in the new InvoiceNinja, you should enable permissive mode on SELINUX again when troubleshooting them, and monitor for SELINUX conflicts. Log into cockpit at https://127.0.0.1:9090 by default, with your username and password from the system.

$ sudo systemctl enable --now cockpit.socket

For example:

When running setup the first time, you will fail PDF test with SELINUX in enforcing, \until you attempt PDF test, and run the following, then run PDF test and fail again, and then run following commands a second time in a row - a lot easier to manage if you set SELINUX to ‘permissive’ and run any conflict resolutions from cockpit after.

$ sudo ausearch -c 'chrome' --raw | audit2allow -M my-chrome
$ semodule -X 300 -i my-chrome.pp

Unfortunately, beyond these steps with SELINUX I cannot offer a more proficient command list. I am still running mostly in enforcing mode, switching back to permissive as I note a broken feature and actively monitor my SELINUX conflicts while testing features and performing work. If someone finds some modifications to the instructions that might accomodate SELINUX better, and pre-emptively configure permissions and policies for chromium and etc, then let me know somehow, I would appreciate that.

Backing up InvoiceNinja critical files

Two things need to be backed up, if you don’t just backup your entire nginx directory often. You need a backup of your .env file, from the installation directory. This file has a complicated encryption key hash saved, and if this key is lost, you will lose access to your database basically, with no workaround. The entries are encrypted with this key. The other thing we can learn to backup breifly is the database as well. Both can be done with one line commands, that you must modify for your environment. Preferably to a mountpoint on another physical storage device, so that you have something to rebuild with if you lose this one suddenly.

I will not cover it here since there’s many resources for it already, but I suggest to setup cron jobs to perform this DB and env backup on a regular basis.

For “ROOTPASS” you can skip this variable and it will prompt for password, but to automate this, you need to pass the password in plain text. You could probably use any other user for this with the permissions set for the whole db though, to avoid passing rootsql pass in plaintext to a cron file.

  $ cp .env /mnt/yourbackupdisk/backups-invoiceninja/invoice-backup-envfile
  $ sudo mysqldump -u root -p ROOTPASS invoice-db > /mnt/yourbackupdisk/backups-invoiceninja/backup-db.sql

sqldump will dump the contents of the database out for you, but the contents themselves are still encrypted and you need the .env file backed up with your key as well.

Especially Important… .env

to backup your .env file, I can’t stress enough, as you host on Enterprise Linux 8 at this time the only way to update is by copying source code package of the next update on top of the existing installation. You don’t wan’t to do something silly on accident and wipe that .env file and destroy your access to your company data.

Congratulations. You should now successfully be able to run InvoiceNinja v5 on Enterprise Linux 8.

6 Likes

A complementary Ubuntu 20.04 LTS version would also be fantastic.

This should work just fine. I tested it all on an Ubuntu VM tonight.

1 Like

Thanks. It’s very helpful.

Thanks for the detailed guide @TechnicallyComputers :metal:

It’s helped me perform the install on a Debian 10 (Buster) LEMP stack obviously using Debian equivalents where necessary. My Ninja setup page is redirecting back to itself on first run so I’ve got some debugging to do :hammer: :smiley:

Just a note of something I noticed while installing composer. After install you ran the update command:

$ sudo composer update

I’m new to composer but the composer documentation explains that update will install the latest available versions of all dependencies then update the lock file with the newly installed version numbers.

Now please don’t take this the wrong way, I’m merely being an inquisitive debugger in lieu of detailed documented requirements from the Invoice Ninja crew. It seems to me, the purpose of the composer.lock file is to ensure anybody deploying a project (in this case Invoice Ninja) ends up with the same suite of dependencies as when the project was successfully compiled, therefore omitting the possibility of incompatible dependencies being loaded. If the lock file is overwritten with the latest versions by the update command, we no longer have the same working environment for Ninja as when it was compiled by the Ninja devs. To quote getcomposer.org:

If there is a composer.lock file in the current directory, it will use the exact versions from there instead of resolving them. This ensures that everyone using the library will get the same versions of the dependencies.

I completely get installing the latest versions of everything by default; I’m attempting the v5 install primarily because I didn’t want to roll back my php7.4 to an older version (v4 being incompatible with 7.4). Now, you have Ninja working and so again, I’m not questioning your methods :v: :grin: but my question is I suppose, was there a reason for updating to the latest dependencies rather than abiding by the composer.lock file in the Ninja zip?

I wasn’t aware of this about composer and the lockfile to standardize dependencies. Thats very intelligent design, and I understand and support the idea for stability and standardization.

I’m going to have to research that more, and update my notes before rewriting anything yet though.

I would say this guide is for CentOS 8, and it has very different dependencies and issues than Ubuntu and probably Debian. For example, the ninja.zip file is not possible to install on CentOS 8. Composer may work but npm update will critically fail almost every step. CentOS 8 requires installing from source-code.zip exclusively. Seems the source code has this file too, so I might test that.

I’d say I only recently confirmed this to myself and didn’t update this version of the guide yet since I was making other changes as well so this wasn’t reflected when you read this guide

1 Like

I guess I wondered if you updated the dependencies beyond the .lock file versions on purpose to help with bugs. It’s my first time using any dependency managers to create ‘sandbox’ environments and I also think it’s pretty cool for standardisation.

Also, you might be interested to know that Node.js/npm has the same functionality using the .json file:

install - Installs dependencies to the dev spec in json file
update - Ignores the json file and update to latest available

There’s a short post here that explains their behaviour well if it interests you.

After I posted this I found your write up on Ubuntu :grin:

Actually both your guides helped me in different places with Debian so thank you! Now I have to fix a login screen bug :face_with_monocle:

1 Like

Login screen bug might be php-fpm related. Verify php-fpm is configured properly if you have not already. My CentOS 8 guide assumes a CentOS 8 environment, and the nginx configuration notes assume default CentOS 8 paths for php-fpm sockets. Relevant:

   fastcgi_pass unix:/var/run/php-fpm/www.sock

Configure nginx/apache to point to this socket wherever php-fpm is configured to run it on your system and ensure your web server has permissions to access it also based on the conf file for php-fpm, wherever it is installed.

I’ll make a reminder to read this stuff next weekend or something, thanks.

Thanks, PHP is ok I think, it’s pointed here in the nginx block

fastcgi_pass unix:/run/php/php7.4-fpm.sock;

I think my problem is mariadb related:

Deserializing '[data, [{permissions: , n~

It’s a server running a few other sites too so everything seems healthy

Did you try to migrate data, or clean install? Data migrations must be done through the webui on v4, running parallel to v5 with two resolvable domains, and will fail if you use SQL dump methods. If your permissions are not sticking with the defined mariadb user, you might experiment with using the root user, to try and rule out one variable. Ok good luck, I have other work. The slack chat is very active by the devs, if you need to look for a little more deeper support that’s a good resource.

It’s a clean install. Thanks for the tip that’s a good idea, I think I’ll try with root. If I solve it I’ll make a note to the solution on here as I’ve talked about it now.

Thanks for your help :+1:

EDIT: The issue causing Deserializing '[data, [{permissions: , n~ on the login modal appears to be fixed in the latest git v2 branch :partying_face:

1 Like

Thanks for the update, that’s great to hear!

1 Like

For those like me, looking for chrome headless dependencies in debian based OS: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md

2 Likes

firewall-cmd command is wrong and should be,

$ sudo firewall-cmd --zone=public --add-service=http --permanent
$ sudo firewall-cmd --zone=public --add-service=https --permanent
$ sudo firewall-cmd --reload

sudo -u nginx mkdir -p /usr/share/nginx/invoiceninja gets permission denied. You instead have to use chown -R after creating the folder
sudo chown -R nginx:nginx /usr/share/nginx/invoiceninja

1 Like

Excellent guide, thank you TechnicallyComputers! Just noticed a few minor things that I had to tweak to get everything working!

MariaDB refused to create a database with dashes in it, so I used ninja instead:
create database ninja;

–permanent needs to be the first command here:
sudo firewall-cmd --permanent -zone=public -add-service=http
sudo firewall-cmd --permanent -zone=public -add-service=https

Not sure if this is the same for others, but git was not installed on my system by default:
sudo yum install git

Composer needs to be installed before generating key:
sudo php artisan key:generate

When backing up, had to make the directory first:
sudo mkdir backupdir

Then I had to remove the slash before /backupdir for the following commands:
sudo cp .env backupdir/invoice-backup-envfile
sudo mysqldump -u root -p ninja > backupdir/invoice-backup-db.sql

Other than that everything worked perfectly! Now the struggle to get migration from v4 working… :rofl:

1 Like

Thanks for catching the typos. I’ve been updating the guide pretty frequently, and recently tried adding respect for the nginx user throughout the process more explicitly, which also produces fewer warnings than running as root and changing ownership after. I’ll update that this weekend.

The migration is a struggle. I have two physically separate machines running the v4 and the v5 throughout this whole beta process and that helps. I keep the old v4 offline and use hosts files to provide name resolution for it, to accommodate the migration process.

I noticed that too after trying to use the name ‘db-ninja-01’. I only put that there to match the default on the setup page, without matching the default .env.example. I’ll change that too, but fyi it will actually work as a db name if you wrap the db name in that lower case tilde key like this:

CREATE DATABASE `db-ninja-01`;

But I recommend just using a regular name like ‘ninja’ or ‘invoices’

I’ve made the relevant changes, and then some. I’ve noticed you used a relative path for the backupdir. That was not my intention. I’ve been more explicit now in the instructions, but you should be backing up those critical files to another physical storage device mounted somewhere else on the system (which can be used along with a compatible version of invoice ninja code to reinstall and reconfigure your database).

It might not really apply to VPS users, but I am sure they can just backup to any other directory on the VPS at minimum, and make their own backup solutions.

My intention is to prevent you from accidentally wiping out your encryption key while making changes to IN setup, and to protect you from filesystem or device failure of your primary storage.

1 Like

Hi @TechnicallyComputers

thanks for the tutorial… so far so fine, but the Nginx doesn’t load the invoiceninja server block. I get the default Nginx page. Do u have any suggestions to fix this?

Many Thanks
Daniel

You have a fully resolvable domain? This could be a few things, you could not have DNS with for example cloudflare setup right. If you know you don’t and want it to work anyways, you could make the domain name resolvable using /etc/hosts and adding a new line for your desired website name.

The guide covers setting up OpenSSL for local encryption, but to make a public facing website with something like cloudflare dns, and letsencrypt for SSL certificates, but that’s beyond the scope of this, and it assumes you have that setup.

If you do have DNS setup and you believe it is correct, you could have to edit the .conf file for the nginx test site and change the extension to .conf.bak, and restart nginx, it may be overriding this other config.