I completed this task while participating in HNG DevOps task and thought to write on the process taken to achieve this.
Project Task
The task is focused on containerizing the given applications written in react and django, running the containers with Docker Compose and using Nginx reverse proxy to serve the frontend application as the default page.
Prerequisites
To get started, it's important to have the below
- An active AWS Account
- A Docker Hub Account
- Knowledge of containers
GitHub
To see the completed project, you can visit the GitHub Repo here.
Getting Started
Create an ec2 instance (vm) from your AWS Console and login.
sudo apt update
sudo apt upgrade
Clone the below repo into it
git clone https://github.com/ibitolamayowa/devops-django-react-task.git
Install docker
You can refer to this article to install Docker
Check that Docker is running
sudo systemctl status docker
Log out and log back in to add the user
To add a password
sudo passwd
Containerizing the application
cd into it , then cd into frontend
cd devops-django-react-task/
cd frontend/
cd src
cd components/
We would first start by editing the App.js file in this location
sudo nano App.js
The file should look like the below, you should change the name to your name.
Create Dockerfile file for frontend
Now move back to the frontend directory, you should be in this directory /devops-django-react-task/frontend
To create your Dockerfile, use the below command
sudo nano Dockerfile
Paste the below into the file and save
# ==== CONFIGURE =====
# Use a Node 16 base image
FROM node:16-alpine
# Set the working directory to /frontend inside the container
WORKDIR /frontend
# Copy frontend files
COPY . .
# ==== BUILD =====
# Install dependencies (npm ci makes sure the exact versions in the lockfile gets installed)
RUN npm i
# Build the app
RUN npm run build
# ==== RUN =======
# Set the env to "production"
ENV NODE_ENV production
# Expose the port on which the app will be running (3000 is the default that `serve` uses)
EXPOSE 3000
# Start the app
CMD [ "npx", "serve", "build" ]
Save and exit.
Build Docker Image
Now you would build the docker image from the Dockerfile file you just created
Ensure you are in the frontend directory where the Dockerfile and application are present while doing this.
docker build -t frontend .
To see the built image, run
docker images
Now you need to push the image to docker hub
docker login
After logging into your account, tag the image and push it
##docker tag imagename username/tag
docker tag frontend favourd205/frontend
docker push favourd205/frontend
Create Dockerfile for Backend (API)
Now cd back to the api folder, you should be in this directory path
cd ..
cd api/
We would first edit the requirements.txt file here as the current psycopg2==2.9.5 version in the file is not supported.
To do this, run the below command
sudo nano requirements.txt
Replace the psycopg2==2.9.5
with psycopg2-binary
Now we can create the Dockerfile file. To do this run the below command
sudo nano Dockerfile
copy and paste the below into it
FROM python:3.8-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONBUFFERED=1
RUN mkdir /backend
WORKDIR /backend
COPY . /backend/
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Now to build the image
docker build -t backend .
NB: Its best practice to do build the image in a virtual environment, it is also possible to build the image without a virtual environment like the below
Now we can push the image
docker tag backend favourd205/backend
docker push favourd205/backend
Check your Docker Hub registry and you should see the two images there
Running the Docker Containers
Now to run the containers you would need docker compose, install docker compose on the virtual machine.
To install docker compose, refer to this
cd out of the api directory and ensure you are on this path devops-django-react-task
. That is where the installation should happen.
After installation, create a docker-compose.yaml
file and paste the below into it
sudo nano docker-compose.yaml
Pate the below into the file
version: "3"
services:
frontend:
image: favourd205/frontend:latest
container_name: frontend
ports:
- 3000:3000
depends_on:
- backend
backend:
image: favourd205/backend:latest
container_name: backend
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
After saving, run
docker-compose up -d
or
docker-compose up --detach
=====remember to allow all traffic
This should run and bring up the two container images
Navigate to your instance ip address on the assigned ports and your applications should be running
Frontend runs on port 3000
Backend runs on port 8000
Routing frontend with Nginx
Now you should install nginx for reverse proxy
sudo apt update
sudo apt install nginx
Confirm that nginx is running
sudo service nginx status
or
sudo systemctl status nginx
For reverse proxy, enter nginx directory
cd /etc/nginx/
ls
Now you can see all nginx files, we need to edit the nginx.conf file
sudo nano nginx.conf
delete all the configurations in the file and use the below
events{
worker_connections 1024;
}
http {
keepalive_timeout 5;
upstream frontend {
keepalive 50;
server 54.173.78.222;
}
server {
listen 80;
location / {
proxy_set_header X-Real-lP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://54.173.78.222:3000;
}
}
}
NB: Ensure to change the server IP address in the configuration to yours as well as the proxy pass IP address
Confirm the above configuration syntax is correct
sudo nginx -t
It should return successful
Now reload nginx
sudo nginx -s reload
Now copy your IP address again but this time do not add any port number to it, the frontend application is supposed to be running by default on the IP address.
Top comments (0)