Dockerize your React, Django Rest Api Application and serve using nginx

Parth Koshta
4 min readMar 5, 2021

--

In this article, we will learn how to use docker to containerize your Fullstack React and Django Rest Api application and serve it using nginx. You should have some familiarity with React and Django, Django Rest Framework and some knowledge regarding the use-case of Docker and Nginx.

In this tutorial, we will,

  • Create a simple React App.
  • Create a Django app with Django Rest Framework.
  • Connect our Django app to MySQL DB.
  • Integrate our Frontend, Backend and DB with docker.
  • Finally, use nginx to serve our app.

Let’s start with creating our frontend react.js application

  • Create a react app(e.g. ‘frontend’ in our case), in your root project folder:
$ npx create-react-app frontend

If you want to run your app:

$ cd frontend
$ yarn start
your app will run on http://localhost:3000/
You will be welcomed with this screen.

Now, let’s create our backend application

We will use pipenv to manage our virtual environment:

  • Install pipenv on your mac using
$ brew install pipenv
  • Make sure you’ve got python and pip
$ python --version
$ pip --version
  • Create a directory backend
$ cd backend
  • Activate your virtual environment using
$ pipenv shell
  • If you need to exit you virtual environment, you can use
$ exit
  • Let’s install some packages that will help us get started, inside your virtual environment
$ pipenv install django
$ pipenv install djangorestframework
$ pipenv install gunicorn
  • Create a django project (e.g. ‘server’ in our case), inside your backend folder:
$ django-admin startproject server .$ python manage.py migrate  // to run migration$ python manage.py startapp core // to create a django app e.g. 'core'
  • Let’s confirm if everything works as expected
$ python manage.py runserveryour server will run on http://localhost:8000/
You will be welcomed with this screen.
  • Add django rest framework to InstalledApps in server/settings.py
INSTALLED_APPS = [
...
'rest_framework',
]
  • In core/views.py, add
from rest_framework.views import APIViewfrom rest_framework.response import Responseclass index(APIView):    def get(self, request, format=None):    return Response('Hello World!')
  • Create a new file core/urls.py and add
from django.urls import include, pathfrom . import viewsurlpatterns = [path("api/hello", views.index.as_view(), name="index"),]
  • In server/urls.py add
from django.urls import include, pathurlpatterns = [
...
path("", include("core.urls")),]
You will see django rest framework response.

Now we will connect our app to MySQL database

  • Install django mysqlclient
pipenv install mysqlclient
  • In server/settings.py add
DATABASES = {"default": {"ENGINE": "django.db.backends.mysql","NAME": <your-db-name>,"USER": <user-name>,"PASSWORD": <password>,"HOST": db,"PORT": 3306,}}

Now we can go ahead with our docker setup

  • Create a folder webserver in project root folder
  • Create a file for our client app and nginx, webserver/Dockerfile
webserver/Dockerfile
  • FROM — a dockerfile must begin with FROM, it tells docker which image we want to use for our container.
  • WORKDIR — sets our work directory inside docker container.
  • COPY — copies file from host to container workdir.
  • RUN — runs the command inside workdir.

Here, we copy our frontend files inside our docker container’s work directory.
Also, we copy webserver/default.conf inside nginx container conf.d directory and our frontend build inside nginx container’s html directory.

  • Create nginx configuration file, webserver/default.conf
webserver/default.conf

We copied our frontend and backend static files inside nginx container and here, we are using nginx to server them.

  • Create Dockerfile for server, server/Dockerfile
server/Dockerfile

Here, we copied backend folder from host to container, installed all the dependencies and specified entrypoint.sh as our entry file, which will be the entrypoint to our container.

  • Add STATIC_URL and STATIC_ROOT in server/settings.py
STATIC_URL = "/staticfiles/"STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

Here, we tell django to collect all our server static files inside staticfiles directory.

Add entrypoint file, server/entrypoint.sh

server/entrypoint.sh

Here, our entrypoint.sh file collects all the static assets as defined in the settings file inside staticfiles folder.

Then, run our server using gunicorn.

  • Now we will create docker-compose.yml in project root folder
docker-compose.yml
  • docker-compose.yml file is used to configure our services.
  • You can learn about various configuration options here.
  • Point to note here for our tutorial’s sake is that we are creating a volume named staticfiles which is being shared between backend and nginx service, this is how we will be able to access staticfiles for our backend inside our nginx container.
  • Finally, build and run our docker container
$ docker-compose up -d --build
  • -d — flag is used to run our container in background.
Our frontend will run http://0.0.0.0/
REST api — http://0.0.0.0/api/hello/
Django admin — http://0.0.0.0/admin/login/?next=/admin/

You can find the github repo for this tutorial here.

I hope this tutorial helped you guys in some way.
This was my first medium article and there are certainly more to come.

Any kind of feedback is welcome.

Find me on LinkedIn

--

--

Parth Koshta

Senior Software Engineer @ Opendoor - I specialize in building websites and cross platform mobile apps and everything around it.