Django 서비스 AWS로 배포하기 - [1] 프로젝트 준비와 AWS 서버 대여
Django 서비스 AWS로 배포하기 - [2] github과 프로젝트 업로드
Django 서비스 AWS로 배포하기 - [3] uWSGI 연결하기
사용자의 브라우저를 통한 요청은 웹 서버가 받는 것이 일반적이지 uwsgi가 받아 처리하는 것은 적절하지 않습니다. 이번 포스트에는 저번 포스트를 통해 Django와 연결해둔 uwsgi 서버와 nginx를 연결해 1차 배포를 완료해 보겠습니다.
* 2022.01.30 업데이트
3번 글처럼 deploy라는 계정을 만들어 사용하는 부분이 없어짐에 따라, 아래 deploy 계정을 썼던 부분들이 수정되었습니다. 기존에 포스팅을 참고하셨던 분들은 유의 바랍니다!
nginx 와 uwsgi를 연결하기
nginx는 대표적인 웹 서버 어플리케이션입니다. 웹 서버는 사용자의 요청(request)을 받아 적절한 반응(response)을 해주는 역할을 하는데, 우리의 Django 프로젝트와 연결한다면 우리가 구축한 이 프로젝트의 방식대로 nginx가 사용자에게 반응해줄 수 있을겁니다.
먼저 서버 컴퓨터에서 nginx를 설치해 줍니다.
$ sudo apt-get install nginx
nginx도 배포에 사용되는 어플리케이션이고, 배포는 기본 계정인 ubuntu가 진행할 것입니다. 따라서, nginx의 설정 파일에서 nginx를 사용하는 유저가 ubuntu임을 알려줍니다. 다음 명령어를 통해 설정 파일을 연 뒤,
$ sudo vi /etc/nginx/nginx.conf
키보드에서 i를 눌러 수정 모드로 바꾼 뒤 첫 줄에 www-data로 되어 있는 user를 ubuntu로 아래와 같이 수정해주고,
user ubuntu;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
.... 중략
esc를 눌러 수정 모드를 해제한 뒤 :wq 친 뒤 엔터를 하면 저장이 되고 파일을 나갑니다.
다시 로컬 컴퓨터로 돌아와서 nginx 설정 파일을 만들어 줄겁니다. 로컬 컴퓨터에서 프로젝트 폴더 내에 .config 폴더 안에 nginx 폴더를 만들고 mysite.conf 파일을 만들어 줍니다. 이런 구조가 되겠죠?
.config
├── nginx
│ └── mysite.conf
└── uwsgi
│ └── mysite.ini
mysite.conf 파일에 다음과 같이 입력합니다.
.config/mysite.conf
server {
listen 80;
server_name *.compute.amazonaws.com;
charset utf-8;
client_max_body_size 128M;
location / {
uwsgi_pass unix:///tmp/mysite.sock;
include uwsgi_params;
}
}
- listen: 요청을 받을 포트 번호를 의미합니다. 80 포트가 http 기본 포트로 여겨집니다.
- server_name: 요청을 받을 서버 주소를 의미합니다. 어디서 많이 봤죠? settings.py의 ALLOWED_HOSTS 변수에 추가한 적이 있습니다.
- location / { }: "server_name/" 식의 요청이 들어올 경우, 처리할 내용에 대해서 정의합니다. location /static/ {} 의 경우엔 "server_name/static/" 주소 요청이 올 경우를 뜻하겠죠?
엇 포트가 80포트로 변경되었네요. 우선 .config/uwsgi/mysite.ini 파일에는 8080포트로 되어 있는데 이 부분을 먼저 수정해주어야 할 것 같습니다. (http = :8080이 삭제되고 그 자리에 소켓 정보와 소유자, 권한을 서술한 세 줄이 추가 됩니다.)
.config/uwsgi/mysite.ini
[uwsgi]
chdir = /srv/django-deploy-test/
module = mysite.wsgi:application
home = /home/ubuntu/myvenv/
uid = ubuntu
gid = ubuntu
socket = /tmp/mysite.sock
chmod-socket = 666
chown-socket = ubuntu:ubuntu
enable-threads = true
master = true
vacuum = true
pidfile = /tmp/mysite.pid
logto = /var/log/uwsgi/mysite/@(exec://date +%%Y-%%m-%%d).log
log-reopen = true
수정된 파일을 서버에 올리기 전에, 짚어야 할 점은 nginx는 항상 켜져있어야 한다는 점입니다. 이전 포스트에서 uwsgi는 결국 명령어를 통해 실행을 해줘야만 켜지는데 uwsgi와 nginx를 연결해야 한다면 uwsgi도 항상 켜져있어야 합니다. 따라서 uwsgi를 계속 켜둘 수 있도록 설정 파일을 추가해서 백그라운드에 계속 실행하도록 합니다.
로컬 컴퓨터의 프로젝트 폴더의 .config 폴더의 uwsgi 폴더안에 uwsgi.service 파일을 만들어 다음과 같이 입력해주고 저장합니다.
[Unit]
Description=uWSGI service
After=syslog.target
[Service]
ExecStart=/home/ubuntu/myvenv/bin/uwsgi -i /srv/django-deploy-test/.config/uwsgi/mysite.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
ExecStart에 있는 값을 어디서 많이 보지 않았나요? 이전 포스트에서 uwsgi를 관리자 권한으로 실행할 때의 명령어입니다. 이걸 service 로 등록하여 백그라운드에 계속 실행하게 할 거에요.
프로젝트 내의 파일들이 변경되었으니 다시 github으로 git push 한 뒤,
$ git add .
$ git commit -m "nginx configuration update"
$ git push origin master
서버 컴퓨터에서 git pull 합니다. git pull과 push는 모두 manage.py가 있는 폴더에서 진행함을 잊지 말아주세요.
$ git pull origin master
먼저 uwsgi.service 파일을 데몬(백그라운드에 실행)에 등록해줍니다. 이 파일을 /etc/systemd/system/ 에 링크를 걸어줍니다.
$ sudo ln -f /srv/django-deploy-test/.config/uwsgi/uwsgi.service /etc/systemd/system/uwsgi.service
데몬을 새로고침 해주고,
$ sudo systemctl daemon-reload
uwsgi 서비스를 사용 가능하게 변경해주고 restart 한 번 해줍니다.
$ sudo systemctl enable uwsgi
$ sudo systemctl restart uwsgi
또한, Django 프로젝트 내의 nginx 설정 파일을 nginx 어플리케이션에 등록해 주어야 합니다. cp 명령어를 이용해 등록하는 경로(sites-available)로 파일을 복사해줍니다.
$ sudo cp -f /srv/django-deploy-test/.config/nginx/mysite.conf /etc/nginx/sites-available/mysite.conf
sites-available에 복사된 설정 파일을 sites-enables폴더 안에서도 링크해줍니다.
$ sudo ln -sf /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/mysite.conf
sites-enables폴더 안의 default 파일을 삭제해줍니다.
$ sudo rm /etc/nginx/sites-enabled/default
이제, 다시 데몬을 새로 고침 해주고 nginx와 uwsgi를 다시 실행해 줍니다.
$ sudo systemctl daemon-reload
$ sudo systemctl restart uwsgi nginx
마지막으로 AWS에 들어가서 지금까지 등록하지 않았던 80번 포트를 열어줍니다. 그리고 저장해줍니다.
이제 다 됐습니다! EC2 인스턴스의 퍼블릭 DNS 주소로 포트 번호 없이 접속해 봅니다.
http://ec2-15-164-212-231.ap-northeast-2.compute.amazonaws.com/
와!! 여기까지 따라오시느라 너무 힘들었을 것 같아요. 수고 많으셨어요!! 첫 배포에 성공하셨습니다!
static 파일 연결해주기
하지만 아직 남은 과제가 있어요 ㅠㅠ Django에는 admin 페이지가 있죠? 한 번 들어가 봅시다.
이건 우리가 보던 admin 페이지의 모습이 아닙니다. 보아하니, html을 꾸며주는 css, js 파일들(정적 파일이라 하여 static 파일이라고 불립니다.)을 로드하지 못하는 것 같군요. 문제는 static 파일의 경로가 nginx에서 설정되어 있지 않기 때문에 발생합니다. static 파일들은 Django 프로젝트 내에 앱 별로 구분되어 놓여있는 경우가 대부분이기 때문에, 이 static 파일들을 하나의 경로로 먼저 모아둘 필요가 있습니다. 이를 쉽게 해주는 명령어는 python3 manage.py collectstatic이에요. 먼저, 이 명령어를 사용하려면 settings.py에 static 파일이 모이는 경로를 설정해 주어야 합니다.
로컬 컴퓨터에서 settings.py 파일의 제일 하단 STATIC_URL 밑에 아래 값을 추가합니다.
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_ROOT 값을 추가한 뒤에 collectstatic 명령어를 사용하면 STATIC_ROOT의 경로에 각 앱의 static 파일들이 모아집니다. 위의 값은 프로젝트 폴더 안에 static 폴더를 만들어 그곳에 모이게 해두게 됩니다. (BASE_DIR이 프로젝트 폴더의 절대 경로를 의미합니다.)
그럼 변경 사항을 git push 하고 서버 컴퓨터에서 pull 합니다. (이제 git push pull 명령어는 생략할게요!) 그 후, 서버 컴퓨터의 manage.py가 있는 폴더에 가서 아래 명령어를 칩니다. 그러면 현재 폴더에 static 폴더가 생기고,
$ python3 manage.py collectstatic
130 static files copied to '/srv/django-deploy-test/static'.
$ ls
db.sqlite3 main manage.py mysite requirements.txt static
다음과 같이 admin폴더를 포함한 static 파일들이 모인 것을 볼 수 있습니다.
static
└── admin
├── css
├── fonts
├── img
└── js
그럼 끝난 것일까요? 아직입니다. mysite.conf 로 설정한 우리의 nginx는 현재 static 파일들이 어디에 있는지 알 수 없습니다. 다시 로컬 컴퓨터로 돌아와서 mysite.conf 파일에서 /static/ 요청시 파일의 경로를 알려줍니다.
.config/nginx/mysite.conf
server {
listen 80;
server_name *.compute.amazonaws.com;
charset utf-8;
client_max_body_size 128M;
location / {
uwsgi_pass unix:///tmp/mysite.sock;
include uwsgi_params;
}
location /static/ {
alias /srv/django-deploy-test/static/;
}
}
그러면 이제 css, js 등 static 파일의 요청이 있을 경우 프로젝트 폴더의 static 폴더를 찾아 적절히 response 해줄 수 있을겁니다. 수정 사항을 git으로 서버 컴퓨터에 옮겨주세요.
이제 mysite.conf 파일을 다시 nginx에 등록해 주어야 합니다. mysite.conf 파일이 수정되었으니까요. 위에서 처럼 다시 nginx에 등록하기 위한 명령어를 입력해줍시다.
$ sudo cp -f /srv/django-deploy-test/.config/nginx/mysite.conf /etc/nginx/sites-available/mysite.conf
$ sudo ln -sf /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/mysite.conf
nginx, uwsgi를 다시 껐다 켜줍니다.
$ sudo systemctl daemon-reload
$ sudo systemctl restart uwsgi nginx
다시 admin 사이트를 들어가면 정상적으로 static 파일들이 적용된 것을 확인할 수 있습니다.
http://ec2-15-164-212-231.ap-northeast-2.compute.amazonaws.com/admin/
네! 이렇게 해서 static 파일까지 적용되어 깔끔하게 나의 서비스를 사람들에게 보여줄 수 있는 수준까지 되었습니다! https가 아닌 http 통신을 사용하고 있고 주소의 이름이 예쁘지는 않지만, 우선 자신의 프로젝트를 누군가 볼 수 있게 되었다는 점에서 1차적으로 배포가 완료되었다고 볼 수 있습니다. 축하드려요!
도메인을 변경하셔야 하고 https로 접속되셔야 한다면 이어서 업데이트되는 포스팅들을 따라해 주시면 됩니다. 저는 첫 배포를 할 때 이 포스팅 수준까지 진행하고 만족만족 대만족 했던 것 같습니다. 고생 많으셨고, 배포하신 서비스의 주소를 친구들에게 보내서 접속하게 해보세요! 감회가 새로울 것입니다.
다음 포스팅은 서비스의 주소를 나만의 도메인으로 변경하는 작업을 해보도록 하겠습니다.
'웹 > Django' 카테고리의 다른 글
Django 서비스 AWS로 배포하기 - [6] https 적용하기 (31) | 2020.03.27 |
---|---|
Django 서비스 AWS로 배포하기 - [5] 도메인 연결하기 (가비아) (10) | 2020.03.26 |
Django 서비스 AWS로 배포하기 - [3] uWSGI 연결하기 (46) | 2020.03.15 |
Django 서비스 AWS로 배포하기 - [2] github과 프로젝트 업로드 (6) | 2020.03.15 |
Django 서비스 AWS로 배포하기 - [1] 프로젝트 준비와 AWS 서버 대여 (17) | 2020.03.15 |