인스턴스에 필요없는 파일들 지워주기
1) 파일 삭제
rm 파일이름2) 디렉토리 삭제
rm -r 디렉터리이름
-r 옵션: 디렉터리와 그 내부의 모든 파일 및 하위 디렉터리를 삭제합니다.3) 여러 파일 및 디렉터리 삭제
rm 파일1 파일2 디렉터리1 디렉터리24) 확인 없이 삭제
rm -rf 파일이름 또는 디렉터리이름rm -rf ./*현재 디렉터리(.)의 모든 파일과 서브디렉터리를 강제로(-f 옵션) 삭제합니다.
- 관리자 권한이 필요한 경우 명령어 앞에
sudo를 붙여줍니다.- 관리자 계정으로 전환하여 진행해도 됩니다.
관리자 권한으로 전환
sudo su - cd /home/ubuntu 삭제 진행 EXIT or CTRL D로 나오기
sudo docker updatesudo apt install docker.io
sudo docker --version
안 쓰는 도커 이미지나 컨테이너 지워주기
1) 사용하지 않는 이미지 삭제
sudo docker image prune -a2) 사용하지 않는 컨테이너 삭제
sudo docker container prune3) 사용하지 않는 볼륨 삭제
sudo docker volume prune4) 사용하지 않는 네트워크 삭제
sudo docker network prune5) 위 명령어들을 한 번에 실행
sudo docker system prune -a
정지된 컨테이너 / 사용되지 않는 네트워크, 이미지 등
sudo docker ps -a명령어로 현재 시스템에 존재하는 모든 Docker 컨테이너의 목록을 확인해서 이것을 지워주고 싶다면,sudo docker rm -f 컨테이너 1 이름 앞 두 글자 컨테이너 2 이름 앞 두 글자명령어로 지워주면 됩니다.
sudo mkdir -p /usr/lib/docker/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o /usr/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/lib/docker/cli-plugins/docker-compose
sudo docker compose version
postgresql은 오픈 소스 데이터베이스로 무료입니다. 또한 장고에서는 기본 데이터베이스로 postgresql을 사용하는 것을 권장하고 있습니다.
💡 docker에서 사용 가능한 이미지들은 https://hub.docker.com에서 제공하고 있습니다.

Docker Compose를 사용하여 PostgreSQL 컨테이너를 실행할 것이므로 위의 명령어는 사용하지 않겠습니다.
Gunicorn(Green Unicorn)은 Python 웹 서버의 하나로, WSGI(웹 서버 게이트웨이 인터페이스)를 지원하는 서버입니다. WSGI는 Python 웹 어플리케이션과 웹 서버 간의 통신을 정의하는 인터페이스 표준입니다.
Gunicorn은 특히 프로덕션 환경에서 Django, Flask 등과 같은 여러 Python 웹 프레임워크를 호스팅하는 데 많이 사용됩니다. Gunicorn은 다중 워커(process)를 사용하여 여러 요청을 동시에 처리하고, 효율적이면서도 안정적인 성능을 제공합니다.
쉽게 설명해서, django 프로젝트를 실행할 때 사용되는 runserver와 같이, 사용자의 요청을 받아 django에 작성한 코드를 실행시켜 주도록 하는 역할을 해줍니다. (= 배포용 runserver)
💡 기본적으로 runserver는 배포용이 아닌 개발용으로 사용되는 명령어이며, 공식 문서에서도 runserver로 배포하는 것을 권장하지 않고 있습니다.
또한 runserver는 기본적으로 싱글 스레드에서 동작하지만, gunicorn은 멀티 스레드로 동작하도록 설정할 수 있기 때문에 많은 요청을 더 효율적으로 처리할 수 있습니다.
pwd # "Print Working Directory" : /home/ubuntu
mkdir YummyYagi-backend # "Make Directory"
cd YummyYagi-backend/ # "Change Directory"

git clone https://github.com/HyeonwoongJang/aws-test ./django
만약 해당 명령어로 git clone 시 아래와 같은 "Permission denied (publickey)" 오류가 난다면,
ubuntu@ip-172-31-36-36:~/YammyYagi-backend$ git clone git@github.com:HyeonwoongJang/aws-test.git ./django
Cloning into './django'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
깃헙 주소를 잘못 가지고 오는지를 확인해주세요... SSH 주소가 아닌 HTTPS 주소로 가져와야합니다.

git clone git@github.com:HyeonwoongJang/-.git ./django
이거로 하면 안됩니다....

settings.py & timezone & .env 설정settings.pyfrom datetime import timedelta
import os
from pathlib import Path
import environ
BASE_DIR = Path(__file__).resolve().parent.parent
env = environ.Env(DEBUG=(bool, True))
environ.Env.read_env(
env_file=os.path.join(BASE_DIR, '.env')
)
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
GPT_API_KEY = env('GPT_DALLE_API_KEY')
DEEPL_AUTH_KEY = env('DEEPL_AUTH_KEY')
PRES_API_KEY = env('PRES_API_KEY')
KAKAO_API_KEY = env('KAKAO_API_KEY')
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': env('POSTGRES_DB'),
'USER': env('POSTGRES_USER'),
'PASSWORD': env('POSTGRES_PASSWORD'),
'HOST': env('POSTGRES_HOST'),
'PORT': env('POSTGRES_PORT'),
}
}
ALLOWED_HOSTS = ['*']
STATIC_ROOT = BASE_DIR / "static"
timezone 설정하기ubuntu@ip-172-31-36-36:~/YummyYagi-backend$ date
Sun Nov 19 18:49:15 UTC 2023
timezone을 변경해주기 위해, 기존 timezone 설정을 Asia/Seoul로 덮어씁니다.
ubuntu@ip-172-31-36-36:~/YummyYagi-backend$ sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
ubuntu@ip-172-31-36-36:~/YummyYagi-backend$ date
Mon Nov 20 03:49:52 KST 2023
.env 설정SECRET_KEY='...'
DEBUG=1
# Celery
EMAIL_PORT=587
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_PASSWORD='...'
EMAIL_HOST_USER='...'
EMAIL_USE_TLS=True
# GPT / DALL-E API 키
GPT_DALLE_API_KEY='...'
# DeePL API 키
DEEPL_AUTH_KEY='...'
# Perspective API 키
PRES_API_KEY='...'
# Kakao API 키
KAKAO_API_KEY='...'
# PostgreSQL
POSTGRES_DB='...'
POSTGRES_USER='...'
POSTGRES_PASSWORD='...'
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
vi Dockerfile
# python 3.11.5버전 이미지를 사용해 빌드 - 프로젝트 파이썬 버전
FROM python:3.11.5
# .pyc 파일을 생성하지 않도록 설정합니다.
ENV PYTHONDONTWRITEBYTECODE 1
# 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정합니다.
ENV PYTHONUNBUFFERED 1
# /app/ 디렉토리를 생성합니다.
RUN mkdir /app/
# /app/ 경로를 작업 디렉토리로 설정합니다.
WORKDIR /app/
# requirments.txt를 작업 디렉토리(/app/) 경로로 복사합니다. - Dockerfile은 프로젝트를 클론 받아온 YummyYagi-backend 디렉토리에 존재합니다.
COPY ./django/requirements.txt .
# 프로젝트 실행에 필요한 패키지들을 설치합니다.
RUN pip install --no-cache-dir -r requirements.txt
# gunicorn을 사용하기 위한 패키지를 설치합니다.
RUN pip install gunicorn psycopg2
nginx는 클라이언트의 request 요청을 처리해주는 웹 서버(web server)입니다. reverse proxy, 로드밸런싱, 캐싱 등의 기능을 지원하며, 클라이언트의 요청을 nginx가 받은 후 service(django) 데이터를 넘겨주는 역할을 해줍니다.
Nginx를 사용하는 이유는 로드밸런싱, SSL 기능, reverse proxy 기능, 그리고 콘텐츠 캐싱을 통해 효율적인 트래픽 관리와 보안 강화, 성능 최적화를 가능하게 하기 때문입니다.
/home/ubuntu/
mkdir nginx
touch default.conf
vi nginx/default.config
server {
listen 80;
server_name _; # 모든 도메인 혹은 ip로 들어오는 요청에 대해 처리해 줍니다.
location / { # nginx로 요청이 들어왔을 때
proxy_pass http://backend:8000/; # backend 컨테이의 8000번 포트로 전달합니다.
}
location /static/ { # 브라우저에서 /static/ 경로로 요청이 들어왔을 때
alias /static/; # /static/ 경로에 있는 파일들을 보여줍니다.
}
location /media/ { # 브라우저에서 /media/ 경로로 요청이 들어왔을 때
alias /media/; # /media/ 경로에 있는 파일들을 보여줍니다.
}
}
vi docker-compose.yml
version: '3.8'
volumes:
django_media: {}
django_static: {}
postgres: {} # postgresql에서 사용 할 볼륨 지정
services:
postgres:
container_name: postgres
image: postgres:14.5
volumes:
- postgres:/var/lib/postgresql/data/
environment:
- POSTGRES_USER
- POSTGRES_PASSWORD
- POSTGRES_DB
restart: always
backend:
container_name: backend
build: ./YummyYagi-backend/
entrypoint: sh -c "python manage.py collectstatic --no-input && python manage.py migrate && gunicorn yummy_yagi.wsgi --workers=5 -b 0.0.0.0:8000"
volumes:
- ./ymbackend/django/:/app/
- /etc/localtime:/etc/localtime:ro
- django_media:/app/media/ # nginx에서 media를 사용할 수 있도록 volume을 지정해줍니다.
- django_static:/app/static/ # nginx에서 static을 사용할 수 있도록 volume을 지정해줍니다.
environment: # django에서 사용할 설정들을 지정해줍니다.
- DEBUG
- POSTGRES_DB
- POSTGRES_USER
- POSTGRES_PASSWORD
- POSTGRES_HOST
- POSTGRES_PORT
depends_on:
- postgres
restart: always
nginx:
container_name : nginx
image: nginx:1.23.2
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- django_media:/media/ # django의 media를 사용할 수 있도록 volume을 지정해줍니다.
- django_static:/static/ # django의 static 사용할 수 있도록 volume을 지정해줍니다.
depends_on:
- backend
restart: always
- docker-compose.yml을 작성한 django 프로젝트를 실행시키기 위한 entrypoint 명령어
sh -c "python manage.py collectstatic --no-input && python manage.py migrate && gunicorn project_name.wsgi --workers=5 -b 0.0.0.0:8000"
sh -c: 컨테이너에서 뒤에 작성한 명령어를 실행시킬 수 있도록 해줍니다.&&: 특정 명령어를 실행한 이후 다음 명령어를 실행시켜 줍니다.python manage.py collectstatic --no-input: 배포를 위해 static 파일을 모아줍니다. 해당 명령어를 실행시키기 위해서는 settings.py에 STATIC_ROOT가 정의되어 있어야 합니다.python manage.py migrate: django에 연결된 db를 migrate 해줍니다.gunicorn project_name.wsgi --workers=5 -b 0.0.0.0:8000: gunicorn을 사용해 django 프로젝트를 실행시킵니다.
project_name:settings.py 파일이 있는 django 프로젝트 폴더 이름을 입력합니다. 이름을 다르게 입력할 경우 에러가 발생합니다.--workers=5: django를 실행시킬 process 갯수를 입력합니다. 일반적으로 cpu 코어 갯수 2 + 1만큼 지정해줍니다.(ex - 2코어라면 22+1=5)-b 0.0.0.0:8000: 8000번 포트로 실행시킵니다.
sudo docker compose up --build -d
Dockerfile에 정의한 run 명령어, WORKDIR 명렁어, COPY 명령어가 실행되고 패키지 설치까지 끝나면 정상적으로 컨테이너가 생성됩니다.
sudo docker compose logs -f
이 과정에서 발생하는 에러는 다음 포스팅에 정리해보도록 하겠습니다.
도커를 이용한 배포 전 과정을 상세히 정리해주셨네요👍