Skip to content

Installation on a production environment

Augustin FL edited this page Dec 29, 2024 · 42 revisions

Before you start: The production environment is great for running FIR with performance and stability in mind. If you want to test FIR just to get acquainted with it or if you want a quick install, we recommend you to run FIR using docker.


This will explain how to install FIR on a production environment. As an example, we will be using nginx as a reverse-proxy and MySQL as DBMS. Feel free to adapt it to you own needs (PostgreSQL, Apache, etc.)

This procedure was tested on an Ubuntu system.

Install Prerequisites

Install the prerequisites for running FIR with MySQL and nginx:

$ sudo apt update
$ sudo apt install mysql-server libmysqlclient-dev gettext python3-dev python3-pip python3-lxml git libxml2-dev libxslt1-dev libz-dev nginx pkg-config python-is-python3 python3-virtualenv redis libsasl2-dev libldap2-dev

Configure MySQL database

Create users:

$ sudo mysql
> CREATE DATABASE fir;
> CREATE USER 'fir'@'localhost' IDENTIFIED BY 'THIS_IS_A_PASSWORD_CHANGE_ME_PLZ';
> GRANT USAGE ON *.* TO 'fir'@'localhost';
> GRANT ALL PRIVILEGES ON `fir`.* TO 'fir'@'localhost';

Install FIR

Create a folder /opt/fir owned by www-data

$ sudo install -d -o www-data -g www-data -m 755 /opt/fir
$ sudo -u www-data bash
$ cd /opt/fir

then, create a virtual environment and clone the git repo:

$ virtualenv env-FIR
$ source env-FIR/bin/activate
$ git clone https://github.com/certsocietegenerale/FIR.git

cd into the FIR directory and install Python dependencies:

$ cd FIR
$ find . -name requirements.txt -exec pip install -r {} \;

Create a production configuration file by copying the fir/config/production.py.sample to fir/config/production.py

$ cp fir/config/production.py.sample fir/config/production.py

Change the settings in the production.py file according to your setup. This includes the ALLOWED_HOSTS directive - change it to whatever vhost you're planning to use in your deployment. Also, remember to change the timezone in base.py

If you want to enable the plugins, copy the fir/config/installed_apps.txt.sample file to fir/config/installed_apps.txt:

$ cp fir/config/installed_apps.txt.sample fir/config/installed_apps.txt

Create the tables in the database:

$ ./manage.py migrate --settings fir.config.production

Create a superuser:

$ ./manage.py createsuperuser --settings fir.config.production

You will be asked for super-user account credentials. Enter them to continue.

Import initial data (you can change these later from the Django backend):

$ ./manage.py loaddata incidents/fixtures/01_seed_data.json --settings fir.config.production

Collect static files (these will be cached for better performance)

$ ./manage.py collectstatic --settings fir.config.production 

If you want to use internationalization:

$ python manage.py compilemessages

This will generate a bunch of .mo files that Django will use for translating the UI. This command should also be run in the directories of plugins that support internationalization.

uWSGI

We need to install uWSGI in order to serve our application:

$ pip install uwsgi

then exit env-FIR virtualenv and www-data shell: you will need root permissions for the next steps

Create a directory for the socket:

$ sudo install -d -o www-data -g www-data -m 700 /run/fir

Next, create a file in /etc/systemd/system/fir.service with the following content:

[Unit]
Description=Fast Incident Response
After=syslog.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/fir/FIR
ExecStart=/opt/fir/env-FIR/bin/uwsgi --socket /run/fir/fir.sock --chdir /opt/fir/FIR --module fir.wsgi
Restart=always
KillSignal=SIGQUIT
Type=Debug
StandardError=syslog
NotifyAccess=All

[Install]
WantedBy=multi-user.target

Then start FIR with the following commands:

$ sudo systemctl daemon-reload
$ sudo systemctl start fir.service # start FIR
$ sudo systemctl enable fir.service # configure FIR to start automatically on boot

Please note that it will only work if your configuration file is fir/config/production.py. Otherwise, you will need to update the file fir/wsgi.py with the correct settings module.

Nginx reverse proxy

Download uwsgi params:

$ sudo wget https://raw.githubusercontent.com/nginx/nginx/master/conf/uwsgi_params -P /etc/nginx

Remove the default configuration file:

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

Create a /etc/nginx/sites-available/fir file with the following contents:

upstream fir {
        server unix:///run/fir/fir.sock;
}

server {
        server_name FIR.DOMAIN.COM;

        location / {
                uwsgi_pass fir;
                include /etc/nginx/uwsgi_params;
        }

        location /static/ {
                alias /opt/fir/FIR/static/;
        }
}

Make sure you replace FIR.DOMAIN.COM with the host you will be using to host your FIR install. This should match what you specified in the ALLOWED_HOSTS directive in production.py. (This solves error 400 problems as described in #46)

Enable the configuration:

$ sudo ln -s /etc/nginx/sites-available/fir /etc/nginx/sites-enabled/fir
$ sudo systemctl reload nginx 

Running Celery

Some plugins, such as fir_notification or fir_abuse, are using celery workers to process asynchronous tasks. If you enabled these plugins, you may want to create a systemd service for the worker.

create a file in /etc/systemd/system/fir_worker.service with the following content:

[Unit]
Description=Fast Incident Response worker
After=syslog.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/fir/FIR
ExecStart=/opt/fir/env-FIR/bin/celery -A fir_celery.celeryconf.celery_app worker -l info
Environment="DJANGO_SETTINGS_MODULE=fir.config.production"
Restart=always
KillSignal=SIGQUIT
Type=Debug
StandardError=syslog
NotifyAccess=All

[Install]
WantedBy=multi-user.target

Then, enable the worker:

$ sudo systemctl daemon-reload
$ sudo systemctl start fir_worker.service # start FIR celery worker
$ sudo systemctl enable fir_worker.service # configure celery worker to start automatically on boot

Keeping your FIR installation up-to-date

Pull the repo:

$ sudo -u www-data bash
$ cd /opt/fir/FIR
$ git pull

Apply migrations, if any:

$ source ../env-FIR/bin/activate
$ ./manage.py migrate --settings fir.config.production

Update static files, if necessary:

$ ./manage.py collectstatic --settings fir.config.production

Restart the server:

$ exit
$ sudo systemctl restart fir