Automated invoice generation with customizable HTML templates for webstores and SaaS integration
2.1K

nullInvoice is a Spring Boot microservice for automated invoice generation and management with fully customizable HTML templates, designed for integration with webstores and SaaS platforms.
Generate compliant invoices on-demand via REST API with PDF export, multi-tenant support, and document immutability for financial compliance.
Create a docker-compose.yml:
version: '3.8'
services:
nullinvoice:
image: nullata/nullinvoice:latest
container_name: nullinvoice
ports:
- "8080:8080"
environment:
- TZ=Europe/Sofia
- DB_HOST=mariadb
- DB_PORT=3306
- DB_USER=nullinvoice
- DB_PASSWORD=changeme
- DB_NAME=nullinvoice
- DB_PARAMS=?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/Sofia
- QUEUE_ENABLED=true
depends_on:
- mariadb
restart: unless-stopped
mariadb:
image: mariadb:10.11
container_name: nullinvoice-db
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=nullinvoice
- MYSQL_USER=nullinvoice
- MYSQL_PASSWORD=changeme
- TZ=Europe/Sofia
volumes:
- mariadb_data:/var/lib/mysql
restart: unless-stopped
volumes:
mariadb_data:
Start the stack:
docker compose up -d
Access the application at http://localhost:8080
If you have an existing MariaDB/MySQL instance:
docker run -d \
--name nullinvoice \
-p 8080:8080 \
-e TZ=Europe/Sofia \
-e DB_HOST=your-db-host \
-e DB_PORT=3306 \
-e DB_USER=nullinvoice \
-e DB_PASSWORD=your_password \
-e DB_NAME=nullinvoice \
-e DB_PARAMS='?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/Sofia' \
--restart unless-stopped \
nullata/nullinvoice:latest
The application user needs these permissions (DELETE intentionally excluded for compliance):
CREATE DATABASE nullinvoice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'nullinvoice'@'%' IDENTIFIED BY 'your_secure_password';
GRANT SELECT, INSERT, UPDATE ON nullinvoice.* TO 'nullinvoice'@'%';
GRANT CREATE, ALTER, INDEX, REFERENCES ON nullinvoice.* TO 'nullinvoice'@'%';
FLUSH PRIVILEGES;
The database schema is managed automatically by Flyway migrations on startup.
| Variable | Required | Default | Description |
|---|---|---|---|
TZ | Yes | - | System timezone (e.g., Europe/Sofia, America/New_York) |
APP_PORT | No | 8080 | Application port |
DB_HOST | Yes | localhost | Database host |
DB_PORT | No | 3306 | Database port |
DB_USER | Yes | nullinvoice | Database username |
DB_PASSWORD | Yes | - | Database password |
DB_NAME | Yes | nullinvoice | Database name |
DB_PARAMS | Yes | - | JDBC connection parameters including serverTimezone |
QUEUE_ENABLED | No | true | Master switch for the async invoice generation worker. Set to false to disable the background poller. |
CRITICAL: The TZ environment variable and serverTimezone in DB_PARAMS must match your database server timezone to ensure correct date/time handling.
On first access, you'll be redirected to /setup:
http://localhost:8080/loginBy default, UI sessions expire after 30 minutes of inactivity. To customize, you can mount a custom application.yml:
server:
servlet:
session:
timeout: 60m # Options: 15m, 30m, 1h, 2h, etc.
Mount the file in your container:
volumes:
- ./custom-application.yml:/app/config/application.yml:ro
template_id or template_name/swagger (requires login)Generate an invoice via API:
curl -X POST http://localhost:8080/api/v1/invoices/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"response_type": "pdf",
"supplier_id": 1,
"client": {
"name": "Client Co",
"addressLine1": "123 Main St",
"city": "Sofia",
"country": "BG"
},
"items": [
{"description": "Service", "quantity": 1, "unit_price": 1000, "tax_rate": 0.2}
]
}' -o invoice.pdf
Generate API keys from Admin > API Keys after logging in.
⚠️ This application is designed for internal/private network deployment.
Recommended deployment:
Production checklist:
UI available in: English, Bulgarian, German, Spanish, Italian, Russian
Invoice templates can be created in any language with proper font support.
Example invoice templates are available in 6 languages in the repository:
View Example Templates on GitHub
Templates are fully customizable XHTML with inline CSS and support 30+ placeholders for supplier, client, and financial data. Upload custom templates via the web UI after setup.
/swagger (requires login)/openapiThe application stores all data in the MariaDB database. Ensure you persist the database volume:
volumes:
- mariadb_data:/var/lib/mysql
No application-level volumes are required.
curl http://localhost:8080/api/v1/health
Returns 200 OK when the application is healthy.
View application logs:
docker logs nullinvoice
docker logs -f nullinvoice # Follow logs
This project is licensed under the Elastic License 2.0.
Copyright 2026 nullata
✨ Submit additional image requests at: GitHub repository.
✨ Report issues: github.com/nullata/nullInvoice/issues
✨ Support the project: ko-fi.com/nickscripts
Content type
Image
Digest
sha256:57c327568…
Size
193.8 MB
Last updated
20 days ago
docker pull nullata/nullinvoice