Run InvoiceNinja 5 Docker installation with a SSL/TLS certificate
In this post you will learn how to secure your InvoiceNinja 5 docker installation with a SSL/TLS certificate. This will securely encrypt the communication between the client and the server part of InvoiceNinja 5 and is hence a key part if you're running this on a public URL.
In my previous post I have explained how you can run InvoiceNinja 5 in a Docker image using docker compose.
To simplify this post, I will be using self-sigend certificates. You can obtain certificates also for a trusted authority like Let's encrypt. You can check out my post how to set up a NGINX with Let's encrypt here.
Create the SSL/TLS certificates
The first step is to create the certificates. This can be done with openssl and the following command.
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
This will create a public (/etc/ssl/certs/nginx-selfsigned.crt) and a private key (/etc/ssl/private/nginx-selfsigned.key) in the directoy /etc/ssl and with a validity of 365 days. The private key will be without a password (-nodes).
Preparing the NGINX
The docker image of InvoiceNinja 5 comes with a NGINX as web server hosting the content. The configs for the web server are stored in ./docker/nginx/*. The standard configuration is the in-vhost.conf. Next you create a copy of tthe config and rewrite it to server port 443 for SSL/TLS.
cd /docker/nginx/
sudo cp in-vhost.conf in-vhost-ssl.conf
sudo vim in-vhost-ssl.conf
Change the content of the file to the following:
server {
#port 443 to enable standard ssl
listen 443 ssl;
server_name localhost;
#Adding the certificates
ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/private/nginx-selfsigned.key;
client_max_body_size 100M;
root /var/www/app/public/;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
}
If you want to server both, 443 and 80 you can keep the inital port 80 config in the file, redirect all port 80 traffic to 443 or use a reverse proxy on 443 to redirect the traffic to port 80.
That's it for the NGINX config.
Config docker-compose for InvoiceNinja 5 to server SSL/TLS
As next step you will need to tell the docker image where the certificates are and open port 443. You need to edit the docker-compose.yml file and change it as follows:
version: '3.7'
services:
server:
image: nginx
restart: always
env_file: env
volumes:
# Vhost configuration
- ./config/nginx/in-vhost-ssl.conf:/etc/nginx/conf.d/default.conf:ro
- ./docker/app/public:/var/www/app/public:ro
- /etc/ssl/certs:/etc/ssla #add certificates volume
depends_on:
- app
# Run webserver nginx on port 80
# Feel free to modify depending what port is already occupied
ports:
- "81:80"
- "443:443" #uncomment this line to server port 443
networks:
- invoiceninja
extra_hosts:
- "in5.test:192.168.xx.xx " #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.test:192.168.xx.xx " #host and ip
db:
image: mysql:5
ports:
- "3305:3306"
restart: always
env_file: env
volumes:
- ./docker/mysql/data:/var/lib/mysql:rw,delegated
networks:
- invoiceninja
extra_hosts:
- "in5.test:192.168.xx.xx " #host and ip
networks:
invoiceninja:
Now rebuild the docker and you can checkt InoiceNinja 5 out using SSL/TLS. E.g. with https://<your-ip>