진짜진짜 너무 중요한 마지막 단계!
이를 통해 얼추 실제 웹 서버의 통신 단계에 대해서 이해하게 되었다. 또한 다양한 설정을 하는 것에 있어서 구글에 힌트가 있지 그것들이 정답이 아닐 수 있으므로, 깊이 이해하고 사용해야겠다고 느꼈다.
이제 EC2로 만든 가상 컴퓨터 내에 웹서버를 설치하고, 실제로 서버가 작동될 수 있도록 여러가지 설정하는 과정을 진행할 것이다.
이 과정에서 해당 웹서버와 내가 만든 서버 애플리케이션을 연결해보려 한다.
웹서버에는 대표적으로 apache와 Nginx가 있는데, 이번엔 NginX로 웹서버를 설치하여 flask 서버와 연동할 것이다.
우선 블로그 내 이미 EC2 instance를 구축하는 것에 대해서도 정리했고, web server도 설치해보았으므로, 관련해서는 해당 글을 참고하고,
바로 EC2로 구축한 가상 컴퓨터에 들어가서 web server와 flask 서버를 연결해보겠다.
1. 우선 터미널로 서버에 접속을 하고 웹서버를 설치하자.
서버와 연동이 안된 상태에서 EC2의 public IP로 들어가면 아래와 같이 NginX 웹서버 페이지가 렌더링 될 것이다.
** 우리는 EC2 instance라는 이름을 가진 가상의 컴퓨터를 산 것이고, 거기서 우리가 개발단에서 만든 서버를 구동시켜 주어야 한다. 그럴려면 환경을 동일하게 만들어 주어야 한다. 개발단계에서는 파이썬 버전 3.8을 썼는데 prod 단계에서는 다른 버전을 쓰면 안 되지 않을까?
물론 node를 쓴다면 npm 을 통해서 자연스럽게 버전 관리가 가능하다. 그러나 파이썬은 가상환경을 설치하고 / 필요한 라이브러리들을 freeze 해주는 과정이 필요하다.
2. 가상환경 설치(해당 블로그 참고)
-> 다양한 가상환경이 있지만 우리는 anaconda를 사용했으므로, 가상 컴퓨터에도 아나콘다를 설치해주었다.
a. 우선 아래의 링크로 들어가서 내가 원하는 버전을 선정해주자.
https://repo.anaconda.com/archive/
b. 그리고 가상 서버 터미널에 아래의 명령어를 입력해준다. 그러면 내 가상 컴퓨터에 conda를 다운로드 받는 것이다.
sudo wget https://repo.anaconda.com/archive/[파일명]
ex) sudo wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh
c. conda 설치해주기 / 하단의 명령어를 가상서버 터미널에 입력
bash Anaconda3-2020.02-Linux-x86_64.sh
몇가지 동의해야할 것들이 나오는데 yes 처리해주면 됨
d. 아래의 터미널 명령어로 파일을 에디터 모드로 열어서 PATH를 설정하자(이는 필수사항은 아니다)
# 방법 1,2중 한가지로 하면 됨
vim ~/.bashrc # 방법1 vim 에디터 사용
gedit ~/.bashrc # 방법2 그냥 text Editor 사용
PATH = [경로]/bin:$PATH
ex) PATH = /home/[userid]/anaconda3/bin:$PATH
경로에 conda를 설치할 때 알려준 경로를 집어넣어준다.
e. 변경내용 적용하기
source ~/.bashrc
f. 가상환경 추가될 수 있도록 setting 하기
source ~/anaconda3/etc/profile.d/conda.sh
g. 그리고는 개발 단계에서 진행한 것과 똑같은 단계로 가상환경을 만들어주면 된다.
이는 이미 블로그에 정리해두었으니 참고(링크)
3. 배포하고자 하는 프로젝트를 최종 push 하기전에 설치되어있는 라이브러리를 한데 모아서 보여주는 requirement.txt 파일을 생성할 것이다.
$ touch requirements.txt
$ pip freeze > requirements.txt
4. 위의 과정을 통해서 git에 push 된 레포를 git clone 하여 가상 서버에 가지고 오자.
a. 위에서 만든 가상환경을 conda activate [가상환경 이름] 으로 실행해준다.
b. 해당 가상환경 내에 개발단계와 동일하게 라이브러리를 설치해준다.
pip install -r requirements.txt
5. Nginx - uWSGI - 서버 연동해주기
여기서 node 프로젝트를 배포해줄 때는 없었던 새로운 개념이 등장했다.
uWSGI란 무엇일까??? 이 부분에 대해서는 사실 이미 한 번본적이 있고 TIL 로 정리한 적도 있다.
wsgi server는 많은 request들을 다룰 수 있도록 설계되었다. framework들은 스스로 수천개의 request들을 실행하고 최고의 방법으로 처리할 수 있도록 설계되어있지 않다.(django의 경우 manage.py runserver로 배포하면 안된다는 소리다.)
wsgi는 python web 개발 속도를 올려준다,
uWSGI는 이 wsgi의 종류 중 하나이다. 파이썬에서 지원하는 wsgi 종류 중 하나이다.
이에 대해서는 따로 추가적으로 정리해볼 예정이다.
a. 우선 uwsgi 와 nginx 설정 폴더는 메인 root 폴더에 이미 존재하기 때문에 힘들여서 만들어줄 필요는 없다.
가상 서버 터미널에 cd /etc 명령어를 치면, 그 폴더 내에서 uwsgi 와 nginx 폴더를 찾을 수 있다.
b. 가장 중요하다. 가상환경 내에 uwsgi를 설치해 주어야 한다.
-> 이 부분을 놓쳐서 실제로 오랫동안 에러를 겪었다. 이는 왜그런 것일까?
-> 가상환경 또한 일종의 가상 서버이다. 가상 컴퓨터 안의 가상 컴퓨터 라는 개념인 것이다. 그러니 이 가상 서버와 외부 서버를 연결해 줄 미들웨어는 하나의 라이브러리처럼 꼭 다시 설치해 주어야 한다.
-> conda 에서 설치할 때 명령어는 아래와 같다
conda install -c conda-forge uwsgi
c. uwsgi 설정 / 혹은 시작 명령어
구글링을 하면 많이들 uwsgi 설정 파일에 대해 당연하게 설명하고 간다. 하지만 이는 필수는 아니다.
미들웨어를 통해서 서버를 시작할 때 그 명령어가 길어서, 설정 파일을 활용하는 것이다.
나는 만들지 않았다. 자꾸 에러가 발생했기 때문이다. 만약에 만들고자 한다면 해당 블로그를 참고하자
설정 파일 만들고 싶다면
/etc/uwsgi/apps-available/uwsgi.ini 여기 경로에서
[uwsgi]
chdir=/home/ubuntu/[내 프로젝트 폴더이름]
module=[서버 최초 실행파일]:app
master=True
pidfile=/tmp/project-master.pid
vacuum=True
max-requests=5000
home=/home/ubuntu/anaconda3/medisharp/venv - > 아나콘다 가상환경 사용시
virtualenv=/home/ubuntu/anaconda3/medisharp/venv - > 아나콘다 가상환경 사용시
socket=/home/ubuntu/[프로젝트 폴더 이름]/uwsgi.sock
chmod-socket=666
만들지 않는 다면 아래의 명령어로 바로 서버를 실행해 볼 수 있다.
uwsgi --socket 0.0.0.0:5000 --protocol=http -w [서버가 최초로 실행되는 파일]:app
ex) uwsgi --socket 0.0.0.0:5000 --protocol=http -w manage:app
위 명령어는 프로젝트 폴더 내에서 해야한다.
여기서도 한 번더 애를 먹은 것이 wsgi.py 파일을 최초 실행 파일로 만들어서 서버에서 이미 만들어준 파일과 연결하라는 글이 많았다.
하지만 이 또한 선택 사항이다. 오히려 우리 프로젝트 처럼 manage 라이브러리를 써서 폴더 구조를 짰다면 추천하지 않는다.
app.run()이 중복되어서 에러가 난다.
그리고 아래의 명령어로 소켓을 생성해준다.
# 처음 실행 시 (소켓생성)
$ sudo service uwsgi retart
# 설정사항 혹은 flask 웹 어플리케이션 소스 변경 후 적용
$ sudo service uwsgi reload
d. nginx 설정해주기
nginx 설정도 sudo nano /etc/nginx/sites-available/default 이 경로가 필수가 아니다
/etc/nginx 이 경로의 nginx.conf 파일을 건드려줘야 한다,
아래는 설정 파일 내용이다.(아직 SSL 인증 받기 전의 설정 파일 내용이다)
http {
server {
listen 80;
server_name ~.;
root [프로젝트 폴더이름];
location / {
try_files $uri @app;
access_log off;
}
location /favicon.ico {
deny all;
log_not_found off;
access_log off;
}
location @app {
access_log /var/log/nginx/access.log;
include uwsgi_params;
uwsgi_pass unix:/home/ubuntu/[프로젝트 폴더이름]/uwsgi.sock;
uwsgi_max_temp_file_size 20480m;
uwsgi_buffering off;
uwsgi_ignore_client_abort on;
uwsgi_buffers 2560 160k;
uwsgi_buffer_size 2560k;
uwsgi_connect_timeout 30s;
uwsgi_send_timeout 30s;
uwsgi_read_timeout 30s;
uwsgi_busy_buffers_size 2560k;
uwsgi_temp_file_write_size 2560k;
proxy_read_timeout 30s;
proxy_connect_timeout 75s;
}
}
-> 여기서 우선 다시 서버 실행이 잘되나 확인해 주었는데 자꾸 에러가 났다.
한참 헤맸는데 잘 살펴보니 이전에 실수로 다른 로직에 설치해준 uwsgi가 실행으로 잡히더라
detected binary path: /home/ubuntu/.local/bin/uwsgi
이렇게 추론하게 된 이유가, 가상환경에 다 있는 모듈들인데도 불구하고 자꾸 못찾는다는 에러가 나고 있었기 때문이다.
따라서 해당 uwsgi 를 삭제해주고
conda update -n base -c defaults conda
위의 명령어를 실행해준 다음에 아래 명령어를 설정하면 현재 실행되고 있는 uwsgi를 알 수 있다.
which uwsgi
이렇게 하고 다시 서버를 실행하니 성공...후 다행이다...그럼 이제 다시 proxy 설정부터 차근차근진행했다.
sudo service nginx restart
e. ACM으로 SSL 인증서 발급 후, Route 53으로 ELB와 연결 해준 후에 다시 nginx.conf 파일 내용을 변경해 주어야 한다.
http {
server {
"기존과 동일"
if ($http_x_forwarded_proto != "https") {
return 301 https://$host$request_uri;
}
location / {
"기존과 동일"
}
location @app{
"기존과 동일"
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 30s;
proxy_connect_timeout 75s;
proxy_pass http://127.0.0.1:5000;
proxy_redirect off;
}
}
-> 즉 proxy 관련 내용들을 location @app에 추가해주었다.
-> 이는 무조건 적인 정답은 아니고, 우리프로젝트에서는 이렇게 해준 이유가 location/ 에서 바로 try_files $uri @app; 해당 코드를 통해
바로 location @app으로 이동되고, 이 곳에서 uwsgi와 연결되어 처리해주기 때문이다.
-> 보통 구글에서는 일반적으로 location / 내에 설정하는 사람들도 많던데, 우리 서버 통신 특성으로 다른 곳에 설정사항을 기재했다.
그리고 아래의 명령어로 nginx 를 다시 시작해주자(환경 파일을 변경해주었기 때문에)
sudo service nginx restart
그 다음에 아래 명령어를 실행하면 서버가 실행되고, 우리가 만든 도메인 주소를 입력하면 우리가 만든 프로젝트로 인입되는것을 확인할 수 있다. (여기서 나는 이해를 잘못해서 실수로 protocol 명령에 https 를 입력했고, 계속 실행되지 않았다. 그런데 nginx.conf 파일에서 http listen 으로 설정해주었기 때문에 시작도 http로 해야 한다,)
-> 이에 대해서는 해당 글에서 http : 80으로 들어가는 경우 https: 443으로 리다이렉트 되도록 설정해 주었다.
uwsgi --socket 0.0.0.0:5000 --protocol=http -w [서버가 최초로 실행되는 파일]:app
ex) uwsgi --socket 0.0.0.0:5000 --protocol=http -w manage:app
그리고 현재 서버 실행 확인 하는 명령어는 아래의 명령어이다
netstat -tlpn
'DevOps' 카테고리의 다른 글
CI/CD란? (0) | 2022.03.01 |
---|---|
docker VS kubernetes (0) | 2022.02.25 |
Deploy_AWS Route 53 / ACM으로 SSL 인증서 발급받기 (0) | 2021.01.14 |
Deploy_DNS(Domain Name System)를 이해하고 사용하기 (0) | 2021.01.14 |
AWS - Elastic Load Balancer(ELB) (0) | 2021.01.06 |