Installation¶
Auditize is a Python 3.12+ application that uses MongoDB as a database and do not use the filesystem to persist data. It's base configuration is 100% environment variables based, making it easy and flexible to configure, especially in a Docker environment.
Auditize is composed of two distinct services:
- an ASGI web application that serves both the API and the frontend
- a scheduler that runs period tasks
It is delivered as a Python package on PyPI that can be installed with pip
(the package installer for Python). Please note that the Auditize package dependencies are pinned to ensure a stable and reproducible installation.
The following sections will guide you through the installation of Auditize in two different contexts:
MongoDB
Auditize requires MongoDB 7.0+ to run. It uses transactions for certain operations, meaning that your MongoDB server must be configured with a replica set. Please note that a replicat set can be configured with a single MongoDB instance.
Auditize creates a main database named auditize
in charge of storing the configuration data. For each new log repository, a dedicated database will be created with a name prefixed by auditize_logs_
.
Docker Compose¶
The Docker Compose environment described here provides a complete Auditize setup including MongoDB.
First, create an auditize-docker
directory where you will store the various files related to your Auditize's Docker setup, and go to this directory:
Then, create a Dockerfile
file with the following content:
Warning
This is a minimal Dockerfile that installs the auditize
package and exposes the port 80. In a real-world / production setup, you would typically implement security and optimization measures such as:
- running the application as a non-root user,
- using a non-privileged port,
- making the Docker image as small as possible by using an optimized base image,
- pin the version of the
auditize
package to a specific version, - etc.
This image will be used to run both the web application and the scheduler Docker Compose services.
Next, create a docker-compose.yml
file in the same directory with the following content:
services:
mongo:
image: mongo
hostname: mongo # we need a static hostname for MongoDB replication
command: ["--replSet", "rs0"]
restart: always
volumes:
- mongo-data:/data/db
web:
image: auditize
build: .
pull_policy: never
depends_on:
- mongo
command: ["serve", "--host", "0.0.0.0", "--port", "80"]
ports:
- "8000:80"
env_file: ".env"
environment:
- AUDITIZE_MONGODB_URI=mongodb://mongo:27017/
scheduler:
image: auditize
build: .
pull_policy: never
depends_on:
- mongo
command: ["schedule"]
env_file: ".env"
environment:
- AUDITIZE_MONGODB_URI=mongodb://mongo:27017/
# we set PYTHONUNBUFFERED, otherwise the print() from "schedule" are not shown
- PYTHONUNBUFFERED=1
volumes:
mongo-data:
This docker-compose.yml
uses a .env
file for the Auditize base-configuration, so let's create a .env
file in the same directory with at least the following configuration elements:
AUDITIZE_PUBLIC_URL
is the public URL of your Auditize instance from which the web application will be accessed by your users or API clients (e.g.https://auditize.example.com
). It is used to generate URLs in the emails sent by Auditize.AUDITIZE_JWT_SIGNING_KEY
is the key used to sign the JWT tokens generated by Auditize (e.g. user sessions).
Please refer to the configuration documentation for more details.
Finally, start the Docker containers:
You need then to initialize the MongoDB replica set by running the following command:
Before you can use Auditize, you need to create a superadmin user. You can do this by running the following command:
docker exec -it auditize-docker-web-1 auditize bootstrap-superadmin YOUR_EMAIL YOUR_FIRST_NAME YOUR_LAST_NAME
Where:
auditize-docker-web-1
is the name of the web container to run the command fromYOUR_EMAIL
,YOUR_FIRST_NAME
, andYOUR_LAST_NAME
must be replaced by your actual user information
The command will prompt you for a password and then create the superadmin user.
You can now access Auditize at http://localhost:8000
and log in with the superadmin user you just created.
Using Gunicorn¶
The previous setup uses auditize serve
to run the web application. What this command does under the hood is to run the Uvicorn ASGI server with one worker. You may want to use Gunicorn with multiple workers for better performance as recommended in the Uvicorn documentation.
In this case, you can follow the same steps as above but make the following change in Dockerfile
:
And this change in the docker-compose.yml
file:
# command: ["serve", "--host", "0.0.0.0", "--port", "80"]
entrypoint:
[
"gunicorn",
"auditize:asgi()",
"-k",
"uvicorn.workers.UvicornWorker",
"-w",
"4",
"-b",
"0.0.0.0:80",
]
In this example, Gunicorn is configured to run 4 workers with the Uvicorn worker class. You can adjust the number of workers according to your needs / host resources.
Note
Since Auditize is an ASGI application, you can use any other ASGI server to run it instead of Uvicorn or Uvicorn+Gunicorn.
Ngnix, TLS, Kubernetes and beyond¶
The Docker Compose environment described above is a good starting point to run Auditize in a development/test environment. For a production deployment, you may consider:
- using a reverse proxy such as Nginx to serve the web application and handle TLS termination,
- deploying Auditize in a Kubernetes cluster with a proper ingress controller,
- build a custom Docker image with security and optimization measures,
- etc.
When deploying Auditize in a Kubernetes cluster, you have the flexibility to scale it by choosing between multiple pods running directly with Uvicorn and a single worker (through auditize serve
) or using Gunicorn with multiple workers. Using Uvicorn directly in each pod can be simpler and more lightweight, making it easier to manage and scale horizontally. The FastAPI documentation provides more information on how to deploy a FastAPI application in Kubernetes.
Info
You can also take a look at the auditize-docker repository which provides an exemple of Docker Compose environment with Nginx proxying and automatic SSL certificate generation using Let's Encrypt.
Standalone¶
Introduction¶
Auditize supports Python 3.12+. This version of Python is available on Ubuntu 24.04+ and RHEL 9.4+ (among others) as time of writing.
In this section, we will build a standalone Auditize environment using:
- Auditize installed in a Python virtual environment
- Gunicorn with ASGI workers
- Nginx as a reverse proxy
We assume that you have a working MongoDB instance available configured with a replica set and the corresponding MongoDB URI to connect to it.
Here, we take Ubuntu 24.04 as an example, but the steps should be similar for other Linux distributions (especially Debian-based ones and distros using systemd
).
Install and configure Auditize¶
First, install the virtualenv
package and create a Python virtual environment with Auditize and Gunicorn:
sudo apt install -y python3-virtualenv
sudo virtualenv /opt/auditize
sudo /opt/auditize/bin/pip install auditize gunicorn
Create a /opt/auditize/env
file containing your Auditize configuration. It should contain at least the required fields AUDITIZE_PUBLIC_URL
, AUDITIZE_JWT_SIGNING_KEY
, and AUDITIZE_MONGODB_URI
if your MongoDB server is not running locally:
Then, ensure appropriate permissions and ownership on this file:
Bootstrap the superadmin user:
sudo AUDITIZE_CONFIG=/opt/auditize/env /opt/auditize/bin/auditize bootstrap-superadmin YOUR_EMAIL YOUR_FIRST_NAME YOUR_LAST_NAME
The auditize bootstrap-superadmin
command will prompt you for a password and then create the superadmin user.
Info
The install path /opt/auditize
can be changed to any other path you prefer (when doing so, make sure to adjust the paths in the following steps accordingly). We use the www-data
user to run the services for simplicity, but you can choose to create a dedicated user for Auditize (you will have to ensure that the /run/gunicorn.sock
socket file is still accessible by Nginx that runs as www-data
).
Run Auditize's scheduler with systemd¶
First, create a /opt/auditize/log
directory to store the logs:
Then, create a /etc/systemd/system/auditize-scheduler.service
file with :
[Unit]
Description=Auditize Scheduler
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/auditize
EnvironmentFile=/opt/auditize/env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/auditize/bin/auditize schedule
Restart=always
RestartSec=3
StandardOutput=append:/opt/auditize/log/scheduler.log
StandardError=append:/opt/auditize/log/scheduler-error.log
[Install]
WantedBy=multi-user.target
And activate the service:
Run Gunicorn with systemd¶
We are going to use systemd
to create a UNIX socket for Gunicorn. Nginx will forward requests to this socket and systemd
will start the Gunicorn service when the first request is received.
Create a /etc/systemd/system/auditize-gunicorn.socket
file with:
[Unit]
Description=Unix socket for Auditize Gunicorn
[Socket]
ListenStream=/run/gunicorn.sock
SocketUser=www-data
SocketGroup=www-data
SocketMode=0660
[Install]
WantedBy=sockets.target
Create a /etc/systemd/system/auditize-gunicorn.service
:
[Unit]
Description=Run Auditize using Gunicorn
Requires=auditize-gunicorn.socket
After=network.target
[Service]
Type=notify
NotifyAccess=main
User=www-data
Group=www-data
WorkingDirectory=/opt/auditize
EnvironmentFile=/opt/auditize/env
ExecStart=/opt/auditize/bin/gunicorn 'auditize:asgi()' \
--error-logfile /opt/auditize/log/gunicorn.log \
-k uvicorn.workers.UvicornWorker -w 4
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
The -w 4
option tells Gunicorn to run 4 workers. You can adjust this number according to your needs / host resources.
Enable and start the auditize-gunicorn.socket
(systemd
will start the auditize-gunicorn.service
when needed) :
Setup Nginx¶
Install Nginx:
Add this Nginx configuration file at /etc/nginx/sites-available/auditize
:
server {
listen 80;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://gunicorn;
}
}
upstream gunicorn {
server unix:/run/gunicorn.sock;
}
Remove the default Nginx configuration if any:
Enable the Auditize configuration for Nginx:
Restart Nginx:
You can now access Auditize at http://YOUR_SERVER_HOSTNAME
and log in with the superadmin user you created earlier.
TLS¶
It is of course highly recommended to use TLS for your Auditize instance. Here is an example of an Nginx configuration with TLS, it has been generated using the Mozilla SSL Configuration Generator and it assumes that you have a valid certificate, private key, and DH parameter files in /opt/auditize/ssl/
:
# generated 2024-10-08, Mozilla Guideline v5.7, nginx 1.17.7, OpenSSL 1.1.1k, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1k&guideline=5.7
# adapted for Auditize
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /opt/auditize/ssl/cert.pem;
ssl_certificate_key /opt/auditize/ssl/key.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /opt/auditize/ssl/dhparam;
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# replace with the IP address of your resolver
resolver 127.0.0.1;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://gunicorn;
}
}
upstream gunicorn {
server unix:/run/gunicorn.sock;
}