home | prev | next

NGINX deployment

Initial Setup

This document describes how to deploy the CDCS using uWSGi and Nginx. Currently you can deploy the Material Data Configuration System (MDCS) and the Materials Registry and Repository (MRR). Both are deployed using uWSGI, which is a fast, self-healing and developer/sysadmin-friendly application container server coded in pure C. It is served thru Nginx proxies. This document will how to serve via NGINX.

  1. Upload project to desired directory (with http access), in this example we called it mdcs. If you are deploying this, this directory must be in the Server Root.

    $ git clone https://github.com/usnistgov/mdcs mdcs --branch master
    cd mdcs
  2. Install required packages for the project. This includes Python modules or required software such as databases.

  3. Run installation scripts for project provided with the project download.

  4. Install NGINX to serve MDCS and MMR over the web.

Virtual Environment

It is recommended you use a virtual environment that can be built separate from the system binaries, to make sure the apache user can access all needed binaries. Again, the Environment MUST BE in the Server Root path, in this example we have created the environment in /var/www/html/env,with a Server Root of /var/www/html and are using Anaconda, but any environment creator will work.

1. Install Anaconda
$ wget https://repo.anaconda.com/archive/Anaconda2-5.1.0-Linux-x86_64.sh
$ bash Anaconda2-5.2.0-Linux-x86_64.sh
 
2. Update Conda
$ conda update -n base conda
3. Create Environment with python 2.7
$ conda create -y -p /var/www/html/env python=2.7
4. Enable environment
source activate /var/www/html/env

Databases and Django

1. Install mongodb
$ yum install mongodb-server
$ yum install mongodb
2. Start Mongo
3. Create Admin User
$ mongo
use admin
db.createUser(
{
    user: "admin",
    pwd: "admin",
    roles: [ { role: "userAdminAnyDatabase", db: "admin"},"backup","restore"]
}
)
exit
4. Create MDCS user
5. Install django-mongoengine from GitHub

6. Celery, Redit, and Git

Celery, Redis and Git may already be installed on your system, if they are, you can use what is installed, otherwise install:

1. Install Git
$ yum install git
2. Install Celery using pip:
$ pip install Celery
3. Run Celery
$ celery worker -E --app=mdcs -l info -B --purge --logfile=/home/www/html/mdcs/logs/celery.log --workdir=/home/www/html/mdcs --detach
Note: mdcs is the project name
4. Install Redis:
$ yum install redis
5. Run Redis
$ redis-server --daemonize yes

7. uWSGI

The following is the config file for uWSGi distributed with CDCS (mdcs/mdcs.ini). Again, it is installed in /var/www/html/mdcs/ which MUST be in the Server Root path.

In this example: ServerRoot /var/www/html and it runs as user/group www-data/www-data

mdcs.ini:

[uwsgi]
protocol=http
buffer-size=32768
master = true
processes = 5
socket=XXX.XXX.XXX.XXX(this is your IP address):8000 (this is the port)
chmod-socket = 664
vacuum = true
die-on-term = true
pidfile=/var/run/mdcs.pid
chdir=/var/www/html/mdcs
pythonpath=/var/www/html/env/lib/python2.7/site-packages
wsgi-file=/var/www/html/mdcs/mdcs/mdcs.wsgi
uid=www-data
gid=www-data
check-static=/var/www/html/mdcs
thunder-lock=true
enable-threads=true
virtualenv=/var/www/html/env
static-map=/static=/var/www/html/mdcs/static.prod
static-check=/var/www/html/mdcs/static.prod
static-check=/var/www/html/mdcs
daemonize=/var/www/html/mdcs/logs/uwsgi.log
Install uwsgi
$ pip install uwsgi
Start MDCS
$ uwsgi --ini /var/www/html/mdcs/mdcs/mdcs.ini

Settings.py

Make the following edits to settings.py.

1. Set secret key
SECRET_KEY = <secret_key>
2. Set host name
ALLOWED_HOSTS = ['HOSTNAME.SITE.COM']
3. Activate HTTPS
os.environ['HTTPS'] = 'on'
4. Secure cookies
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_AGE = None
SESSION_COOKIE_SECURE = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 604800
5. Set x-frame options Note this may be done in webserver config
X_FRAME_OPTIONS = 'SAMEORIGIN'
6. Set User Database or use default
** PostGRES   (Can be MYSQL also)**
DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'USER':"mgiUser",
            'PASSWORD': "pass4mgiUser123",
            'NAME': 'mgi',
        }
    }
 
Or Use the Default Sqlite
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

Host

  1. Install Nginx on host.

  2. Create or upload certificate, key and certificate chain for HTTPS configuration.

NOTE: Chmod 600 [account] the certificate, key and certificate chain.

Nginx

$ yum install nginx
$ yum install bzip2
1. nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
 
events {
        worker_connections 768;
}
 
http {
    add_header Strict-Transport-Security "max-age=15768000" always;
    add_header X-Content-Type-Options "nosniff" always;
    #add_header X-Frame-Options "SAMEORIGIN" always;  **Uncomment if not done in settings.py**
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Whome "l-cbz02";
 
    server_names_hash_bucket_size 64;
    uwsgi_cache_path  /var/cache/nginx levels=1:2 keys_zone=my_app:10m inactive=5m;
 
    client_body_buffer_size  1K;
    client_max_body_size 256M;
    client_header_buffer_size 2k;
    large_client_header_buffers  4 4k;
 
    map_hash_bucket_size 2048;
    map $sent_http_content_type $expires {
        default           off;
        application/json  42d;
    }
    expires $expires;
 
 
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
 
        ##
        # Basic Settings
        ##
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        ##
        # SSL Settings
        ##
        ssl_protocols TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;
        ##
        # Logging Settings
        ##
        log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
        ##
        # Gzip Settings
        ##
        gzip on;
        gzip_disable "msie6";
        ##
        # Virtual Host Configs
        ##
        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/default.d/mdcs_nginx.conf;
}
2. mdcs_nginx.conf

Note: For Nginx if there is an intermediate certificate, it must be after the host certificate in the same file, in this case we used mdcs.chained.crt which contained both certs.

root /var/www/html;
index index.html index.htm;
server {
    charset utf-8;
    listen              443 ssl;
    server_name         mdcs.nist.gov;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_certificate     /home/www/html/mdcs/certs/mdcs.chained.crt;
    ssl_certificate_key /home/www/html/mdcs/certs/mdcs.key;
    ssl_session_cache shared:mySSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;
 
    # OCSP Stapling
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
    ## Improves TTFB by using a smaller SSL buffer than the nginx default
    ssl_buffer_size 8k;
 
    access_log /home/www/html/mdcs/logs/access_mdcs.log main;
    error_log /home/www/html/mdcs/logs/error_mdcs.log warn;
 
   location / {
        limit_except GET POST { deny  all; }
        include /etc/nginx/uwsgi_params;
        proxy_pass http://mdcs.nist.gov:8000;
   }
}
 
server {
    listen              80 default_server;
    server_name         mdcs.nist.gov;
    return 301 https://$host$request_uri;
}
 
3. open firewall ports 80 & 443
  $ firewall-cmd --add-port=80/tcp
  $ firewall-cmd --add-port=443/tcp
4. Run Nginx
  $ service nginx start