Skip to content

Django, uWSGI, Nginx on Freebsd

Srijan Choudhary
2 min read

Here are the steps I took for configuring Django on Freebsd using uWSGI and Nginx.

The data flow is like this:

Web Request ---> Nginx ---> uWSGI ---> Django

I was undecided for a while on whether to choose uWSGI or gunicorn. There are some blog posts discussing the pros and cons of each. I chose uWSGI in the end.

Also, to start uWSGI in freebsd, I found two methods: using supervisord, or using a custom freebsd init script which could use uWSGI ini files. Currently using supervisord.

Install Packages Required

$ sudo pkg install python py27-virtualenv nginx uwsgi py27-supervisor

Also install any database package(s) required.

Setup your Django project

Choose a folder for setting up your Django project sources. /usr/local/www/myapp is suggested. Clone the sources to this folder, then setup the python virtual environment.

$ virtualenv venv
$ source venv/bin/activate
$ pip install -r requirements.txt

If required, also setup the database and run the migrations.

Setup uWSGI using supervisord

Setup the supervisord file at /usr/local/etc/supervisord.conf.

Sample supervisord.conf:

[unix_http_server]
file=/var/run/supervisor/supervisor.sock   

[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB       ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10          ; (num of main logfile rotation backups;default 10)
loglevel=info               ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisor/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false              ; (start in foreground if true;default false)
minfds=1024                 ; (min. avail startup file descriptors;default 1024)
minprocs=200                ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock
history_file=~/.sc_history  ; use readline history if available

[program:uwsgi_myapp]
directory=/usr/local/www/myapp/
command=/usr/local/bin/uwsgi -s /var/run/%(program_name)s%(process_num)d.sock
        --chmod-socket=666 --need-app --disable-logging --home=venv
        --wsgi-file wsgi.py --processes 1 --threads 10
stdout_logfile="syslog"
stderr_logfile="syslog"
startsecs=10
stopsignal=QUIT
stopasgroup=true
killasgroup=true
process_name=%(program_name)s%(process_num)d
numprocs=5
supervisord.conf

And start it:

$ echo supervisord_enable="YES" >> /etc/rc.conf
$ sudo service supervisord start
$ sudo supervisorctl tail -f uwsgi_myapp:uwsgi_myapp0

Setup Nginx

Use the following line in nginx.conf's http section to include all config files from conf.d folder.

include /usr/local/etc/nginx/conf.d/*.conf;

Create a myapp.conf in conf.d.

Sample myapp.conf:

upstream myapp {
    least_conn;
    server unix:///var/run/uwsgi_myapp0.sock;
    server unix:///var/run/uwsgi_myapp1.sock;
    server unix:///var/run/uwsgi_myapp2.sock;
    server unix:///var/run/uwsgi_myapp3.sock;
    server unix:///var/run/uwsgi_myapp4.sock;
}

server {
    listen       80;
    server_name  myapp.example.com;
 
    location /static {
        alias /usr/local/www/myapp/static;
    }

    location / {
        uwsgi_pass  myapp;
        include uwsgi_params;
    }
}
myapp.conf

And start Nginx:

$ echo nginx_enable="YES" >> /etc/rc.conf
$ sudo service nginx start
$ sudo tail -f /var/log/nginx-error.log

Accessing http://myapp.example.com/ should work correctly after this. If not, see the supervisord and Nginx logs opened and correct the errors.

devops

Related Posts

Download a file securely from GCS on an untrusted system

Download files from google cloud storage using temporary credentials or time-limited access URLs

Advanced PostgreSQL monitoring using Telegraf, InfluxDB, Grafana

Introduction This post will go through my experience with setting up some advanced monitoring for PostgreSQL database using Telegraf, InfluxDB, and Grafana (also known as the TIG stack), the problems I faced, and what I ended up doing at the end. What do I mean by advanced? I liked this

Advanced PostgreSQL monitoring using Telegraf, InfluxDB, Grafana

Running docker jobs inside Jenkins running on docker

Jenkins [https://www.jenkins.io/] is a free and open source automation server, which is used to automate software building, testing, deployment, etc. I wanted to have a quick and easy way to run Jenkins inside docker, but also use docker containers to run jobs on the dockerized Jenkins. Using

Running docker jobs inside Jenkins running on docker