WEB-DEV
One of the options for delivering an AI application is creating a USER INTERFACE so that the clients can use the AI app even without any knowledge of programming. For this time, I’ve decided to try it out on AWS.
To be honest, the deployment process was WAAAY harder than I’d expected. (After a while, I found out that using AWS ECR and ECS instead is more preferable considering scalability, but I was already halfway there so I just went with it)
CODE
I’m using docker-compose with 3 services..
1. backend -> DJANGO app
2. db
3. Nginx
Directory TREE
├─backend
│ ├─.env
│ └─DockerFileBack.prod
│
├─nginx
│ ├─default.conf
│ └─DockerFile
│
└─docker-compose.prod.yml
docker-compose.prod.yml
version: "3.3"
services:
#Container for BACKEND
backend:
container_name: backend
build:
context: ./backend
dockerfile: DockerFileBack.prod
# Command I want to run every time the container is built
command: >
/bin/bash -c "
python manage.py makemigrations;
python manage.py migrate --noinput;
python manage.py collectstatic --no-input --clear; #--CHECK DockerFileBack.file
gunicorn -b 0.0.0.0:8000 PROJECT_NAME.wsgi:application; #Bind gunicorn to port 8000
"
# Exposing a port lets other container access this port
expose:
- 8000
# Path to .env file which has the secret access keys
env_file:
- ./backend/.env
depends_on:
- db
db:
image: postgres:13.0-alpine
container_name: db
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file: ./backend/.env
nginx:
build: ./nginx
# Nginx CANNOT serve static files so you'll need to..
# 1.Create directory "staticfile" -> Check DockerFileBack.prod
# 2.run collectstatic command like the code in the backend container
# This will save the static data to directory in step 1.
# 3.Set volume name and file path here to the staticfiles directory
volumes:
- static_volume:/home/app/web/staticfiles
#When someone Accesses port 1337 -> connect with the port 80 in DOCKER
#Later on we'll proxy all request from port 80 to 8000
ports:
- "1337:80"
depends_on:
- backend
volumes:
postgres_data:
static_volume:
DockerFileBack.prod
FROM python:3.9.5
ENV PYTHONUNBUFFERED 1
# create directory
RUN mkdir -p /home/app
# create the appropriate directories
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
#All the data from collectstatic command(docker-compose.yml) Will be saved here,
RUN mkdir $APP_HOME/staticfiles
WORKDIR $APP_HOME
COPY . .
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
# copy project
COPY . $APP_HOME
Nginx (Most confusing part for me)
There are 2 files you’ll need to configure.
1. default.conf
2. DockerFile -> Replace the default default.conf inside the container with the one you’ve created in Step1
default.conf
#ANY_NAME should be the same as the location's proxy pass below
upstream ANY_NAME {
server back:8000;
}
server {
#If someone comes to port 80..
listen 80;
#Proxy to ANY_NAME (which is port 8000)
location / {
proxy_pass http://ANY_NAME; #ANY_NAME can be any name as long as it is the same as the upstream name
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/staticfiles/;
}
}
DockerFile
# Get Image
FROM nginx:1.21-alpine
# remove the default default.conf
RUN rm /etc/nginx/conf.d/default.conf
# replace with the default.conf you've created
COPY default.conf /etc/nginx/conf.d/default.conf