AWS Blog
Overview of AWS
Personalized Deployment Blog
Introduction
Deployment is the final step in the software development lifecycle. Before we push our project live, it is crucial to ensure that everything is properly set up, from the frontend to the backend. This guide outlines the essential steps required for deploying a full-stack application, covering everything from server configuration to DNS setup.
Preparing for Deployment
Before starting, complete a thorough review of the frontend-to-backend integration. Ensure that your test server is running smoothly locally. If it doesn’t work locally, it won’t work in production.
Additionally, document the deployment process, including terms, visuals, and troubleshooting steps. Clearly define roles for Deployment Admins and prepare necessary configuration files in your repository.
Deployment Steps
1. Build and Test
Build your application locally and test it to ensure that it works as expected.
2. Configure files for Deployment
NGINX FILE (motor.stu.nginx_file)
server {
listen 80;
listen [::]:80;
server_name motor.stu.nighthawkcodingsociety.com ; # Change server name to the one on R53
# Configure CORS Headers
location / {
proxy_pass http://localhost:8104; # Change port to port on docker
# Simple requests
if ($request_method ~* "(GET|POST|PUT|DELETE)") { # Customize Request methods based on your needs
add_header "Access-Control-Allow-Origin" *;
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS, HEAD"; # Make sure the request methods above match here
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
}
docker-compose.yml
version: '3'
services:
web:
image: motorsports
build: .
env_file:
- .env # This file is optional; defaults will be used if it does not exist
ports:
- "8104:8104"
volumes:
- ./instance:/instance
restart: unless-stopped
Dockerfile
FROM docker.io/python:3.12.8
WORKDIR /
# --- [Install python and pip] ---
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y python3 python3-pip git
COPY . /
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install gunicorn
RUN ./scripts/db_init.py
ENV GUNICORN_CMD_ARGS="--workers=3 --bind=0.0.0.0:8104"
EXPOSE 8104
# Define environment variable
ENV FLASK_ENV=production
CMD [ "gunicorn", "main:app" ]
3. Deploy to AWS EC2 using cockpit backdoor
Clone the repository to the virtual machine
git clone https://github.com/Tvick22/personal_flocker_backend.git motor_backend
cd motor_backend
Recreate the .env file
touch .env
Add the following to the .env file
ADMIN_USER='toby'
ADMIN_PASSWORD='123Toby!'
DEFAULT_USER='hop'
DEFAULT_PASSWORD='123Hop!'
Ensure that the DOCKERFILE file can initialize the database
RUN ./scripts/db_init.py
Build the docker image
docker-compose build
Run the docker image
docker-compose up -d
Ensure that the docker image is running on our port (8104)
docker ps
Ensure we are running on port 8104
curl localhost:8104
4. Configure DNS (Domain Name)
Configure the DNS to point to the EC2 instance. This can be done by creating a new record set in the hosted zone, stu.nighthawkcodingsociety.com. The hosted zone can be found in the AWS console under Route 53. The record set can be created by clicking on Create Record Set and selecting the appropriate values.
How is my frontend integrated with my backend?
The frontend is integrated with the backend by using a proxy server. The proxy server is responsible for forwarding requests to the appropriate backend server. In this case, the proxy server is NGINX, which is configured to forward requests to the backend server running on port 8104.
Step by step exapmle
- The frontend sends a request to the domain. (motor.stu.nighthawkcodingsociety.com)
- The domain name is resolved to the IP address of the server. (DNS)
- The IP address is sent to the proxy server where it is forwarded to the appropriate docker container based on the port (8104). (NGINX)
- The docker container running on port 8104 receives the request and processes it. (Python Flask)
- The response is sent back to the proxy server and the proxy server sends it to the frontend. (NGINX to frontend)
TCP and Certbot
In this exapmle, requrests are sent using the TCP (Transmission Control Protocol) protocol. A three-way TCP handshake establishes a reliable connection between the client (browser) and the server.
The Certbot tool is used to encrypt the data sent between the client and the server. This ensures that the data is secure and cannot be intercepted by third parties. It also enables HTTPS, which is a secure version of the HTTP protocol.
Physical Connection
In this exapmle, the physical connection between the client and the server is established using a Ethernet cable or Wi-Fi or fiber optic cable. IP packets are converted into physical signals, and these signals traverse physical infrastructure, including cables, wireless access points, and routers.
Layers of the TCP/IP Model
The TCP model is a conceptual framework that describes the functions of a communication system.
- Application Layer - In this case, the application layer is the frontend web server (Github Pages)
- Transport Layer - In this case, the transport layer is the TCP protocol and NGINX
- Network Layer - In this case, the network layer is the IP protocol and Router
- Physical Layer - In this case, the physical layer is the Ethernet cable or Wi-Fi or fiber optic cable
Example of a TCP/IP model:
Restart nginx (Dont forget to test it before though)
sudo systemctl restart nginx
Deployment
docker-compose build
docker-compose up -d
If you want to see debug messages then remove the -d tag (it stands for detach).
docker exec -it motor_backend-web-1 scripts/db_init.py
exec runs a bash command in the docker container.