Skip to content

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:

mkdir auditize-docker
cd auditize-docker

Then, create a Dockerfile file with the following content:

FROM python:3.12

RUN pip install auditize

EXPOSE 80

ENTRYPOINT ["auditize"]

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=http://localhost:8000
AUDITIZE_JWT_SIGNING_KEY=YOUR_AUDITIZE_JWT_SIGNING_KEY
  • 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:

docker compose up -d

You need then to initialize the MongoDB replica set by running the following command:

docker exec -it auditize-docker-mongo-1 mongosh --eval "rs.initiate()"

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 from
  • YOUR_EMAIL, YOUR_FIRST_NAME, and YOUR_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:

# RUN pip install auditize
RUN pip install auditize gunicorn

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:

AUDITIZE_PUBLIC_URL=...
AUDITIZE_JWT_SIGNING_KEY=...
AUDITIZE_MONGODB_URI=...

Then, ensure appropriate permissions and ownership on this file:

sudo chown www-data:www-data /opt/auditize/env
sudo chmod 660 /opt/auditize/env

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:

sudo mkdir /opt/auditize/log
sudo chown www-data:www-data /opt/auditize/log

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:

sudo systemctl enable --now auditize-scheduler

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) :

sudo systemctl enable --now auditize-gunicorn.socket

Setup Nginx

Install Nginx:

sudo apt 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:

sudo rm /etc/nginx/sites-enabled/default

Enable the Auditize configuration for Nginx:

sudo ln -s /etc/nginx/sites-available/auditize /etc/nginx/sites-enabled/auditize

Restart Nginx:

sudo systemctl 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;
}

Warning

Make sure that the files under /opt/auditize/ssl/ have proper permissions:

sudo chmod o-rwx /opt/auditize/ssl/*