Invoice Ninja: Self-Hosted Invoicing and Billing for Freelancers and Small Teams
Most freelancers and small businesses reach for a SaaS invoicing tool and end up paying $15 to $30 a month for features they use maybe 20% of. Wave, FreshBooks, QuickBooks — they all work, but they all take a cut of your transaction fees or charge per user, and your billing data lives entirely on their platform. If they change pricing or shut down, you spend a weekend migrating.
Photo by Tim Rüßmann on Unsplash
Invoice Ninja is the open source alternative that takes invoicing seriously. It covers the full billing workflow: quotes that convert to invoices, expense tracking, time logging, recurring billing, client portals where clients can view and pay their invoices, and Stripe integration for accepting card payments. The hosted version is free for up to 10 clients. Self-host it and the client limit disappears entirely.
Invoice Ninja vs. the Field
There are a handful of serious open source invoicing platforms. Here is how they compare.
| Feature | Invoice Ninja | Crater | Akaunting | Frappe/ERPNext |
|---|---|---|---|---|
| Self-hostable | Yes | Yes | Yes | Yes |
| License | Elastic / v4 open source | MIT | GPL-3.0 | GPL-3.0 |
| Invoices & quotes | Yes | Yes | Yes | Yes |
| Expense tracking | Yes | Yes | Yes | Yes |
| Time tracking | Yes | No | No | Yes |
| Recurring invoices | Yes | Yes | Limited | Yes |
| Client portal | Yes | No | No | Yes |
| Payment gateways | 40+ (Stripe, PayPal, etc.) | Stripe, PayPal | 10+ | 10+ |
| Multi-currency | Yes | Yes | Yes | Yes |
| Tax support | Yes | Yes | Yes | Yes |
| Projects / tasks | Yes | No | No | Yes |
| Mobile app | iOS + Android | No | No | No |
| Setup complexity | Medium | Low | Low | High |
| Target user | Freelancers, small teams | Solo freelancers | SMBs | Medium businesses |
Crater is the simplest option — if you just need to send invoices and track payments, it takes 10 minutes to deploy and stays out of your way. Invoice Ninja is the right choice when you also need time tracking, client portals, and a payment gateway that clients can use to pay without emailing you a bank transfer. ERPNext/Frappe is overkill for anything short of a company with a real accounting department.
What Invoice Ninja Includes
Invoice Ninja is a complete billing platform, not just an invoice generator. The feature set breaks down into several areas:
Invoicing and quotes. Create professional invoices with your logo, custom fields, line items, discounts, and taxes. Quotes can be sent to clients, approved by clients through the portal, and converted to invoices in one click. Invoices can be emailed directly from the platform or downloaded as PDFs.
Recurring billing. Set up recurring invoice schedules (weekly, monthly, quarterly, custom) that automatically generate and send on the specified date. Essential for retainer clients or subscription services.
Expenses. Log business expenses with vendor, amount, category, and receipt attachments. Expenses can be marked billable to a client and added to an invoice with a few clicks.
Time tracking. Log time against projects and tasks, then add logged time as billable line items on an invoice. The time tracker is a stopwatch-style tool, not a full project management suite, but it covers the basic freelancer workflow of tracking hours per project.
Client portal. Each client gets a portal where they can view all their invoices, approve quotes, download PDFs, and pay outstanding invoices. This eliminates a lot of back-and-forth email — clients can self-serve without contacting you.
Payment processing. Invoice Ninja connects to over 40 payment gateways. Stripe is the most common. Clients click "Pay Now" in the portal and pay by card. You get notified, the invoice is marked paid automatically.
Installing with Docker Compose
Invoice Ninja v5 runs as a Laravel application. The Docker deployment uses an nginx container alongside the application container.
services:
invoice-ninja:
image: invoiceninja/invoiceninja:5
container_name: invoice-ninja
environment:
APP_URL: "https://invoices.example.com"
APP_KEY: "${IN_APP_KEY}"
DB_HOST: invoice-ninja-db
DB_DATABASE: ninja
DB_USERNAME: ninja
DB_PASSWORD: "${IN_DB_PASSWORD}"
REQUIRE_HTTPS: "true"
TRUSTED_PROXIES: "*"
MAIL_HOST: "smtp.example.com"
MAIL_PORT: "587"
MAIL_USERNAME: "[email protected]"
MAIL_PASSWORD: "${SMTP_PASSWORD}"
MAIL_ENCRYPTION: "tls"
MAIL_FROM_ADDRESS: "[email protected]"
MAIL_FROM_NAME: "Your Business Name"
volumes:
- ninja_public:/var/www/app/public
- ninja_storage:/var/www/app/storage
depends_on:
invoice-ninja-db:
condition: service_healthy
restart: unless-stopped
invoice-ninja-nginx:
image: nginx:alpine
container_name: invoice-ninja-nginx
ports:
- "9000:80"
volumes:
- ninja_public:/var/www/app/public:ro
- ./nginx/in-vhost.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- invoice-ninja
restart: unless-stopped
invoice-ninja-db:
image: mariadb:10.11
container_name: invoice-ninja-db
environment:
MYSQL_DATABASE: ninja
MYSQL_USER: ninja
MYSQL_PASSWORD: "${IN_DB_PASSWORD}"
MYSQL_ROOT_PASSWORD: "${IN_DB_ROOT_PASSWORD}"
volumes:
- ninja_db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
ninja_public:
ninja_storage:
ninja_db_data:
You also need an nginx config file at ./nginx/in-vhost.conf:
server {
listen 80;
server_name _;
root /var/www/app/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass invoice-ninja:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
}
Generate the APP_KEY before first launch:
# Generate a Laravel app key
docker run --rm invoiceninja/invoiceninja:5 php artisan key:generate --show
# Copy the output into your .env as IN_APP_KEY
Then start the stack:
docker compose up -d
Navigate to https://invoices.example.com to complete the setup wizard. The first account created is the admin.
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
Creating Your First Invoice
Once setup is complete, the workflow for sending an invoice is:
Create a client. Go to Clients > New Client. Enter the company name, contact name, email, billing address. The email address is where invoices will be sent.
Create a product (optional). Under Products, create line item templates for services you bill regularly. This saves you from re-typing "Consulting — hourly" on every invoice.
Create an invoice. Invoices > New Invoice. Select the client, add line items (services, products, or ad-hoc descriptions with quantities and rates), apply taxes if needed, and add a due date.
Send it. Click Email Invoice. Invoice Ninja sends the PDF to the client and creates a portal link they can use to view and pay.
The invoice editor is clean and functional. You can drag line items to reorder them, add custom fields, attach files, and include internal notes visible only to you. The PDF output looks professional with minimal effort.
Client Portal and Payment Processing
The client portal is one of Invoice Ninja's strongest features relative to simpler tools. Each client gets a unique URL where they can:
- View all past and outstanding invoices
- Approve or decline quotes
- Download PDFs
- Pay outstanding invoices directly
For payment processing, connect Stripe under Settings > Payment Gateways > Add Gateway. You will need your Stripe publishable key and secret key. Once configured, clients see a "Pay Now" button on outstanding invoices and can pay by card without any friction. Payment confirmation happens automatically — Invoice Ninja receives the webhook from Stripe and marks the invoice as paid.
Stripe is the most common choice, but Invoice Ninja also supports PayPal, Square, Authorize.Net, GoCardless for ACH/BACS, and several dozen regional gateways.
Multi-Currency and Tax Support
Invoice Ninja handles both international billing scenarios well.
Multi-currency. Set a default currency for your company and override it per client. Invoice Ninja stores exchange rates and can display amounts in both the invoice currency and your base currency on reports. Useful for freelancers billing clients in USD, EUR, and GBP simultaneously.
Taxes. Create named tax rates under Settings > Tax Rates. Tax rates can be applied at the invoice level, the line item level, or both. You can configure inclusive taxes (GST in Australia, VAT in Europe) or exclusive taxes. For US freelancers, you can create state-specific tax rates and apply them to the appropriate clients.
Invoices display the tax breakdown clearly, which matters for clients that need to account for input tax credits.
Backup and Maintenance
All state lives in the MariaDB database and the ninja_storage volume (which holds uploaded files and PDFs). Back up both:
# Database backup
docker exec invoice-ninja-db mysqldump -u ninja -p${IN_DB_PASSWORD} ninja > ninja_backup.sql
# Storage volume
docker run --rm -v ninja_storage:/source -v $(pwd):/backup alpine \
tar czf /backup/ninja-storage-$(date +%Y%m%d).tar.gz -C /source .
Upgrading is straightforward — pull the new image and restart. Laravel handles migrations on startup:
docker compose pull invoice-ninja
docker compose up -d invoice-ninja
Check the release notes before major version upgrades. Invoice Ninja v5 is the current generation — do not mix v4 and v5 images.
Honest Trade-offs
Invoice Ninja is a good fit if:
- You are a freelancer or run a small agency and bill multiple clients regularly
- You need time tracking connected directly to invoicing
- Clients paying online through a portal would meaningfully reduce your admin time
- You want recurring invoices without paying for FreshBooks
- Multi-currency billing or complex tax scenarios apply to your business
Consider alternatives if:
- You are a solo freelancer who sends maybe 5 invoices a month. Crater is simpler to set up and maintain, and covers that use case without the complexity.
- You need full double-entry accounting. Invoice Ninja tracks income but is not an accounting system. For that, look at Akaunting or pair Invoice Ninja with a separate tool.
- You want one tool for everything including inventory, HR, and payroll. ERPNext covers all of that at the cost of significant setup complexity.
Practical limitations to be aware of:
The setup is more involved than simpler invoicing tools. The nginx + application container split, the need for a working SMTP configuration before you can invite users, and the queue worker requirements for scheduled tasks mean that getting Invoice Ninja fully operational requires more than a docker compose up. Plan for an hour of initial configuration.
The UI is good but not exceptional. Some areas of the settings feel dated, and finding specific configuration options can involve clicking through several menus. Once configured, day-to-day use is smooth, but initial setup has a learning curve.
Should You Use Invoice Ninja?
For freelancers and small teams who have outgrown manually generating PDFs or simple cloud invoicing tools, Invoice Ninja is the most complete self-hosted option available. The combination of professional invoicing, client portals, time tracking, and Stripe payment processing in a single self-hosted package is genuinely hard to match at any price. You own your data, you control your branding, and you are not paying per-seat fees as your client list grows.
If your needs are simple, start with Crater. If you need everything Invoice Ninja offers, the setup investment pays for itself quickly in time saved chasing payments and managing client billing manually.
