Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Invoice Ninja Ubuntu
GUIDEInstall Guides

How to Install Invoice Ninja on Ubuntu 24.04 VPS: Self-Hosted Invoicing & Billing

26 min read

How to Install Invoice Ninja v5 on Ubuntu 24.04 VPS — Self-Hosted Invoicing & Billing

Invoice Ninja is one of the most mature open-source invoicing platforms available, rivaling commercial products like FreshBooks and QuickBooks Online. Self-hosting it on your own VPS gives you unlimited clients, unlimited invoices, full data ownership, and no monthly subscription fees. This guide walks you through a production-grade installation of Invoice Ninja v5 on Ubuntu 24.04, from a freshly provisioned server to a TLS-secured billing system with queue workers, scheduled tasks, and PDF generation working end to end.

Skip the setup hassle? Deploy a pre-configured LEMP stack on our CloudCore Starter VPS and have Invoice Ninja running in under 30 minutes. All you need is a domain.

Table of Contents

  • What is Invoice Ninja?
  • Why Self-Host Invoice Ninja v5?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Install Nginx
  • Step 3: Install PHP 8.3 and Required Extensions
  • Step 4: Install and Configure MariaDB
  • Step 5: Download Invoice Ninja v5
  • Step 6: Configure the .env File
  • Step 7: Run Database Migrations
  • Step 8: Set File Permissions
  • Step 9: Configure the Nginx Server Block
  • Step 10: Enable TLS with Let's Encrypt
  • Step 11: Schedule the Cron Job
  • Step 12: Run the Queue Worker as a systemd Service
  • Step 13: Complete First-Run Setup
  • Post-Install: Payment Gateways, Branding, Recurring Invoices
  • Backups and Updates
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Invoice Ninja?

    Invoice Ninja is a free, open-source invoicing, billing, and business management suite built on the Laravel PHP framework with a React-based client portal. It began in 2014 as a simple invoicing tool and has grown into a full accounts-receivable platform used by freelancers, agencies, and small-to-medium businesses worldwide. The project is distributed under the Elastic License (AAL 3.0) and the source code is maintained at invoiceninja.github.io.

    The v5 release (currently the actively developed branch) is a complete rewrite of the older v4 codebase. It introduces a modern Vue.js admin interface (the "React Admin Portal"), a faster API, native support for multiple companies under one account, improved tax handling for EU VAT and US state sales tax, and a dedicated mobile app for iOS and Android.

    The feature set is broad. On the core billing side you get unlimited invoices and quotes, recurring invoices with auto-billing, proposals that convert to invoices, credit notes and refunds, and statements for client accounts. For time and project tracking, Invoice Ninja includes a project management module, task timers that convert tracked hours into billable line items, and expense tracking with receipt attachments and markup rules. The client portal lets your customers log in, view outstanding invoices, pay online, download PDFs, and approve quotes. You also get multi-currency support, 40+ payment gateway integrations (Stripe, PayPal, Authorize.net, Mollie, GoCardless, and more), customizable PDF templates, a REST API, webhooks, and Zapier integration.

    Invoice Ninja is used by solo consultants tracking a handful of clients, agencies managing hundreds of recurring subscriptions, and SaaS companies that need a white-label billing backend. Because it is self-hosted, all invoice PDFs, client payment details, and financial records stay on your own server.

    Why Self-Host Invoice Ninja v5?

    The hosted SaaS version of Invoice Ninja starts at around $10/month per user for the Pro plan and scales up with feature tiers. Running your own copy on a VPS eliminates that recurring cost and delivers several additional advantages:

    • Free forever, unlimited everything -- The self-hosted version has no client limits, no invoice limits, no user limits, and no feature restrictions. You only pay for the VPS.
    • Complete data ownership -- Invoices, client details, tax numbers, and payment records stay on your server. Nothing is transmitted to Invoice Ninja's cloud.
    • Custom branding -- Remove the "Powered by Invoice Ninja" footer, use your own domain, apply your own color scheme, and ship invoices that look like they came from your own billing system.
    • API rate limits you control -- The hosted version throttles API calls. On your own server you set the limits based on your infrastructure.
    • GDPR compliance by design -- Keeping EU citizen financial data on an EU-hosted VPS simplifies Article 28 compliance. You are the processor and the controller.
    • Integration freedom -- Run the database locally alongside your other business tools (CRM, ERP, analytics), join tables directly, and build reports without hitting an external API.
    • Custom PDF templates -- Modify the invoice templates with your own HTML/CSS and upload custom fonts. Full control over every pixel.

    Cost Comparison: Self-Hosted vs. Hosted Invoice Ninja vs. Commercial Alternatives

    ScenarioInvoice Ninja Hosted ProFreshBooks PlusQuickBooks Online EssentialsSelf-Hosted on VPS
    Monthly cost$10/user/mo$33/mo$35/moEUR 7.99/mo (CloudCore Starter)
    Client limitUnlimited50 billableUnlimitedUnlimited
    Invoice limitUnlimitedUnlimitedUnlimitedUnlimited
    Users included1 (add-on for more)13Unlimited
    Custom brandingLimitedLimitedLimitedFull
    Data residencyUS-basedUS-basedUS-basedYour choice
    Annual cost (3 users)$360$396$420~EUR 60
    For any business sending more than a handful of invoices per month, the self-hosted payback period is typically under 30 days.

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to your server (PuTTY on Windows, Terminal on macOS/Linux)
    • A domain name pointed at your VPS IP address (required for TLS and email deliverability)
    • At least 1 GB of RAM (2 GB+ recommended for comfortable operation with background workers)
    • At least 10 GB of free disk space for the application, database, PDF storage, and attachments
    • SMTP credentials or a transactional email service (Postmark, Mailgun, Amazon SES) for sending invoices via email
    Recommended Plan: CloudCore Starter
    >
    For a small-to-medium invoicing workload (up to a few thousand invoices per month), we recommend the CloudCore Starter plan:
    >
    - 3 vCPU cores
    - 8 GB RAM
    - 75 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 7.99/month
    >
    This provides comfortable headroom for PHP-FPM, MariaDB, the queue worker, and the PDF rendering service to coexist. If you are billing larger volumes (tens of thousands of invoices per month) or running multiple companies under one install, scale up to a CloudCore Professional or Business plan.

    Connect to your server via SSH to begin:

    bash
    ssh root@your-server-ip

    This guide assumes your domain is billing.example.com. Replace it with your actual domain throughout.

    Step 1: Update System Packages

    Start with a full package update. This ensures you have the latest security patches and that dependency resolution works cleanly during the PHP and MariaDB installs.

    bash
    sudo apt update && sudo apt upgrade -y

    Expected output (abbreviated):

    text
    Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
    Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
    Reading package lists... Done
    Building dependency tree... Done
    Calculating upgrade... Done
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

    Install a few basic utilities you will need throughout the install:

    bash
    sudo apt install -y curl wget unzip git software-properties-common ca-certificates lsb-release gnupg

    If the kernel was updated, reboot before continuing:

    bash
    sudo reboot

    Step 2: Install Nginx

    Invoice Ninja works with both Apache and Nginx. We recommend Nginx for its lower memory footprint and better handling of concurrent PHP-FPM workers under modest VPS resources.

    bash
    sudo apt install -y nginx

    Enable and start the service:

    bash
    sudo systemctl enable --now nginx

    Allow HTTP and HTTPS through the firewall:

    bash
    sudo ufw allow OpenSSH
    sudo ufw allow 'Nginx Full'
    sudo ufw --force enable

    Verify Nginx is responding:

    bash
    curl -I http://localhost

    Expected output:

    text
    HTTP/1.1 200 OK
    Server: nginx/1.24.0 (Ubuntu)

    For a fuller walkthrough of the web server, see our guide on How to Install Nginx on Ubuntu 24.04.

    Step 3: Install PHP 8.3 and Required Extensions

    Invoice Ninja v5 requires PHP 8.1 or newer. PHP 8.3 is the current stable release and ships in Ubuntu 24.04's default repositories, so no third-party PPAs are needed.

    Install PHP-FPM and the extensions Invoice Ninja depends on:

    bash
    sudo apt install -y \
        php8.3-fpm php8.3-cli php8.3-common \
        php8.3-bcmath php8.3-ctype php8.3-curl \
        php8.3-fileinfo php8.3-gd php8.3-gmp \
        php8.3-iconv php8.3-intl php8.3-mbstring \
        php8.3-mysql php8.3-opcache php8.3-tokenizer \
        php8.3-xml php8.3-zip php8.3-soap php8.3-imap

    Each of these extensions has a purpose in Invoice Ninja:

    • bcmath, gmp -- Arbitrary precision math for currency calculations
    • ctype, mbstring, tokenizer -- Laravel core requirements
    • fileinfo -- Attachment handling and MIME detection
    • gd -- Image processing for logos and signatures
    • iconv, intl -- Character set conversion and internationalization (locales, currencies)
    • curl -- Outbound HTTP for payment gateway APIs and webhooks
    • mysql, pdo_mysql -- MariaDB/MySQL database connectivity
    • openssl (bundled with PHP core) -- TLS, encryption, signing
    • xml, soap -- Integrations that use XML/SOAP endpoints
    • zip -- Installer ZIP handling and attachment archives
    • opcache -- Opcode caching for production performance
    Tune PHP for Invoice Ninja by editing the FPM pool:

    bash
    sudo nano /etc/php/8.3/fpm/php.ini

    Change the following values (search with Ctrl+W):

    ini
    memory_limit = 512M
    upload_max_filesize = 50M
    post_max_size = 50M
    max_execution_time = 180
    max_input_time = 180
    date.timezone = UTC

    Restart PHP-FPM:

    bash
    sudo systemctl restart php8.3-fpm
    sudo systemctl enable php8.3-fpm

    For a general LEMP stack walkthrough, see our guide on How to Install the LEMP Stack on Ubuntu 24.04 and the deeper PHP configuration reference.

    Step 4: Install and Configure MariaDB

    Invoice Ninja supports MySQL and MariaDB. MariaDB is the drop-in replacement maintained by MySQL's original authors and is what we recommend.

    bash
    sudo apt install -y mariadb-server mariadb-client

    Enable and start the service:

    bash
    sudo systemctl enable --now mariadb

    Run the secure installation wizard. Accept the defaults (press Enter) except where prompted for a root password:

    bash
    sudo mysql_secure_installation

    Answer the prompts:

    • Switch to unix_socket authentication? n
    • Change the root password? Y (set a strong password)
    • Remove anonymous users? Y
    • Disallow root login remotely? Y
    • Remove test database? Y
    • Reload privilege tables? Y
    Create the Invoice Ninja database and user. Replace STRONG_PASSWORD_HERE with a randomly generated password:

    bash
    sudo mariadb

    Inside the MariaDB shell:

    sql
    CREATE DATABASE ninja CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'ninja'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD_HERE';
    GRANT ALL PRIVILEGES ON ninja.* TO 'ninja'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    Invoice Ninja requires the local_infile setting to be enabled for CSV imports. Edit the MariaDB config:

    bash
    sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

    Under [mysqld], add or uncomment:

    ini
    local_infile = 1
    sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
    innodb_file_per_table = 1

    Restart MariaDB:

    bash
    sudo systemctl restart mariadb

    For a deeper dive into database tuning, see How to Install MariaDB on Ubuntu 24.04.

    Step 5: Download Invoice Ninja v5

    Create the application directory and download the latest release. The official release ZIPs are published at github.com/invoiceninja/invoiceninja/releases — always grab the latest v5.x.x tag.

    bash
    sudo mkdir -p /var/www/invoiceninja
    cd /var/www/invoiceninja

    Fetch the latest release archive. At the time of writing the most recent version is v5.10.x — check the releases page for the current version and substitute it below:

    bash
    sudo wget https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar -O invoiceninja.tar

    Extract into the current directory:

    bash
    sudo tar -xf invoiceninja.tar -C /var/www/invoiceninja --strip-components=1
    sudo rm invoiceninja.tar

    The directory should now contain the standard Laravel layout (app/, bootstrap/, config/, public/, storage/, vendor/, artisan, etc.). The official release bundle ships with vendor/ already populated, so you do not need to run composer install on the server.

    Step 6: Configure the .env File

    Copy the example environment file and generate an application key.

    bash
    cd /var/www/invoiceninja
    sudo cp .env.example .env

    Generate the encryption key (Laravel uses this for cookies, sessions, and field-level encryption):

    bash
    sudo php artisan key:generate --force

    Edit the .env file:

    bash
    sudo nano .env

    Set the core configuration values:

    ini
    APP_NAME="Your Company Billing"
    APP_ENV=production
    APP_DEBUG=false
    APP_URL=https://billing.example.com

    DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=ninja DB_USERNAME=ninja DB_PASSWORD=STRONG_PASSWORD_HERE

    BROADCAST_DRIVER=log CACHE_DRIVER=file QUEUE_CONNECTION=database SESSION_DRIVER=file SESSION_LIFETIME=120

    MAIL_MAILER=smtp MAIL_HOST=smtp.postmarkapp.com MAIL_PORT=587 MAIL_USERNAME=your-smtp-username MAIL_PASSWORD=your-smtp-password MAIL_ENCRYPTION=tls [email protected] MAIL_FROM_NAME="${APP_NAME}"

    REQUIRE_HTTPS=true TRUSTED_PROXIES=*

    PDF_GENERATOR=snappdf

    A few notes on these values:

    • APP_URL must match the exact URL (including https://) where you will access the admin interface. PDF generation and webhook signatures depend on this being correct.
    • QUEUE_CONNECTION=database stores pending jobs in MariaDB. For higher throughput you can switch to redis later.
    • PDF_GENERATOR=snappdf uses Invoice Ninja's built-in headless Chromium wrapper for PDF rendering (covered in the troubleshooting section).
    Save and exit (Ctrl+O, Enter, Ctrl+X).

    Step 7: Run Database Migrations

    With the .env file in place, populate the database schema:

    bash
    cd /var/www/invoiceninja
    sudo php artisan migrate --seed --force

    Expected output (abbreviated):

    text
    INFO  Preparing database.
      Creating migration table .................................. 12ms DONE

    INFO Running migrations. 2014_10_13_000000_create_users_table ..................... 245ms DONE 2014_10_13_000000_create_accounts_table .................. 198ms DONE ... Database seeding completed successfully.

    The --seed flag loads reference data: countries, currencies, tax rates, language translations, and default invoice/quote templates.

    To populate the app with example clients, invoices, and products for testing (optional, recommended only on non-production installs):

    bash
    sudo php artisan db:seed --class=RandomDataSeeder --force

    Finally, warm up the Laravel caches for production performance:

    bash
    sudo php artisan optimize

    This compiles the config, routes, and view caches so they are not rebuilt on every request.

    Step 8: Set File Permissions

    Nginx and PHP-FPM run as the www-data user. The application needs write access to storage/ (logs, cached views, generated PDFs, uploaded attachments) and bootstrap/cache/ (compiled Laravel caches).

    bash
    sudo chown -R www-data:www-data /var/www/invoiceninja
    sudo find /var/www/invoiceninja -type d -exec chmod 755 {} \;
    sudo find /var/www/invoiceninja -type f -exec chmod 644 {} \;
    sudo chmod -R 775 /var/www/invoiceninja/storage
    sudo chmod -R 775 /var/www/invoiceninja/bootstrap/cache
    sudo chmod -R 775 /var/www/invoiceninja/public

    The 775 on storage/, bootstrap/cache/, and public/ allows the group (www-data) to write. Every other file and directory is read-only for the web server.

    Step 9: Configure the Nginx Server Block

    Create the Invoice Ninja server block. The document root must point at public/ (the Laravel front controller lives there).

    bash
    sudo nano /etc/nginx/sites-available/invoiceninja

    Paste the following, replacing billing.example.com with your domain:

    nginx
    server {
        listen 80;
        listen [::]:80;
        server_name billing.example.com;

    root /var/www/invoiceninja/public; index index.php index.html;

    client_max_body_size 50M;

    location / { try_files $uri $uri/ /index.php?$query_string; }

    location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_read_timeout 180; }

    location ~ /\.(?!well-known).* { deny all; }

    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|ttf|svg)$ { expires 30d; add_header Cache-Control "public, no-transform"; } }

    Enable the site and remove the default:

    bash
    sudo ln -s /etc/nginx/sites-available/invoiceninja /etc/nginx/sites-enabled/
    sudo rm -f /etc/nginx/sites-enabled/default

    Test the configuration and reload:

    bash
    sudo nginx -t
    sudo systemctl reload nginx

    You should now be able to reach http://billing.example.com in a browser and see the Invoice Ninja setup screen. Do not proceed with the web installer yet — finish the TLS and cron setup first.

    Step 10: Enable TLS with Let's Encrypt

    Invoice Ninja stores credit card details (via tokenized gateway references) and authenticates users via cookies. TLS is mandatory for production. Let's Encrypt issues free, 90-day certificates that renew automatically.

    Install Certbot and the Nginx plugin:

    bash
    sudo apt install -y certbot python3-certbot-nginx

    Request a certificate. Certbot will automatically modify your Nginx config to add the TLS listener and redirect HTTP traffic to HTTPS:

    bash
    sudo certbot --nginx -d billing.example.com

    Answer the prompts (enter an email, accept terms, choose redirect-to-HTTPS).

    Verify auto-renewal is scheduled:

    bash
    sudo systemctl status certbot.timer
    sudo certbot renew --dry-run

    For a complete walkthrough including DNS-01 challenges and wildcard certificates, see How to Install Let's Encrypt SSL on Ubuntu 24.04.

    Step 11: Schedule the Cron Job

    Invoice Ninja relies on Laravel's scheduler for recurring invoice generation, payment retries, reminder emails, daily stats, and cleanup tasks. The scheduler must be triggered every minute.

    Open the crontab for the www-data user:

    bash
    sudo crontab -u www-data -e

    Add this line at the bottom:

    text
        * cd /var/www/invoiceninja && /usr/bin/php artisan schedule:run >> /dev/null 2>&1

    Save and exit. Laravel's scheduler runs once a minute and decides internally which jobs to dispatch based on their defined schedule (hourly, daily, monthly, etc.).

    Verify the cron entry is registered:

    bash
    sudo crontab -u www-data -l

    Step 12: Run the Queue Worker as a systemd Service

    Invoice Ninja dispatches background jobs for email sending, PDF generation, webhook delivery, and payment processing to a queue. Without a queue worker, invoices will sit unsent and PDFs will never render.

    Create a systemd unit:

    bash
    sudo nano /etc/systemd/system/invoiceninja-worker.service

    Paste:

    ini
    [Unit]
    Description=Invoice Ninja Queue Worker
    After=network.target mariadb.service

    [Service] User=www-data Group=www-data Restart=always RestartSec=3 WorkingDirectory=/var/www/invoiceninja ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600 StandardOutput=append:/var/log/invoiceninja-worker.log StandardError=append:/var/log/invoiceninja-worker.log

    [Install] WantedBy=multi-user.target

    Reload systemd, enable, and start:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now invoiceninja-worker
    sudo systemctl status invoiceninja-worker

    Expected output:

    text
    ● invoiceninja-worker.service - Invoice Ninja Queue Worker
         Loaded: loaded (/etc/systemd/system/invoiceninja-worker.service; enabled; preset: enabled)
         Active: active (running) since Wed 2026-04-16 11:30:00 UTC; 5s ago
       Main PID: 2345 (php)
          Tasks: 1 (limit: 9404)
         Memory: 42.0M

    The --max-time=3600 flag restarts the worker every hour, which keeps memory usage stable (long-running PHP processes tend to accumulate memory).

    Supervisor Alternative

    If you prefer Supervisor to systemd (for multi-worker scaling), install it:

    bash
    sudo apt install -y supervisor
    sudo nano /etc/supervisor/conf.d/invoiceninja-worker.conf

    Paste:

    ini
    [program:invoiceninja-worker]
    process_name=%(program_name)s_%(process_num)02d
    command=/usr/bin/php /var/www/invoiceninja/artisan queue:work --sleep=3 --tries=3 --max-time=3600
    autostart=true
    autorestart=true
    user=www-data
    numprocs=2
    redirect_stderr=true
    stdout_logfile=/var/log/invoiceninja-worker.log
    stopwaitsecs=3600

    Apply:

    bash
    sudo supervisorctl reread
    sudo supervisorctl update
    sudo supervisorctl start invoiceninja-worker:*

    Use either systemd or Supervisor, not both.

    Step 13: Complete First-Run Setup

    Visit https://billing.example.com in your browser. You will be redirected to the setup wizard.

    The wizard asks for:

  • Database credentials -- These are pre-populated from .env. Click "Test Database Connection."
  • Email configuration -- Pre-populated from .env. Click "Test Mail Configuration" to send yourself a test email.
  • Account email and password -- This creates your first admin user.
  • Site URL confirmation -- Should match APP_URL in .env.
  • Click Submit. Invoice Ninja writes a lock file, finalizes the install, and redirects you to the admin dashboard.

    Log in with the admin email and password you just set. You will land on the dashboard, which shows outstanding invoices, overdue amounts, and revenue graphs (all at zero for a fresh install).

    Post-Install: Payment Gateways, Branding, Recurring Invoices

    With the core system running, these are the most common setup tasks for a production billing system.

    Connect Stripe

    Navigate to Settings -> Online Payments -> Payment Methods -> Add Gateway -> Stripe.

  • In your Stripe Dashboard, copy the Publishable Key and Secret Key.
  • Paste into the Invoice Ninja configuration screen.
  • Enable the payment methods you accept (Credit Card, ACH, SEPA Direct Debit, iDEAL, etc.).
  • Configure the webhook: Stripe -> Developers -> Webhooks -> Add Endpoint. URL is https://billing.example.com/payment_webhook/COMPANY_KEY/GATEWAY_ID (Invoice Ninja shows the exact URL in the gateway settings).
  • Connect PayPal

    Same flow under Settings -> Online Payments -> Payment Methods -> Add Gateway -> PayPal. You'll need a PayPal Business account and REST API credentials from developer.paypal.com.

    Custom Branding

    Go to Settings -> Company Details to set your company name, address, VAT/Tax ID, and logo. Then Settings -> Invoice Design to customize the PDF template, colors, fonts, and watermark. Upload your logo under Settings -> Branding -> Logo.

    To remove the "Powered by Invoice Ninja" footer from emails and the client portal, enable White-Label License under Settings -> Account Management. The self-hosted white-label license is a one-time $30 purchase that removes all Invoice Ninja branding and unlocks custom email signatures — fair support for the open-source project.

    Recurring Invoices

    Create a recurring invoice under Recurring Invoices -> New. Set the frequency (weekly, monthly, annually, custom), the start date, and whether to auto-send and auto-bill. Recurring invoices dispatch on the schedule you set — powered by the cron job you configured in Step 11.

    Client Portal

    Each client automatically gets a portal at https://billing.example.com/client/login. They can view outstanding invoices, pay online, download PDFs, approve quotes, and update their contact details. Customize the portal under Settings -> Client Portal — enable/disable features, set the accent color, and add a custom terms-and-conditions URL.

    Multi-Company Setup

    Invoice Ninja supports up to 10 companies under a single admin account. Click the company dropdown in the top bar and select Add Company. Each company has its own branding, invoice numbering, clients, and financial records.

    Backups and Updates

    Database and File Backups

    Schedule a nightly backup via cron:

    bash
    sudo nano /usr/local/bin/invoiceninja-backup.sh

    Paste:

    bash
    #!/bin/bash
    BACKUP_DIR="/var/backups/invoiceninja"
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    mkdir -p "$BACKUP_DIR"

    Database dump

    mysqldump -u ninja -p'STRONG_PASSWORD_HERE' ninja | gzip > "$BACKUP_DIR/ninja-db-$TIMESTAMP.sql.gz"

    Storage directory (uploaded attachments, logos)

    tar -czf "$BACKUP_DIR/ninja-storage-$TIMESTAMP.tar.gz" -C /var/www/invoiceninja storage

    Retain last 14 days

    find "$BACKUP_DIR" -type f -mtime +14 -delete

    Make it executable and schedule:

    bash
    sudo chmod +x /usr/local/bin/invoiceninja-backup.sh
    sudo crontab -e

    Add:

    text
    0 3   * /usr/local/bin/invoiceninja-backup.sh

    For off-site backup, add a rclone or rsync step to the script pointing at S3, B2, or another VPS.

    In-App Updates

    Invoice Ninja v5 includes a self-updater. Navigate to Settings -> Account Management -> System Settings -> Update App. Click Update and the application will fetch the latest release, back up the current install, and swap in the new version.

    For the self-updater to work, the web server must be able to write to /var/www/invoiceninja. This is already the case if you followed Step 8.

    If the in-app updater fails (common causes: disk full, permissions changed), you can update manually:

    bash
    cd /var/www/invoiceninja
    sudo -u www-data php artisan down
    sudo wget https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar -O /tmp/invoiceninja.tar
    sudo tar -xf /tmp/invoiceninja.tar -C /var/www/invoiceninja --strip-components=1
    sudo chown -R www-data:www-data /var/www/invoiceninja
    sudo -u www-data php artisan migrate --force
    sudo -u www-data php artisan optimize
    sudo -u www-data php artisan up
    sudo systemctl restart invoiceninja-worker

    Always run a database backup before upgrading.

    Troubleshooting

    ProblemCauseSolution
    Invoices not sending via emailQueue worker not runningCheck sudo systemctl status invoiceninja-worker. Inspect /var/log/invoiceninja-worker.log. Restart: sudo systemctl restart invoiceninja-worker
    Recurring invoices not generatingCron not configured or running as wrong userVerify sudo crontab -u www-data -l shows the schedule line. Check /var/log/syslog for cron errors.
    500 Internal Server ErrorPHP error, missing extension, or permissionsTail the log: sudo tail -f /var/www/invoiceninja/storage/logs/laravel.log. Check PHP extensions: php -m \</td><td>grep -i gmp. Re-run Step 8 permissions.
    PDFs fail to generatesnappdf Chromium binary missingRun sudo -u www-data php artisan snappdf:chromium-download. Ensure /tmp is writable.
    "Storage not linked" warningPublic symlink missingsudo -u www-data php artisan storage:link
    "Your database does not support server-side prepared statements"MariaDB configConfirm sql_mode from Step 4 is applied: sudo mariadb -e "SELECT @@sql_mode;"
    Login fails with CSRF errorSession or APP_URL mismatchConfirm APP_URL in .env matches the browser URL exactly (including protocol). Clear caches: sudo -u www-data php artisan optimize:clear
    White label license shows as invalidLicense key encrypted with different APP_KEYDo not regenerate APP_KEY after install — it breaks stored encrypted fields. Restore from backup if needed.
    Client portal shows 404Nginx try_files misconfiguredRe-check the location / block in Step 9. Confirm document root is /var/www/invoiceninja/public.
    Queue jobs pile upWorker crashed or insufficient memoryCheck worker log. Increase memory_limit in php.ini. Restart worker.

    Viewing Logs

    The Laravel application log captures most runtime errors:

    bash
    sudo tail -f /var/www/invoiceninja/storage/logs/laravel.log

    The queue worker log:

    bash
    sudo tail -f /var/log/invoiceninja-worker.log

    Nginx access and error logs:

    bash
    sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

    PDF Generation Deep Dive

    Invoice Ninja v5 uses snappdf (a headless Chromium wrapper) to render PDFs in the same browser engine customers see in the client portal. On first install, you need to download the Chromium binary:

    bash
    cd /var/www/invoiceninja
    sudo -u www-data php artisan snappdf:chromium-download

    If Chromium fails to launch on your VPS (common in constrained containers), install the system dependencies:

    bash
    sudo apt install -y libnss3 libatk-bridge2.0-0 libx11-xcb1 libxcomposite1 \
        libxdamage1 libxrandr2 libgbm1 libxkbcommon0 libpango-1.0-0 libcairo2 libasound2t64

    As an alternative, you can switch to the hosted PDF service by setting PDF_GENERATOR=hosted_ninja in .env — Invoice Ninja's team hosts a free rendering service for self-hosted installs.

    FAQ

    Is the self-hosted version of Invoice Ninja really free forever?

    Yes. The core Invoice Ninja v5 codebase is published under the Elastic License (AAL 3.0) and remains free to self-host for commercial use. The only paid component is the optional White-Label License ($30 one-time), which removes Invoice Ninja branding from client-facing pages and emails and unlocks custom email signatures. There is no user cap, no invoice cap, no client cap, and no feature gate. All payment gateway integrations, recurring billing, the client portal, project/time tracking, and the API are included.

    What's the difference between Invoice Ninja v4 and v5?

    Invoice Ninja v4 (legacy) is the original Laravel codebase and will continue receiving security patches but no new features. Invoice Ninja v5 is a full rewrite with a new React-based admin interface, a faster API (3-5x improvement on most endpoints), native multi-company support, better tax handling for EU VAT and US state sales tax, and an improved client portal. All new installs should use v5. If you have a v4 install, the project provides a v4-to-v5 migration tool that exports v4 data and imports it into a fresh v5 install.

    Can I run Invoice Ninja behind a reverse proxy or CDN?

    Yes. Add TRUSTED_PROXIES= (or a specific IP range) to .env and ensure your proxy sets X-Forwarded-Proto: https and X-Forwarded-For headers. For Cloudflare, enable "Full (Strict)" SSL mode and set the origin certificate appropriately. For Varnish or Nginx reverse proxies, pass through all /api/ and /payment_webhook/* routes without caching.

    How do I send invoices via Postmark, Mailgun, or Amazon SES?

    All three work seamlessly via SMTP. In .env:

    • Postmark: MAIL_HOST=smtp.postmarkapp.com, port 587, username/password = your server API token
    • Mailgun: MAIL_HOST=smtp.mailgun.org, port 587, username = your Mailgun SMTP user, password = your SMTP password
    • Amazon SES: MAIL_HOST=email-smtp.us-east-1.amazonaws.com (pick your region), port 587, use IAM SMTP credentials
    For better deliverability, configure SPF, DKIM, and DMARC DNS records for your sending domain. Invoice Ninja also supports direct API mailers (MAIL_MAILER=postmark, MAIL_MAILER=ses) — see the Invoice Ninja docs for driver-specific env variables.

    Can I run multiple companies or white-label for clients?

    Yes. A single Invoice Ninja install supports up to 10 companies under one admin account, each with its own branding, clients, and numbering. For true multi-tenant SaaS (separate databases per customer), you'll need to run separate Invoice Ninja installs per tenant or use the API to provision under a single instance. For agency use cases where you bill your own clients and also manage billing for their end-customers, the 10-company limit is usually sufficient.

    How does Invoice Ninja compare to Akaunting, Crater, and BillBee?

    Invoice Ninja has the most mature feature set, the largest gateway integration library (40+), a polished client portal, and native mobile apps for iOS and Android. The community is large and the release cadence is fast (monthly patch releases).

    Akaunting is a broader accounting suite (invoices + double-entry bookkeeping + inventory + payroll) and competes more directly with QuickBooks than with pure invoicing tools. Heavier to self-host, smaller gateway library.

    Crater is a newer, Laravel-based invoicing tool with a clean UI but fewer features (no recurring invoices in the core, no time tracking, smaller gateway library). Best for simple use cases.

    BillBee is a commercial SaaS focused on e-commerce order management with invoicing as one feature. Not self-hostable.

    For most VPS users wanting a self-hosted invoicing and billing platform, Invoice Ninja remains the best balance of features, maturity, and active development.

    Next Steps

    Now that Invoice Ninja is running on your VPS, here are recommended next steps to harden and extend your setup:

    • Harden SSH and enable unattended upgrades -- Disable password authentication, switch to SSH keys, and enable unattended-upgrades so security patches apply automatically. See our guide on Ubuntu server hardening.
    • Add Redis for faster queues and sessions -- Swap QUEUE_CONNECTION=database and SESSION_DRIVER=file for redis. Redis on a local socket is dramatically faster under load. Install Redis, update .env, and restart PHP-FPM and the worker.
    • Monitor uptime and alert on failures -- Deploy Uptime Kuma on a separate server and monitor both the admin URL and the /api/v1/health endpoint. Alert via email, Slack, or Discord when either is down.
    • Integrate with your CRM via the API -- Invoice Ninja exposes a full REST API documented at api-docs.invoicing.co. Push new clients from your CRM (HubSpot, Pipedrive) directly into Invoice Ninja, or pull invoice status back into your CRM for commission tracking.
    • Set up Zapier or n8n automations -- Connect Invoice Ninja to 5,000+ apps via the official Zapier integration or self-host n8n on the same VPS. Common workflows: send a Slack alert on payment received, create a Trello card for each new invoice, sync payments into a Google Sheet.
    • Explore the plugin ecosystem -- The Invoice Ninja GitHub org hosts companion tools including the iOS/Android apps, Chrome extension for time tracking, and community gateway packs.

    Skip the Manual Install — Get a Production-Ready VPS
    >
    Our CloudCore Starter VPS gives you the exact stack this guide installs — Ubuntu 24.04, 8 GB RAM, 75 GB NVMe SSD — for EUR 7.99/month. Deploy in 60 seconds, point your domain, and follow this guide end to end in under 30 minutes.
    >
    - Ubuntu 24.04 LTS pre-installed
    - Full root access with SSH
    - Unmetered bandwidth on a 1 Gbit/s port
    - Daily automated snapshots available
    - 24/7 support from humans who use Invoice Ninja themselves
    >
    Deploy Your Billing VPS Now — Plans start at EUR 7.99/month.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket