Let's Dockerize your Django & React JS App.
Tags: beginners, webdev, python, docker
Published: 2023-04-27 08:29:29

Ah, the infamous words of a developer: "**but it works on my machine!**" - a phrase that strikes fear into the hearts of anyone who's ever had to deploy their code. We've all been there - you spend hours trying to debug an issue, only to realize that it was caused by differences in your development environment and the production environment. This is where Docker comes in.

## Introduction

Docker is a platform that enables you to package your application and its dependencies into a single container, which can be run anywhere, regardless of the host operating system or hardware. With Docker, you can ensure that your code runs smoothly across all machines, without having to worry about environment discrepancies.

Here are a few benefits of using Docker for your Python and React.js app:

- Portability: Package your app and its dependencies into a single container to deploy and scale your app across different environments.

- Consistency: Define your app's environment in a Dockerfile to ensure that all developers and machines are using the same setup.

- Isolation: Provide a secure and isolated environment for your app to run in to improve security and prevent conflicts.

- Efficiency: Use resources more efficiently than traditional virtual machines to reduce infrastructure costs and easily manage your containers.

- Flexibility: Modular architecture to break down your app into smaller, more manageable components and easily update and deploy individual components without disrupting the rest of the app.

## Prerequisites

- Basic knowledge of Django and React.js frameworks
- [Docker](https://www.docker.com/products/docker-desktop/) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your system
- [Python](https://www.python.org/downloads/) and [Node.js](https://nodejs.org/en/download) installed on your system

## Docker Compose

[Docker Compose](https://docs.docker.com/compose/) is a tool for defining and running multi-container Docker applications. It allows you to define all the services that your application needs in a single file, called a `docker-compose.yml` file. With Docker Compose, you can start and stop all the containers that your application needs with a single command.

## Setting Up the Project

Let's get our ducks in a row, or in this case, our directories in order! Before we dive into dockerizing our Python and React app, let's take a quick tour of the project structure. This way, you'll be able to keep your code organized and tidy, just like your closet (or at least we hope so!).

```
django-react-docker/
│
├── api/
│   ├── manage.py
│   ├── project/
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── Dockerfile
│
├── frontend/
│   ├── node_modules/
│   ├── public/
│   │   ├── index.html
│   │   └── ...
│   ├── src/
│   │   ├── App.js
│   │   └── ...
│   ├── package.json
│   └── ...
│   └── Dockerfile
│
└── docker-compose.yml
```

## Now, let's start by **building our API**.

Inside the folder 'django-react-docker`, let's make another folder api. This is where the code for API will be located.

Inside the api folder, let's make a django project using the command `django-admin startproject project`.

Let's create our `views.py` file in project folder and fetch the current time and date.

Let's first import all `JsonResponse` and `datetime`.
`from django.http import JsonResponse`
`from datetime import datetime`

Now let's make a view to return the current time and date


![View for returning time and date](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gw8hylgbse4nyrhb2pb.png)

Now, let's update our `urls.py` file to direct the view to homepage.


![URL's.py](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhlhk9t88vc0qnjsjaw5.png)

Now, let's manage our settings in project's 'settings.py'

- Let's add our allowed hosts

`ALLOWED_HOSTS = ['0.0.0.0', 'http://localhost:8000/', '127.0.0.1']`

- We need to add `corsheaders` under installed apps.

`INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders'
]`

- Let's add our `http://localhost:3000` to allowed `CORS_ORIGIN_WHITELIST`

`CORS_ORIGIN_WHITELIST = [
     'http://localhost:3000'
]`

- Now let's add a middleware class to listen in on responses:

`MIDDLEWARE = [
    ...,
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...,
]`


## Building a Docker Container for Django 

Now to dockerize our django app, we need to make a `Dockerfile` inside the `api` folder.


![Docker Container for Django](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xg350iaej59c5y3mdxzy.png)

Let's break this down for a better understanding.

- FROM python:3.8-slim-buster: This specifies the base image to use for building the container. In this case, it's the official Python 3.8 slim version based on Debian 10 (Buster) image.

- ENV PYTHONUNBUFFERED=1: This sets an environment variable to prevent Python from buffering standard output and standard error streams, which can cause delays in log messages.

- WORKDIR /api: This sets the working directory inside the container to /api. This means that any subsequent commands will be executed in the context of this directory.

- RUN pip install django django-cors-headers: This installs the required Python packages, Django and Django-cors-headers, using pip.

- COPY . .: This copies the contents of the current directory (where the Dockerfile is located) to the working directory inside the container, /api.

- EXPOSE 8000: This exposes port 8000 of the container to the host machine.

## Building the frontend

Let's build the frontend to display the time and date recieved from api.

Let's run the boilerplate command to make a React app.

`npx create-react-app frontend`

Now, let's navigate to `App.js` file and fetch the data from api and set the data fetched data in `useState`.


![App.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bamfnajho1edy167qyjw.png)


## Building a Docker Container for React App

Now to dockerize our React app, we need to make a `Dockerfile` inside the `frontend` folder.


![React Docker File](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/frsnulkq8p3seeg2khhl.png)

## Creating a Docker Compose File

Now, let's make a docker compose file which will run both are images Django app image and React App image together.

Remember this file should be in root folder.


![Docker Compose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55avl3gx2ewcqe16v8d0.png)

Now, let's break down the docker compose file:

- services: This section defines the two services that will be created by Docker Compose: api and web.

- build: This section specifies the path to the Dockerfile that will be used to build the container for each service.

- ports: This section maps the container port to the host port, allowing the services to be accessed from the host machine.

- volumes: This section maps the local directory on the host machine to the directory in the container, allowing changes made to the code on the host to be reflected in the container.

- command: This section specifies the command that will be executed when the container is started. In the case of the api service, it starts the Django server and exposes it to the container network, and for the web service, it starts the React app.

## Building the Image

Now, the final step, to build the image we will be using docker command `docker-compose build`.

After exciting this command it will take some time to build the image. Once the image has been built, you can see the image in your docker desktop app.


![Docker Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5mskkugxg7x2imbvq55.png)

Once the building of image has been completed, we can run the app using the docker command `docker-compose up`


![Docker is up](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0yuo2nezlec32qhxzr4x.png)

You can see all the images that are being used in the terminal.

![Local Host](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfjkzu43jxiy6pzvu7c6.png)

Once all the images are running, you can access the web app on [local host]( http://localhost:3000/ ).

If you're interested in the code mentioned above, you can find it on [GitHub](https://github.com/adii9/dockerup). If you find it useful or valuable, consider giving the repository a star to show your support!

## Conclusion

In this tutorial, we learned how to dockerize a Python and React.js app using Docker Compose. We also saw how to create a Docker container for our Django app and run it in a container. By following these steps, developers can ensure that their application runs consistently and reliably across different environments, reducing errors and improving performance. With Docker, deploying applications has never been easier.

Also, if you enjoyed this content and would like to stay updated on future posts, feel free to connect with me on [LinkedIn](https://www.linkedin.com/in/aditya-mathur-52322b16a/) or [X](https://twitter.com/adii_mathur) or check out my [Github ](https://github.com/adii9)profile. I'll be sharing more tips and tricks on Django and other technologies, so don't miss out!

If you find my content valuable and would like to support me, you can also [buy me a coffee](https://www.buymeacoffee.com/aditya360l). Your support helps me continue creating helpful and insightful content. Thank you!