Well, you have developed your first version of your super-mega-giga web app and you want to deploy it. Your application consists of two parts: API (backend) and your java-script code (frontend). In this article, I am going to explain how to deploy your API written in Django and your frontend written in AngularJS with a little bit of help of NodeJS and npm.

API deployment - Docker configuration

It is good practice to use docker to isolate your environment for every app you are planning to use. We will set up 2 docker containers: one for Django app and one for database we use in our backend.

When you have situation like this: to have more containers bound in some way, it is always recommended to use docker-compose to easily manage your containers.

First, we will make Dockerfile for our container serving our Django API

Here is an example of Dockerfile to use:

FROM python:3.4
ENV PYTHONUNBUFFERED 1
# ssh-keygen is needed because some packages from requirements.txt are not available on pypy and are git cloned instead
RUN ssh-keygen -q -t rsa -N '' -f id_rsa
RUN apt-get update && apt-get install netcat -y
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
ADD requirements-dev.txt /code/
RUN pip install -r requirements.txt && pip install -r requirements-dev.txt && pip install uwsgi
ADD . /code/
RUN groupadd -r youruser && useradd -r -g youruser youruser
USER youruser

This image will download and install needed packages for deployment and install all libraries listed in requirements.txt as well as in requirements-dev.txt. Just list your dependencies by their name in Python package index.

Now, you have to configure your docker-compose.yml:

db:
    image: postgres
web:
    build: .
    command: sh bin/production.sh 9005
    volumes:
        - .:/code
    ports:
        - "9005:9005"
    links:
        - db
    environment:
        - DJANGO_SETTINGS_MODULE=project.settings_docker

as you can see, we are listening to port 9005 and we run our production script. bin/production.sh script just runs uwsgi bound to specified port from the first argument to the script

#!/bin/sh

python manage.py migrate --noinput
python manage.py collectstatic
uwsgi --chdir=/code -s 0.0.0.0:$1 --module=project.wsgi:application

And it’s done! Just run your containers now:

docker-compose up 

Deploying API to NGinx

In your Nginx configuration, just add this location:

location /api/ {
	uwsgi_pass 127.0.0.1:9005;
	include uwsgi_params;
	uwsgi_modifier1 30;
}

Make sure that all your API urls defined in urls.py begin with “/api/”

For admin interface, you can do the same but for different location, “admin” instead of “api”:

location /admin/ {
	uwsgi_pass 127.0.0.1:9005;
	include uwsgi_params;
	uwsgi_modifier1 30;
}

Also, you will have to serve your static files:

location /static/ {
	alias /path/to/your/app/code/static/;
}

Deploying frontend

Frontend deployment with NPM is easy, first you have to set up your package.json properly:

....
"scripts": {
  "build:js": "cp node_modules/jquery/dist/* app/dist/ && browserify app/scripts/app.js > app/dist/liberator.js",
  "build:bootstrap": "cp -rv node_modules/bootstrap/dist/* app/dist/",
  "build": "mkdir app/dist -p && npm run build:js && npm run build:bootstrap",
  "clean": "rm -rfv dist/",
  "lint": "jshint **.js",
  "prebuild": "npm run lint",
  "watch": "watch 'npm run build' ./app/ --filter=watch_filter",
  "serve": "http-server -p 9000 -a 0.0.0.0 ./app/",
  "livereload": "live-reload ./app/dist/ --port 9001"
},
....

And just run

npm run build

and your distribution will be held in app/ directory (where dist directory is located) so just configure NGinx to alias to that location:

location / {
	alias /path/to/frontend/app/;
}

And that’s it! Restart NGinx and enjoy testing your app in production. :)

If you have some suggestions or if you want to remind me on some issues, just fill comment form below.