Self Host Installation
Invoice Ninja adapts to however you want to host it. You can use whatever fits your access level. Start with the option that is easiest today and switch later when your needs change.
Secure & fast maintenance
CLI
Install, configure, update, back up, monitor, and receive notifications for your self-hosted Invoice Ninja, from a single CLI. Requires SSH access.
Focus on saving time,
less stress, certainty, and convenience.
Docker or Podman
Docker images
Official containers for Octane and Debian builds. Perfect for reproducible environments and quick pilots.
Running web stack
Server manual install
Install from the tarball or git, tweak nginx/Apache yourself, and own every line. Works great on bare metal or cloud VMs. You can still adopt the CLI later to automate updates and backups.
Cloudron server
Cloudron marketplace
Deploy Invoice Ninja as an app and let Cloudron handle SSL, backups, and log rotation.
Softaculous access
Softaculous one-click
Hosting panels that include Softaculous (cPanel, DirectAdmin, etc.) can install Invoice Ninja with a few clicks.
Elestio server
Elestio managed VM
Elestio provisions a VM, installs Invoice Ninja, and keeps monitoring and backups running for you.
YunoHost server
YunoHost package
If you already run YunoHost, add Invoice Ninja as an app and inherit its user and domain management features.
Server requirements
- PHP 8.2 with: bcmath, ctype, imagick, soap, gd, mbstring, openssl, tokenizer, xml, curl, zip, gmp, iconv, mysqli, intl, FPM (for nginx), and saxon (for e-invoice validation).
- MySQL 5.7+ or MariaDB 10.3+, or a compatible managed MySQL tier.
- nginx or Apache with HTTPS enabled.
sudo apt install php8.2-bcmath php8.2-gmp php8.2-gd php8.2-mbstring \
php8.2-xml php8.2-curl php8.2-zip php8.2-mysql php8.2-fpm \
php8.2-imagick php8.2-soap php8.2-common php8.2-intl
Invoice Ninja v5 is not an in-place upgrade from v4.x—start with a clean install before migrating data.
Install into the document root (domain or subdomain). Subdirectories such as https://example.com/ninja are not supported.
Shared hosting providers can still run Invoice Ninja, but make sure cron access is available. Softaculous or the manual tarball method is usually the quickest way to deploy on shared environments, and you can always migrate out later with the INmanage CLI once you have full server access.
Linux server configs
Prefer to see the entire build spelled out? These community guides take you from bare metal to a running Invoice Ninja instance. Every path below can later be handed over to the INmanage CLI card for automated updates and backups once the web server and database are running.
Ubuntu 22.04
TechnicallyComputers’ step-by-step guide for Invoice Ninja v5.5 on the latest LTS release.
Debian 12 (Bookworm)
Dros’ tutorial plus a management script for updates, backups, and general deployments.
Debian 12 via WSL
Install Invoice Ninja on Windows using WSL with the same automation scripts.
Enterprise Linux 8
Companion guide for Alma, Rocky, and other Enterprise Linux distributions.
Arch Linux
Community-maintained walkthrough covering pacman packages and Arch-specific tweaks.
Manual install checklist
This path gives you full control over every package. Once the base install is up, you can still point the INmanage CLI at the same server—it will adopt the instance and handle future updates and backups for you.
-
Download the latest
invoiceninja.tarfrom the GitHub releases. -
Unpack it into your vhost root (for example
/var/www/invoiceninja). -
Set permissions so the web user owns the files:
sudo chown -R www-data:www-data /var/www/invoiceninja
sudo find /var/www/invoiceninja -type d -exec chmod 755 {} \; -
Configure nginx (sample below) or Apache. Enable gzip for quicker page loads.
server {
listen 80;
server_name ninja.example.com;
root /var/www/invoiceninja/public;
index index.php index.html;
client_max_body_size 20M;
location = /index.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ \.php$ { return 403; }
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ /\.ht { deny all; }
} -
Create the database and grant a user full access (MySQL’s official guide can help).
-
Configure cron so the Laravel scheduler fires every minute:
* * * * * cd /var/www/invoiceninja && php artisan schedule:run >> /dev/null 2>&1Shared hosting often requires:
* * * * * cd /path/to/root && /usr/bin/php -d register_argc_argv=On artisan schedule:run >> /dev/null 2>&1 -
Run the web installer at
https://ninja.example.com/setup, enter your database credentials, and you’re done.
After installation
- Git installs:
git clone --depth 1 https://github.com/invoiceninja/invoiceninja.gitthen follow the manual checklist before pointing the browser to/setup. Note: The React UI is not included and needs to be wired manually. So, really not the way to go for production. For production and full CLI control consider the INmanage CLI card. - Docker tips: restart containers after editing
.envand keep your volumes mapped so invoices survive rebuilds. - Queues: enable the Laravel queue worker (Supervisor) once you have root access. Laravel’s guide shows the unit file.
Whatever route you picked, the INmanage CLI and Docker stacks make it easy to move between servers later, so start simple and iterate.
$ sudo supervisorctl start invoiceninja-worker:*
Running the following will show worker processes as RUNNING (on my installation, I see 8 worker processes, numbered 00 through 07)
$ sudo supervisorctl status
Now that the Supervisor is configured, we need to tell Invoice Ninja to actually use it.
Edit the .env file for Invoice Ninja
$ sudo vi /path/to/invoiceninja/.env
Edit the following line to change it from sync to database, and save the file
QUEUE_CONNECTION=database
Finally, now that everything is set up, reload the config for Invoice Ninja and restart the queue. I’m using www-data for this example as the web server user.
$ cd /path/to/invoiceninja/
$ sudo -u www-data php artisan optimize
$ sudo -u www-data php artisan queue:restart
That’s it! You should now have a functioning Supervisor setup for Invoice Ninja.
Alternative for queues on shared hosting
If you are on shared hosting, it is possible to get the queues working by defining a new cron with the following configuration:
*/5 * * * * cd /path/to/root/folder && /usr/bin/php -d register_argc_argv=On artisan queue:work --stop-when-empty
Some people have different web hosting setups, so this might also work:
*/5 * * * * php /home/admin/domains/site.com/private_html/invoices_site/artisan queue:work --stop-when-empty
This cron will start a queue worker every 5 minutes and run any jobs that are in the queue and then gracefully terminate itself. This means any emails / notification may be queued for a small period of time prior to executing. If this amount of delay is acceptable, it is a great way to get queue's working on shared hosting.
If you prefer to manage the queues with Supervisor, then you will want to disable the internal Invoice Ninja commands which start the queue, to do this simly set the following .env var
INTERNAL_QUEUE_ENABLED=false
You will then have full control over the queue.
Shared Hosting
Keep this section short and pragmatic: many tasks are easier with the CLI card above, but if your provider only offers shared hosting, follow the list below.
Server requirements
Invoice Ninja needs the following PHP functions on shared hosting. If any of them are disabled, open a ticket with your provider or consider switching to a Softaculous-capable host (see the Softaculous card above).
- proc_open
- exec
- open_basedir
- fpassthru
Without these modules, the installer will fail. The setup wizard performs checks, but it is faster to confirm with your host before you start.
Quick path (Softaculous)
If your control panel includes Softaculous (cPanel, DirectAdmin, Plesk, etc.):
- Open the Softaculous marketplace and search for “Invoice Ninja”.
- Follow the one-click installer (same metadata as the Softaculous card).
- After the app is live, add the cron entry Softaculous proposes or use the snippet below.
Manual path (tarball)
- Create a MySQL-compatible database + user with full privileges.
- Download the latest
invoiceninja.tarfrom GitHub releases and upload it topublic_html(or the document root your panel exposes). - Extract the archive and rename
.env.exampleto.env. - Point your subdomain to the
/publicdirectory. Example:/domains/domain.com/public_html/invoices/public/. - Visit
https://yourdomain.com/setup, fill in the wizard, review any errors instorage/logs/laravel.logif needed.
Cron on shared hosting
Add the scheduler cron job in your panel (adjust paths as needed):
* * * * * cd /path/to/root/folder && /usr/bin/php -d register_argc_argv=On artisan schedule:run >> /dev/null 2>&1
Queues can be run with a 5‑minute worker if Supervisor isn’t available:
*/5 * * * * cd /path/to/root && /usr/bin/php -d register_argc_argv=On artisan queue:work --stop-when-empty
When you outgrow shared hosting, clone the site to a VPS and hand it over to the INmanage CLI installer for automated updates and backups.
Mail Configuration
When configuring your email, please ensure all of the fields are filled in. In particular you must include the MAIL_FROM_ADDRESS and MAIL_FROM_NAME to prevent errors such as
Address in mailbox given [ ] does not comply with RFC 2822, 3.6.2.
Here is a full example - using Gmail as an example.
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME="your_email_address@gmail.com"
MAIL_PASSWORD="your_password_dont_forget_the_quotes!"
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="your_email_address@gmail.com"
MAIL_FROM_NAME="Full Name With Double Quotes"
If you are using SSL encryption the MAIL_PORT is 465. TLS encryption is on port 587.
Individual mail configurations per company
From v5.5.38 we support per company mail configurations.
What does this mean?
For example if you have two Companies, Acme co and Ninja co you can create separate mail server configurations for each company.
To configure this you will need to prefix your .env with the primary key of the company ie In your database open the companies table, and if the primary ID column is 1 for Acme co this would be the configuration
1_MAIL_HOST=
1_MAIL_PORT=
1_MAIL_USERNAME=null
1_MAIL_PASSWORD=null
1_MAIL_ENCRYPTION=null
If Ninja Co company id 5
5_MAIL_HOST=
5_MAIL_PORT=
5_MAIL_USERNAME=null
5_MAIL_PASSWORD=null
5_MAIL_ENCRYPTION=null
Currency Conversion
Invoice Ninja supports Open Exchange for currency conversion. Open Exchange currently provides a free tier which is suitable for daily updates of the exchange rates. Simply insert a Open Exchange API key into your .env file to enable exchange rate updates:
OPENEXCHANGE_APP_ID=your_open_exchange_api_key_here
Currencies are updated automatically by using the scheduler. In case the currencies are not available within the UI please double check the database table currencies and ensure that exchange_rate fields contains realistic values.
Lib Saxon
If using e invoicing, you may want to install the saxon extension. The saxon extension provides XSLT2 validation of e invoice schema's and provides additional confidence that your einvoice will be accepted by third party systems.
- On shared hosting, enable the Saxon extension in cPanel if available.
- On the official Debian Docker image, Saxon is installed via
mlocati/php-extension-installer(saxonin the install list). - On bare‑metal Linux or VM's, you typically install the shared library first, then compile/enable the PHP extension.
- For SaxonC, download the HE build from https://www.saxonica.com/download/c.xml.
We have a short video showing the installation steps here: