Invoice Ninja ist eine sehr umfragreiches Rechnungsstellungsplattform und das beste ist Invoice Ninja ist Open Source! Hier zeige ich euch wie ihr es mittels Docker zum laufen bekommt. Mit einer Lizenz unterstütz man das OpenSource Projekt und das Invoice Ninja Logo auf der Rechnung wird entfernt.
1. Voraussetzungen
- Docker installiert (Anleitung)
- Traefik v2 installiert
2. Repositories clonen
Auch wenn wir die ein oder andere Anpassung manuel machen müssen vereinfacht es diese Anleitung ungemein also clonen wir uns das offizielle GIT-Repository:
git clone https://github.com/invoiceninja/dockerfiles /opt/containers/invoiceninja
cd /opt/containers/invoiceninjaCode-Sprache: PHP (php)
3. Anpassungen
3.1. Docker-Compose.yml aufräumen und anpassen
nano docker-compose.ymlCode-Sprache: CSS (css)
version: '3.7'
services:
server:
image: nginx
restart: always
env_file: env
volumes:
# Vhost configuration
#- ./config/caddy/Caddyfile:/etc/caddy/Caddyfiledocker-com
- ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
- ./docker/app/public:/var/www/app/public:ro
depends_on:
- app
# Run webserver nginx on port 80
# Feel free to modify depending what port is already occupied
ports:
- "80:80"
#- "443:443"
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
app:
image: invoiceninja/invoiceninja:5
env_file: env
restart: always
volumes:
- ./config/hosts:/etc/hosts:ro
- ./docker/app/public:/var/www/app/public:rw,delegated
- ./docker/app/storage:/var/www/app/storage:rw,delegated
depends_on:
- db
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
db:
image: mysql:5
# When running on ARM64 use MariaDB instead of MySQL
# image: mariadb:10.4
# For auto DB backups comment out image and use the build block below
# build:
# context: ./config/mysql
ports:
- "3305:3306"
restart: always
env_file: env
volumes:
- ./docker/mysql/data:/var/lib/mysql:rw,delegated
# remove comments for next 4 lines if you want auto sql backups
#- ./docker/mysql/bak:/backups:rw
#- ./config/mysql/backup-script:/etc/cron.daily/daily:ro
#- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro
#- ./config/mysql/backup-script:/etc/cron.monthly/monthly:ro
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
# THIS IS ONLY A VALID CONFIGURATION FOR IN 4. DO NOT USE FOR IN 5.
# cron:
# image: invoiceninja/invoiceninja:alpine-4
# volumes:
# - ./docker/app/public:/var/www/app/public:rw,delegated
# - ./docker/app/storage:/var/www/app/storage:rw,delegated
# - ./docker/app/public/logo:/var/www/app/public/logo:rw,delegated
# entrypoint: |
# /bin/sh -c 'sh -s <<EOF
# trap "break;exit" SIGHUP SIGINT SIGTERM
# sleep 300s
# while /bin/true; do
# ./artisan ninja:send-invoices
# ./artisan ninja:send-reminders
# sleep 1d
# done
# EOF'
# networks:
# - invoiceninja
#
networks:
invoiceninja:
Code-Sprache: PHP (php)
version: '3.7'
services:
server:
container_name: invoiceninja-server
image: nginx
restart: always
env_file: env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
- ./docker/app/public:/var/www/app/public:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.invoiceninja.entrypoints=http"
- "traefik.http.routers.invoiceninja.rule=Host(`invoiceninja.deine-domain.de`)"
- "traefik.http.routers.invoiceninja-secure.entrypoints=https"
- "traefik.http.routers.invoiceninja-secure.rule=(Host(`invoiceninja.deine-domain.de`))"
- "traefik.http.routers.invoiceninja-secure.tls=true"
- "traefik.http.routers.invoiceninja-secure.tls.certresolver=http"
- "traefik.http.routers.invoiceninja-secure.service=invoiceninja"
- "traefik.http.services.invoiceninja.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
depends_on:
- app
networks:
- invoiceninja
- proxy
app:
container_name: invoiceninja-app
image: invoiceninja/invoiceninja:5
env_file: env
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config/hosts:/etc/hosts:ro
- ./docker/app/public:/var/www/app/public:rw,delegated
- ./docker/app/storage:/var/www/app/storage:rw,delegated
depends_on:
- db
networks:
- invoiceninja
db:
container_name: invoiceninja-db
# image: mysql:5
build:
context: ./config/mysql
restart: always
env_file: env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./docker/mysql/data:/var/lib/mysql:rw,delegated
- ./docker/mysql/bak:/backups:rw
#- ./config/mysql/backup-script:/etc/cron.daily/daily:ro
- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro
#- ./config/mysql/backup-script:/etc/cron.monthly/monthly:ro
networks:
- invoiceninja
networks:
invoiceninja:
proxy:
external: true
Code-Sprache: PHP (php)
Was angepasst wurde und was individuel angepasst werden muss:
Server:
- Container einen Namen zuordnen mit
container_name - Unnötiger Kommentare entfernt und die auskommentierte
caddy-Konfiguration rausgeworfen - Zeit mit dem Host-System syncronisiert via
- /etc/localtime:/etc/localtime:ro - Labels hinzugefügt. Hier müsst ihr eure Domain anpassen!
- Die Ports aus
serverentfernt. Erreichbarkeit läuft über Traefik. networksumproxyerweitertextra_hostsentfernt
App:
- Container einen Namen zuordnen mit
container_name - Zeit mit dem Host-System syncronisiert via
- /etc/localtime:/etc/localtime:ro extra_hostsentfernt
DB:
image: mysql:5auskommentiertBuildaktiviert- Zeit mit dem Host-System syncronisiert via
- /etc/localtime:/etc/localtime:ro ./docker/mysql/bak:/backups:rwaktiviert- Jetzt die Backup Strategie hier wählen – ich habe hier wöchentlich für mich gewählt
networks:
- Hinzufügen von
proxyzu dem Standard-Netzwerk.
3.2. MYSQL Dockerfile anpassen
Auch wenn ich es in den Issues schon angesprochen habe und es auch ausführlich getestet habe hat es noch keinen Einzug in das Repository genommen. Wir benötigen diese Änderung aber damit die Backups auch funktionieren:
nano config/mysql/Dockerfile
FROM mysql:5-debian
# When running on ARM64 use MariaDB instead of MySQL
#FROM mariadb:10.4
ENV force_color_prompt yes
RUN apt-get update;
RUN apt-get install -y cron;
ENTRYPOINT \
service cron start; \
printenv | grep -v "no_proxy" >> /etc/environment; \
docker-entrypoint.sh mysqld
Code-Sprache: PHP (php)
Angepassungen:
- Hier wurde aus
mysql:5nunmysql:5-debian
3.3. env-Datei anpassen
Kommen wir zum Herzstück des ganzen die Konfiguration. Doch bevor wir diese anpassen müssen wir kurz noch einen Befehl ausfüren um uns einen passenden Passpharase zu generieren:
docker run --rm -it invoiceninja/invoiceninja php artisan key:generate --show
Den ausgegebenen Schlüssel kopieren wir uns in unsere Zwischenablage und bearbeiten nun die env:
nano env
# IN application vars
APP_URL=http://in.localhost:8003
APP_KEY=<insert your generated key in here>
APP_DEBUG=true
REQUIRE_HTTPS=false
PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*'
QUEUE_CONNECTION=database
# DB connection
DB_HOST=db
DB_PORT=3306
DB_DATABASE=ninja
DB_USERNAME=ninja
DB_PASSWORD=ninja
# Create initial user
# Default to these values if empty
# IN_USER_EMAIL=admin@example.com
# IN_PASSWORD=changeme!
IN_USER_EMAIL=
IN_PASSWORD=
# Mail options
MAIL_MAILER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS='user@example.com'
MAIL_FROM_NAME='Self Hosted User'
# MySQL
MYSQL_ROOT_PASSWORD=ninjaAdm1nPassword
MYSQL_USER=ninja
MYSQL_PASSWORD=ninja
MYSQL_DATABASE=ninja
# V4 env vars
# DB_STRICT=false
# APP_CIPHER=AES-256-CBC
Code-Sprache: PHP (php)
# IN application vars
APP_URL=https://invoiceninja.deine-domain.de # Domain anpassen
APP_KEY=base64:UoAcImuCqsOYzA1BpVXtUDtI/fsacMEl6JXXXXXXXX= # Schlüssel aus der Zwischenablage
APP_DEBUG=false # Debug deaktivieren. In der Produktiv-Version stellt dies eine Sicherheitslücke da
REQUIRE_HTTPS=false # Bleibt deaktiviert. Traefik regelt.
PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*' # Hier könnte man auch spezifisch Hosts deklarieren aber nicht notwendig.
QUEUE_CONNECTION=database
# DB connection
DB_HOST=invoiceninja-db # Anpassung an den Container Namen.
DB_PORT=3306
DB_DATABASE=ninja
DB_USERNAME=ninja
DB_PASSWORD=ninja # Hier kann auch ein sichereres Passwort gewählt werden
# Create initial user
# Default to these values if empty
# IN_USER_EMAIL=admin@example.com
# IN_PASSWORD=changeme!
IN_USER_EMAIL= # Administrative Email eintragen
IN_PASSWORD= # Random passwort -> wird nur zum Login benötigt und kann später jederzeit geändert werden
# Mail options
MAIL_MAILER=smtp # Auf SMTP ändern
MAIL_HOST=smtp.mailtrap.io # Eigenen Server eintragen
MAIL_PORT=2525 # Eigenen SMTP Port eintragen
MAIL_USERNAME=null # SMTP-Usernamen eintragen
MAIL_PASSWORD=null # SMTP-Passwort eintragen
MAIL_ENCRYPTION=null # SMTP-Verschlüsslung eintragen
MAIL_FROM_ADDRESS='user@example.com' # Mailadresse eintragen
MAIL_FROM_NAME='Self Hosted User' # Absendernamen eintragen
# MySQL
MYSQL_ROOT_PASSWORD=ninjaAdm1nPassword
MYSQL_USER=ninja
MYSQL_PASSWORD=ninja # Selbes Passwort wie unter DB_PASSWORD definiert
MYSQL_DATABASE=ninjaCode-Sprache: PHP (php)
3.4. Rechte anpassen
Nun müssen wir noch die Rechte für ein paar Pfade anpassen:
chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/appCode-Sprache: PHP (php)
4. Build durchführen
Nun müssen wir einmal ein Build durchführen damit auch der Backup Cron funktioniert:
docker compose build
5. Container starten
docker compose up -d
Ich hoffe ich habe nichts vergessen – ansonsten hinterlasst mir eine Nachricht in den Kommentaren.
Viel Freude beim ausprobieren

Hallo
psycho0verload , ich verstehe nicht wo ich einen Fehler gemacht habe.
Hmmm…diese Seite ist leider nicht erreichbar
Es sieht so aus, als ob die Webseite unter https://invoiceninja.domain.de/ Probleme hat oder sie wurde möglicherweise dauerhaft zu einer neuen Webadresse verschoben.
ERR_SSL_UNRECOGNIZED_NAME_ALERT
Kann mir da jemand helfen, und weiß zufällig aus Erfahrung wo der Fehler steckt?
Moin ich krieg den Fehler 404, alle anderen Docker funktionieren und hab auch schon alles geprüft
Die Traefik Log Meldung zeigt mir:
level=error msg=”the service \”backoffice@docker\” does not exist” entryPointName=https routerName=invoiceninja-secure@docker
Vielen Dank für die tolle Anleitung. Hat soweit auch alles funktioniert. Ich bekomme im Adminpanel jedoch eine seltsame Benachrichtigung und aus der hinterlegten Doku/Website. Hat jemand vlt eine Idee?