[졸프] ⚗️Flask 웹 서버 호스팅

HaJingJing·2021년 5월 4일
1

졸업 프로젝트 서버 구조

Uwsgi

  • Wsgi는 수많은 request를 다룰 수 있도록 설계된 webserver 전용 인터페이스
  • uWsgi는 Wsgi의 한 종류로 호스팅 서버를 구축할 수 있게 full stack을 지원함
  • uWsgi는 python 기반의 웹프레임워크와 호환성이 좋음
  • uWsgi를 사용하면 개발 속도를 올려주고, stack components들을 유연하게 바꿀 수 있음

Nginx

  • 경량 웹서버로, request에 맞는 static file을 응답해주는 HTTP web server로 활용됨
  • 이외에도, Reverse Proxy Server을 활용하여 WAS 서버의 부하를 줄이는 로드 밸런싱 기능도 가지고 있음

이 2가지를 이용하여 github에 올려놓은 코드를 기반으로 서버를 AWS에 호스팅 해보겠다.

서버 코드 : https://github.com/Kim-Ha-Jeong/Capstone_flask

1. EC2 인스턴스 생성 및 설정

프리티어 고르기 - Ubuntu 18.04
보안 그룹은 기존그룹을 선택한 후에 나중에 수정해주면 된다
키 페어 생성 후, 다운로드 받은 후 인스턴스를 시작할 수 있다.

인스턴스 설정 후 자동으로 뜨게 되는데 웬만하면 하는 걸 권장드린다..
이거 안했다가 과금 물었다ㅠ

대시보드를 보니, 인스턴스가 실행 중인 것을 알 수 있다.

보안 그룹에 가서 보안 그룹을 수정한다.
연결할 포트번호(5001)을 입력해준다.

외부 연결이 가능하게 하려면 ssh 22번 포트가 반드시 열려 있어야만 한다.

2. Windows Terminal을 이용한 환경 설정

windows terminal을 열고 밑 명령어를 입력해주면

ssh -i "*.pem의 위치" ubuntu@할당된 인스턴스.ap-northeast-2.compute.amazonaws.com

결과창이 나오면, 외부에서 ec2 인스턴스에 연결이 된 것을 확인할 수 있다.

앞으로의 진행 순서이다.

1) mysql 설치
2) pip 설치
3) git 설치
4) nginx 설치
5) uwsgi 설치

1) mysql 설치

sudo apt update # 업데이트
sudo apt install mysql-server #mysql 서버 설치

100% 설치가 되었다면, mysql에 접속해본다

sudo mysql -u root -p #접속

처음이라서 비밀번호가 걸려있지 않다.

다른 user를 만들어서 비밀번호를 걸어줘도 되지만, root에 비밀번호만 걸어줄 것이다.

alter user 'root'@'localhost' identified with mysql_native_password by '비밀번호'; # root 비밀번호 변경
flush privileges; # 변경 권한 저장

mysql 8.0 이상만 이 명령문이 실행된다.

나갔다가 다시 비밀번호를 입력하고 들어오니 잘 작동하는 것을 확인할 수 있다.

2) python & pip 설치하기

python --version
# 3.6.9

sudo apt install -y python3-pip
# pip을 설치함

기존 우분투에는 python 3.6.9가 기본적으로 깔려져 있다.
추가로 pip을 설치한다.

3) git 설치

sudo apt install git # git 다운로드
git --version # git version

이미 git이 설치되어 있는 것을 볼 수 있다.

4) nginx 설치

sudo apt-get install nginx # nginx 다운로드

nginx를 다운로드 한다.

5) uwsgi 설치

sudo apt-get install uwsgi # uWSGI
sudo apt-get install uwsgi-plugin-python3 #python uWSGI를 연결하는 플러그인

uwsgi와 기존에 있는 python과 연결해줄 plugin을 다운로드 한다.

3. 깃허브에 올렸던 기존 코드 동작시키기

1) github 주소에 있는 코드 다운로드
2) 폴더 만들기 & 가상환경 만들기
3) mysql에 database & table 만들기
4) nginx 설정
5) uwsgi 설정

1) github 주소에 있는 코드 다운로드

git config --global user.name {username}
git config --global user.mail {email}

자신의 깃헙 이름과 이메일을 괄호 안에 입력하면, 이후에 커밋할 때 그 이름으로 커밋이 들어가게 된다.

cd /var/www
git clone {깃헙 주소} # 깃헙 주소에 있는 코드 다운로드

다운로드 받고 싶은 깃헙 주소를 괄호 안에 입력하고 git clone 해주면 ubuntu 내에 그 코드가 담긴 폴더가 생성된다.

2) 폴더 만들기 & 가상환경 만들기

cd Capstone_flask
mkdir -m 777 output # 모든 권한 허용하는 dir 만들기
mkdir -m 777 input # 모든 권한 허용하는 dir 만들기


두 개의 폴더가 잘 생성된 것을 볼 수 있다.

sudo apt install virtualenv # 가상환경 설치
virtualenv -p python capstone # capstone이라는 가상환경 만들기
source capstone/bin/activate # 가상환경 활성화

잘 활성화되면 (가상환경명)이 앞에 뜨게 된다.

pip3 install -r requirements.txt 
# requirements.txt에 정리되어 있는 라이브러리 설치

코드가 돌아가는 데 필요한 라이브러리를 모두 설치해준다.

흐음...! 망했다! 가상환경은 설치가 잘 안된다 가상환경을 버리고 그냥 pip에다가 하나씩 다운로드 하도록 하자..!

pip3 install (module 이름)

하면 웬만하면 깔리는데 가끔 에러나는 놈들 몇 개만 가져와 보겠다

# module not found 'cv2'
pip3 install opencv-python

# ImportError: libSM.so.6: cannot open shared object file: No such file or directory
sudo apt-get update
sudo apt-get install -y libsm6 libxext6 libxrender-dev
pip3 install opencv-python

# pip install이 killed라는 문구가 뜨며 중단될 때
pip3 install tensorflow --no-cache-dir

# pip install grpcio에서 멈출 때 (너무 오래동안 돌아갈 때)
pip3 install --upgrade pip
pip3 install --upgrade setuptools
pip3 install tensorflow

내가 해결한 문제는 요 정도이다.

3) mysql에 database & table 만들기

mysql -u root -p # mysql 접속

CREATE DATABASE `magicbox_flask`;
USE `magicbox_flask`;

CREATE TABLE `user` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `email` VARCHAR(255) NOT NULL unique,
  `password` VARCHAR(32) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `email_UNIQUE` (`email` ASC)
  );

CREATE TABLE `full` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `full_video` VARCHAR(50) NOT NULL,
  `date` DATETIME NOT NULL,
  `size` VARCHAR(45) NOT NULL,
  `storage_path` VARCHAR(250) NOT NULL,
  `user_id` INT NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`user_id`)
  REFERENCES `magicbox_flask`.`user` (`id`)
  ON DELETE CASCADE
  ON UPDATE CASCADE
  );

CREATE TABLE `edited` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `edited_video` VARCHAR(50) NOT NULL,
  `date` DATETIME NOT NULL,
  `size` VARCHAR(45) NOT NULL,
  `path` VARCHAR(250) NOT NULL,
  `part` INT NOT NULL,
  `user_id` INT NOT NULL,
  `full_id` INT NOT NULL,
  PRIMARY KEY (`id`, `full_id`),
  FOREIGN KEY (`user_id`)
  REFERENCES `magicbox_flask`.`user` (`id`)
  ON DELETE CASCADE
  ON UPDATE CASCADE,
  FOREIGN KEY (`full_id`)
  REFERENCES `magicbox_flask`.`full` (`id`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
  );

저번에 써서 저장해놓았던 쿼리문을 넣으면 mysql에 데이터베이스와 테이블을 만들 수 있다.

4) nginx 설정

cd /etc/nginx/sites-available
sudo vi capstone # config 파일 생성

해당 디렉토리로 이동 후, config 파일을 생성해준다.

server {
        listen 80;
        server_name localhost;
        root /var/www/Capstone_flask;

        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:/tmp/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;
        }
}

config 파일 안에, nginx가 동작하는 정보를 입력한다.

현재는 localhost에 있는 소스를 사용할 예정이니 server_name 옆에 localhost를 입력한다.

sudo ln -s /etc/nginx/sites-available/capstone /etc/nginx/sites-enabled
# 심볼릭 링크 걸어줌
sudo rm /etc/nginx/sites-enabled/default
# 이미 있던 default 파일 지움
sudo service nginx restart 
# 다시 시작

아직 uwsgi, 코드와 연결을 하지 않아서 bad gate가 나온다.

5) uwsgi 설정

cd /var/www/Capstone_flask
sudo vi wsgi.py

내 프로젝트와 uwsgi를 연결시키는 wsgi.py를 생성한다.

# wsgi.py

from app import app
# from app --> run 하는 py파일 이름 
# import app --> Flask(__name__)한 객체 이름

if __name__ == "__main__":
	app.run()

첫번째 app은 구동하는 py파일 이름이고, 두번째 app은 그 파일 안에서 쓰인 객체 이름이다.

cd /etc/uwsgi/apps-available
sudo vi uwsgi.ini # uwsgi를 동작하기 위한 옵션을 정리한 파일

uwsgi를 동작하기 위한 옵션을 정리한 파일인 uwsgi.ini를 만든다.

[uwsgi]
chdir = /home/ubuntu/Capstone_flask/ # 현재 프로젝트 폴더 위치
callable = app # Flask(__name__)한 객체 이름
plugin = python3 # plugin한 python 버전
module = app # run 하는 py파일 이름
master = true
processess=5
threads=3
socket = /tmp/uwsgi.sock # sock 파일 위치
chmod-socket = 666
vaccuum =  true
die-on-term = true
ignore-sigpipe = true
ignore-write-errors = true
disable-write-exception = true

이 중 주석이 달려져 있는 것은 사람마다 다르게 적용할 옵션들이다. 주석을 보고 참고하여 잘 바꿔보도록 하자..!

sudo ln -s /etc/uwsgi/apps-available/uwsgi.ini /etc/uwsgi/apps-enabled/
sudo service uwsgi restart
sudo service uwsgi reload

cd /etc/uwsgi/apps-available
uwsgi uwsgi.ini & # uwsgi.ini을 백그라운드에서 실행함

심볼릭 링크를 설정해주고, restart, reload 해 준다.

그 후, uwsgi.ini 파일이 있는 곳으로 이동한 후, uwsgi.ini를 백그라운드에서 실행하여 내가 터미널을 닫아도 꺼지지 않게 만든다.

sudo nginx -t
sudo service nginx restart

마지막으로 아까 연결해놓은 nginx를 다시 시작해주면, nginx와 uwsgi, 프로젝트가 연결되어 굴러가게 된다.

4. 결과

잘 나오는 것을 볼 수 있다!..
웹 서버 호스팅 성공~!

5. 연결 시도

Postman이나 Android에서 연결을 해보았을 때, 로그인 회원가입과 같이 작은 데이터들을 주고 받는 데에는 문제가 없었다.
하지만, 동영상을 올리고 영상 처리를 진행하는 과정에서 자꾸 꺼졌다.

[Error #28] : No space left on device

이 에러는 AWS 자체의 디스크 크기를 늘려야 해결되었다.

또한, 영상처리하는 과정에서 시간이 너무 오래걸리거나, 서버가 아예 먹는 경우가 생겼는데 이는 CPU 성능이 좋지 않아서 생기는 일이었다...😥

1. 디스크(볼륨) 확장


1) 인스턴스 아이디(빨간 부분)를 누르면, 인스턴스의 세부 정보 페이지가 나온다.

2) 세부 정보 페이지에서 밑으로 스크롤 한 뒤, '스토리지'를 클릭한다.
3) 스토리지 클릭하면 나오는 볼륨 ID(빨간 부분)을 클릭한다.

4) 볼륨 ID에 오른쪽 버튼을 클릭한 후, 볼륨 수정을 클릭한다.

5) 볼륨 유형과 크기를 조절한 후, 수정을 누르면 인스턴스의 볼륨 설정이 수정된다.

2. CPU 교체

1) 인스턴스 오른쪽 마우스 클릭 > 인스턴스 설정 > 인스턴스 유형 변경 으로 들어간다.

2) 인스턴스 유형을 눌러 원하는 인스턴스 종류를 선택한 후, 적용을 누르면 인스턴스의 CPU가 바뀐다.

2가지를 수정한 후, POST도 잘 받아지고 영상 처리도 잘 되는 것을 볼 수 있었다...

하지만, 프리티어가 아니어서 돈을 내야한다..😭
역시 돈이 최고다🤑

여담이지만
한 2시간 테스팅 했는데, 벌써 1000원 정도 과금 나왔다..😣

profile
🌱초보 개발자🌱

1개의 댓글

comment-user-thumbnail
2022년 6월 13일

플라스크 실행시 텐서플로우가 돌아가는데 uwsgi uwsgi.ini & 실행시 서버가 멈춰버립니다. 어떻게 동작하였나요?

답글 달기