Easily update, backup, and install your self-hosted Invoice Ninja instance with a CLI shell script. Maintenance and management has never been faster.
[!TIP] If you seek a very convenient way to install Invoice Ninja from scratch: Go with the Provisioned Installation option.
This script manages your Invoice Ninja installation (version 5 and above) by performing updates, backups, cleanup tasks, and installations, including Installation Provisioning. On the first run, it helps you set up its .env.inmanage
configuration file.
Go to your base directory where the invoiceninja
folder resides or shall reside. Then run:
sudo -u www-data bash -c "git clone https://github.com/DrDBanner/inmanage.git .inmanage && .inmanage/inmanage.sh"
Ensure that www-data
is the correct user (substitute if necessary) who has all the permissions to your Invoice Ninja installation, including reading its .env
configuration file.
If you are in a shared hosting environment with SSH access, you'll most likely have to stick with the user you are logged in and this should/could be fine. Then you install this script with your current user/credentials like this:
git clone https://github.com/DrDBanner/inmanage.git .inmanage && .inmanage/inmanage.sh
And follow the installation wizard. You can accept defaults by pressing [Enter]
. This will take no more than 30 seconds. After that you are ready to go.
[!NOTE]
- Ensure you install in the base directory containing the
invoiceninja
folder to avoid file permission issues.- Run the script as a user who can read the
.env
file of your Invoice Ninja installation. Typically, this is the web server user, such aswww-data
,httpd
,web
,apache
, ornginx
.- Ensure you put its name into the script's
.env.inmanage
configuration file during installation or manually afterwards under $INM_ENFORCED_USER.- The script tries to ensure all needed CLI tools are available and will prompt you if something is missing.
Once installed, you can run the script using the symlink in your base directory. For example:
sudo -u www-data bash -c "./inmanage.sh backup"
This example shows how to run the script in a bash as user www-data
. This can be different on your machine. Like:
./inmanage.sh backup
If you already are the user with the corresponding permissions.
[!TIP] During the installation you have been asked which user shall execute this script. So, if you call it now and you are not that particular user, you'll get prompted to enter the password in order to switch to that user.
So, you probably want to call it with the right user from the get go.
Run the script with one of the following commands to perform the associated tasks:
./inmanage.sh update
./inmanage.sh backup
## As a one-liner:
./inmanage.sh backup && ./inmanage.sh update
Performing a backup prior to an update is a good cause. In case something goes wrong you can switch back to the last working version in no time by renaming the broken installation and putting the last working in place. Like this:
Let's assume your folder looks like this:
ls -la
drwxr-xr-x 15 web vuser 49 20 Juli 22:55 invoiceninja
drwxr-xr-x 15 web vuser 49 20 Juli 14:12 invoiceninja_20240720_141317
drwxr-xr-x 15 web vuser 49 20 Juli 14:13 invoiceninja_20240720_225551
Rename like this:
mv invoiceninja invoiceninja_broken
mv invoiceninja_20240720_225551 invoiceninja
Ensure to substitute the numbers with the correct timestamps/foldername. Now your installation is in the last working state and you prevented downtime.
If you want to run it as a cronjob add this line to your crontab. Mind the user www-data
here as well.
0 2 * * * www-data /path/to/your/inmanage.sh backup > /path/to/logfile 2>&1
I would not update via cronjob. However, if you choose to automate updates with cron, you can include the --force
flag in the update
command to force the update, even if you are already on the latest version.
--force
Flag: The update will proceed regardless of the current version.--force
Flag:
To update the script, use:
cd .inmanage && sudo -u www-data git pull
Note: Ensure you replace www-data
with the appropriate user.
If you have installed the script as the user with the corresponding rights the command looks like this
cd .inmanage && git pull
[!TIP] If you seek a very convenient way to install Invoice Ninja from scratch: Go with the Provisioned Installation option.
clean_install
:
.env.inmanage
[!Important] "When performing a clean install, please ensure that the installation URL matches the format specified in the Invoice Ninja .env file. The URL should be https://127.0.0.1, not https://127.0.0.1/invoiceninja or https://127.0.0.1/invoiceninja/setup to carry on with the GUI db configuration -Invoice Ninja expects to be accessible via base url and not within a path. Make sure your web server is configured accordingly. Note that this is different from the web server’s root path, which should point to
your_path/invoiceninja/public
. For more details, please refer to the Invoice Ninja web server configuration guide."
update
:
--force
flag option.backup
:
cleanup_versions
:
INM_KEEP_BACKUPS
during installation.cleanup_backups
:
INM_KEEP_BACKUPS
during installation.If .inmanage/.env.inmanage
file is not found, the script creates it and prompts for settings like installation directory, backup locations, and other configurations.
You can provision the file manually
# .inmanage/.env.inmanage configuration file
INM_BASE_DIRECTORY="/your/base/directory/" # mind the trailing slash
INM_INSTALLATION_DIRECTORY="./invoiceninja"
INM_ENV_FILE="./invoiceninja/.env"
INM_TEMP_DOWNLOAD_DIRECTORY="./.in_temp_download"
INM_BACKUP_DIRECTORY="./_in_backups"
INM_KEEP_DBTABLESPACE="N" # Removes tablespaces from mysqldump which is needed for 'lower' privileged DB Users.
INM_ENFORCED_USER="www-data"
INM_ENFORCED_SHELL="/bin/bash"
INM_PHP_EXECUTABLE="/usr/bin/php"
INM_ARTISAN_STRING="/usr/bin/php /your/base/directory/./invoiceninja/artisan"
INM_PROGRAM_NAME="InvoiceNinja" # Backup file name
INM_KEEP_BACKUPS="2" # How many iterations to keep
INM_FORCE_READ_DB_PW="N" # Read DB Password from installation or assume existing .my.cnf
Tl:dr; Use this option if you want an "up and running" experience in 2 minutes. Install the script, populate the configuration file with at least database credentials and app url, rename the file, and run the script again. ✨
During setup, the .inmanage/.env.example
file is created, mirroring the standard .env
file (holds the configuration data) of Invoice Ninja. By pre-populating the .inmanage/.env.example
file with APP_URL
and relevant DB_
data, and renaming or copying it to .env.provision
, it becomes a trigger for automated installation provisioning at the next startup of the script. It's a good idea to populate the file with as much as configurations as possible from the get go. You can find valuable hints and options in the Official Documentation for .env and Mail.
Next time you run the script, it performs the following tasks in one batch:
.env.provision
template file to .env
for production useBasically, you save a huge amount of time.
[!IMPORTANT] Within the file
.inmanage/.env.example
are two crucial fields. DB_ELEVATED_USERNAME and DB_ELEVATED_PASSWORD. Fill these fields with credentials of a user that has the rights to create databases and the rights to give grants. In most cases this user is the database root user. Once the creation of the database and user were successful, these credentials do get removed from that file automatically.
IN_CLI_PROVISIONED_INSTALL_vp9.webm
Environment Variables:
.env.inmanage
to configure paths, user settings, PHP executable, and other details.Command Check:
curl
, tar
, php
, etc.) are installed and available on your system.User Check:
Reads Invoice Ninja Configuration
[!CAUTION] If you have set
INM_FORCE_READ_DB_PW="Y"
in your configuration, then it will grab the password and pass it to the mysqldump command. Which CAN be a security issue. So, handle with care.
Version Check
User Interaction
--force
flag enables you to perform the update no matter what.Update Process
Checks
User Interaction
Backup Process
Maybe I'll add some more functionality like initial installation and sync to external locations. We'll see.
Things I could imagine:
I have thought about adding a push/sync function so that backups can be sent to a destination, but the more I think about it, it makes more sense not to, at least at this moment in time. Because in most cases you probably want to transfer a copy to your local network and not synchronize it to a backup server that is available on the internet.
Therefore, it makes much more sense to me to select the backup target directory so that it is monitored by software such as Nextcloud and, in the event of changes, transfers them to your local infrastructure. Have a look at Nexctcloud GitHub as well.
Other solutions may be:
The other option, since we are on a web server, is to make the backup target directory available under a specific URL. Of course, you will not forget to do this in a secure environment, i.e. with the help of user data that not everyone knows.
If you tell me, "No, no ... completely different" then I would think again about creating a cool solution.
Currently, the script is designed to manage a single installation. If you have multiple instances to manage, you'll most probably have them running in different base directories. So, you install this script for each instance.
If you have multiple instances running under the same base directory this script would need to get extended to handle multiple .env.inmange files and a kind of router to manage each instance individually and/or in one batch.
Installation process of the MGM script is the same; But you just do not install any new Invoice Ninja instance. You use the command-line switches for “backup” and “update” → Commands
If you accidentially run the clean_installation
or the provisioned installation
process within an existing installation you get prompted, if you really really want to continue, since there’s already a folder. If you insist with YES here, the old folder gets renamed. So nothing gets deleted.
The .env.provision
file is a template generated from a standard .env
, but it has 2 extra added fields for creating databases. Once it has been processed this .env.provision
file becomes a normal .env
file and gets moved over into a new installation. It’s its only purpose -create new installations. So, in an existing environment it’s just nothing you need to take care of. But if you use it as a kickstarter for a new installation everything you put in there gets copied over -except the DBELEVATED* fields.
This script does not backup any cronjobs nor does it register new ones. It just gives you the exact minimum cronjob line you need after an initial install.
The beloved Invoice Ninja https://github.com/invoiceninja/invoiceninja
If you feel you'd like to donate something for this script go for it: