Docker Installation Recommended
Docker is the fastest way to run Simple Invoices. The included Dockerfile and docker-compose.yml handle everything: PHP, Nginx, database, and frontend assets.
Quick Start
The application will be available at http://localhost:8888. Login with the default credentials if this is your first run.
Choosing a Database
Simple Invoices supports three database backends. Switch by editing your .env.local file and using the matching compose command:
MySQL / MariaDB (default)
PostgreSQL
Comment out the MySQL block in .env.local, uncomment the PostgreSQL block, then:
SQLite (no separate DB container)
Comment out the MySQL block, uncomment the SQLite block:
Environment Configuration
Copy .env to .env.local and adjust the following key settings:
Database
Application
Authentication
Debug & Logging
Security
S3 Storage (optional)
For storing biller logos on S3-compatible object storage:
Garage (self-hosted S3): Run
docker compose -f docker-compose.yml -f docker-compose.s3.yml up -d, thenbash scripts/setup-garage.shto create the bucket and generate credentials.
Included Services
Access Adminer at http://localhost:8081 to browse or manage your database directly.
Architecture
The Docker image is built with a multi-stage Dockerfile:
-
Stage 1 (Node.js): Installs npm dependencies and copies frontend vendor assets into
templates/default/vendor/. This stage is throwaway: only the built assets are kept. -
Stage 2 (PHP-FPM + Nginx): Alpine Linux with PHP 8.2, Nginx, and all required PHP extensions. Copies frontend assets from Stage 1, installs Composer dependencies, and configures Nginx to serve the application.
The final image contains no Node.js: only the compiled vendor assets. This keeps the image small and secure.
Updating
To update to the latest version:
Database patches are applied automatically on startup (when SI_AUTO_MIGRATE=true).
Stopping
Troubleshooting
Port already in use
Change the SI_APP_PORT in .env.local to a free port (e.g., 8080).
Database connection refused
The app waits up to SI_DB_WAIT_MAX seconds (default 30) for the database to become ready. If you see connection errors, check that:
- The database service is running:
docker compose ps - Database credentials match those in
.env.local - The database adapter matches your chosen compose profile
Permission errors on tmp/
The Dockerfile sets correct permissions automatically (chown -R www-data:www-data). If you manually bind-mount the tmp/ directory, ensure the host directory is writable by UID 82 (www-data in Alpine).
Rebuilding after dependency changes
No-cache builds ensure fresh npm and composer installs.