Deploying ColdFront in Production
This document outlines how to run ColdFront in production. ColdFront is written in python3 and uses the Django web framework. Here we showcase deploying ColdFront using Gunicorn and nginx but any method for deploying Django in production could be used. For a more comprehensive list of methods see here.
Preliminaries
It's recommended to create a non-root user for running ColdFront. The Gunicorn worker processes will run under this user account. Also, create a directory for installing ColdFront and related files.
# useradd --system -m coldfront
# mkdir /srv/coldfront
# chown coldfront.coldfront /srv/coldfront
# mkdir /etc/coldfront
Note
This guide uses nginx. So be sure you have nginx installed:
# yum/apt install nginx
Install ColdFront in a virtual environment
# cd /srv/coldfront
# python3 -mvenv venv
# source venv/bin/activate
# pip install --upgrade pip
# pip install coldfront
Configure ColdFront
Create a config file for ColdFront. For a complete list of settings see here.
Note
The config file needs to be readable by nginx user. Ensure you have the appropriate permissions set. For example:
$ chmod 640 /etc/coldfront/coldfront.env
$ chgrp nginx /etc/coldfront/coldfront.env
Create the file /etc/coldfront/coldfront.env
and set at least the following
variables:
# Database connection
DB_URL=mysql://user:password@127.0.0.1:3306/database
# Path to store static assets
STATIC_ROOT=/srv/coldfront/static
# Name of your center
CENTER_NAME='University HPC'
# Cryptographic secret key
SECRET_KEY=
Danger
Never set DEBUG
to True in production. You also MUST set SECRET_KEY
in
production or else each time ColdFront is started a new one will be
generated. You can create a good secret key using the following command:
$ python3 -c "import secrets; print(secrets.token_urlsafe())"
Choosing a database backend: ColdFront supports MariaDB/MySQL, PostgreSQL, or SQLite. If you don't configure a database, it will use SQLite by default and will place the database in the ColdFront working directory. You may not want this for a production installation.
Install your preferred database and set the connection details using
the DB_URL
variable as shown above.
Note: Install python database drivers
Be sure to install the database drivers associated with your db. For example:
$ source /srv/coldfront/venv/bin/activate
$ pip install mysqlclient
$ pip install psycopg2
Initializing the ColdFront database
$ source /srv/coldfront/venv/bin/activate
$ coldfront initial_setup
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
....
....
This should only be done once
You only need to initialize the ColdFront database once after you first install.
Create the super user account
Run the command below to create a new super user account with a secure password:
$ source /srv/coldfront/venv/bin/activate
$ coldfront createsuperuser
Tip
This command should prompt you to select a username, password, and email address for your super user account. Set a secure password for use in production.
Deploy static files
This step allows serving all of ColdFront static assets (CSS/JavaScript/Images)
using nginx. For more information see here.
This command will deploy all static assets to the STATIC_ROOT
path in the configuration step above.
$ source /srv/coldfront/venv/bin/activate
$ coldfront collectstatic
Install Gunicorn
$ source /srv/coldfront/venv/bin/activate
$ pip install gunicorn
Create systemd unit file for ColdFront Gunicorn workers
Create file /etc/systemd/system/gunicorn.service
:
[Unit]
Description=Gunicorn instance to serve Coldfront
After=syslog.target network.target mariadb.service
[Service]
User=coldfront
Group=nginx
WorkingDirectory=/srv/coldfront
Environment="PATH=/srv/coldfront/venv/bin"
ExecStart=/srv/coldfront/venv/bin/gunicorn --workers 3 --bind unix:coldfront.sock -m 007 coldfront.config.wsgi
[Install]
WantedBy=multi-user.target
Note
Adjust the number of workers for your site specific needs using the --workers
flag above.
Start/enable ColdFront Gunicorn workers
# systemctl start gunicorn.service
# systemctl enable gunicorn.service
# Check for any errors
# systemctl status gunicorn.service
Create systemd unit file for ColdFront qcluster scheduled tasks
ColdFront uses Django Q to run scheduled tasks such as sending allocation expiration warning emails. We need to create a unit file to run the qserver process or these tasks will never run.
Create file /etc/systemd/system/coldfrontq.service
:
[Unit]
Description=DjangoQ instance to run Coldfront scheduled tasks
After=syslog.target network.target mariadb.service gunicorn.service
[Service]
User=coldfront
Group=nginx
WorkingDirectory=/srv/coldfront
Environment="PATH=/srv/coldfront/venv/bin"
ExecStart=/srv/coldfront/venv/bin/coldfront qcluster
[Install]
WantedBy=multi-user.target
Start/enable ColdFront qcluster
# systemctl start coldfrontq.service
# systemctl enable coldfrontq.service
# Check for any errors
# systemctl status coldfrontq.service
Configure nginx
We now configure nginx to proxy requests to the ColdFront Gunicorn workers via unix domain socket.
Create file /etc/nginx/conf.d/coldfront.conf
:
server {
listen 443 ssl http2 default_server;
# Note set these to the path of your SSL certs
ssl_certificate /srv/coldfront/tls/coldfront.crt;
ssl_certificate_key /srv/coldfront/tls/coldfront.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location /static/ {
alias /srv/coldfront/static/;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/srv/coldfront/coldfront.sock;
}
}
Use SSL in Production
Be sure to configure nginx with ssl when running in production. Creating and setting up SSL certificates is outside the scope of this document.
Start/enable nginx
# systemctl restart nginx.service
# systemctl enable nginx.service