ubuntu 환경에서 Flask 배포하기 (Github, uWSGI, Socket)
사전준비
패키지 매니징 툴 apt(Advance Packging Tools) 업데이트
$ sudo apt update
Git에서 소스코드 다운로드
1. Git 설치
$ sudo apt install git
2. Git 초기화
프로젝트를 시작하고 소스 코드를 Git으로 관리하고자 한다면 먼저 git init으로 저장소를 초기화 해야 한다. 저장소로 사용하고자 하는 디렉터리로 이동한 다음 git init을 실행한다.
$ git init
3. 소스코드 주소 복사
GIhub 홈페이지에서 가져올 프로젝트 주소 복사 (프로젝트 화면 > Code > Code > Clone > HTTPS)
4. git clone
$ git clone <복사한 소스코드 HTTPS 주소>
5. 복사된 소스코드 폴더로 이동
$ cd myproject
Flask 배포를 위해 필요한 패키지 다운로드
1. python 설치
~/myproject/$ sudo apt install python3-pip python3-dev python3-setuptools
2. ubuntu 빌드를 위한 패키지 설치
~/myproject/$ sudo apt install build-essential libssl-dev libffi-dev
Python 가상환경(Virtual Environment) 설정
1. venv 파이썬 패키지 다운로드
~/myproject/$ sudo apt install python3-venv
2. Flask 어플리케이션 위치에 'myproject_env' 가상환경 생성
: ~/myproject/$ python3 -m venv myproject_env
3. 가상환경 실행
: ~/myproject/$ source myproject_env/bin/activate
가상환경 실행 이후에는 앞에 (myproject_env)가 생성된다.
(myproject_env)user@host:~/myproject$
Flask 어플리케이션 설정
1. wheel 설치
WHL(Wheel) 파일은 Python의 휠 형식으로 저장된 배포 패키지 파일이다. pip 인스턴스에 wheel을 설치하여 패키지가 wheel 아카이브 파일이 없어도 설치될 수 있도록한다.
(myproject_env)user@host:~/myproject$ pip install wheel
2. Flask에 사용된 패키지 다운로드
아래의 reqirements.txt는 로컬에서 pip freeze > requirements.txt 로 패키지 리스트 파일을 생성한다.
(myproject_env)user@host:~/myproject$ pip install -r requirements.txt
3. uWSGI 설치
(myproject_env)user@host:~/myproject$ pip install uwsgi
Flask 어플리케이션 테스트
1. 어플리케이션 테스트를 위해 포트 5000에 대한 액세스 허용
(myproject_env)user@host:~/myproject$ sudo ufw allow 5000
2. app = Flask(__name__) 정의가 포함된 파일 실행
1) 파일로 구동하는 경우
(myproject_env)user@host:~/myproject$ python myproject.py
[myproject.py]
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:pink'>Hellow World</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
2) 모듈로 구동하는 경우
모듈의 __init__.py에 app = Flask(__name__) 가 정의된다.
[Project Sturcture]
.
├── myproject
├── __init__.py
├── function1.py
└── function2.py
└── run.py
이 경우에는 모듈을 run 하는 run.py 파일을 별도로 만들고, run.py를 실행한다.
(myproject_env)user@host:~/myproject$ python run.py
[run.py 예시]
# uwsg.py
from myproject import app
if __name__ == "__main__":
app.run()
3. 테스트 실행 결과 확인
[콘솔 Output]
# Output
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Serving Flask app 'myproject'
* Debug mode: off
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:5000
* Running on http://0.0.0.0:5000 (Press CTRL+C to quit)
서버 아이피를 포트 5000으로 접근하면 다음과 같은 화면을 확인 할 수 있다.
http://your_server_ip:5000
uWSGI 설정
1. WSGI 진입점(Entry Point) 생성
모듈로 Flask를 구동하는 경우 run.py가 Entry Point가 된다.
from myproject import app
if __name__ == "__main__":
app.run()
2. WSGI 테스트하기
(env) uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
서버 아이피를 포트 5000으로 접근하면 다음과 같은 화면을 확인 할 수 있다.
http://your_server_ip:5000
3. uWSGI 구성 파일 생성
:~/myproject$ sudo nano myproject.ini
[uwsgi]
module = run:app # run.py에서 app으로 정의된 항목이 모듈
master = true # master 모드에서 시작
processes = 5 # request를 처리하기 위해 작동할 프로세스 수
socket = myproject.sock # uWSGI와 웹 서버(예: Nginx) 간의 통신을 위한 소켓 파일의 경로
chmod-socket = 660 # 소켓 파일에 대한 퍼미션을 설정
vacuum = true # uWSGI 종료 시 생성된 소켓 파일을 자동으로 삭제하는 옵션
die-on-term = true
logger = file:/var/log/uwsgi/myproject.log # 로그 설정
log-4xx = true # 4xx 에러 로깅
log-5xx = true # 5xx 에러 로깅
env = FLASK_ENV=development # 환경변수 설정
systemd 서비스 등록(unit file 생성)
서버에 서비스를 등록하여 ubuntu 부팅시 uWSGI를 자동으로 시작하고, Falsk 어플리케이션을 서빙하도록 한다.
$ sudo nano /etc/systemd/system/myproject.service
[Unit] # 서비스의 전반적인 설정
Description = uWSGI instance to serve myproject # 서비스의 설명을 지정
After = network.target # 서비스가 network.target (네트워크 서비스) 이후에 시작되도록 설정
[Service]
User = ubuntu # 서비스를 실행할 사용자 계정을 지정
Group = www-data # 서비스를 실행할 때 사용할 그룹 지정
WrokingDirectory=/home/ubuntu/myproject # 서비스가 실행될 작업 디렉토리
# 서비스가 실행될 환경 변수 설정. 여기서는 가상 환경의 bin 디렉토리를 PATH에 추가
Environment="PATH=/home/ubuntu/myproject/myproject_env/bin"
# 서비스가 시작될 때 실행될 명령 지정
ExecStart=/home/ubuntu/myproject/myproject_env/bin/uwsgi --ini myproject.ini
[Install]
WantedBy=multi-user.target
우분투에서는 기본적으로 Nginx의 www-data 사용자가 홈 디렉토리의 파일을 읽을 수 없으므로 chgrp 명령어를 사용하여 홈 디렉토리와 관련된 그룹을 변경한다.
$ sudo chgrp www-data /home/ubuntu
uWSGI 시작
1. uWSGI 시작
:~/myproject$ sudo systemctl start myproject
:~/myproject$ sudo systemctl enable myproject
2. uWSGI 재시작
:~/myproject$ sudo systemctl restart myproject
3. uWSGI 상태 확인
:~/myproject$ sudo systemctl status myproject
Nginx 프록시 구성
Nginx를 프록시로 구성하려면, Nginx 설정파일에서 새로운 서버 블록을 생성해야 한다.
$ sudo nano /etc/nginx/sites-available/myproject
아래와 같이 서버 블록을 설정한다. 해당 서버 블록은 Nginx가 포트 80에서 요청을 수신해서 uwsgi_pass 경로의 소켓 파일로 요청을 전달하고, 서버의 도메인 이름에 대한 요청에 해당 블록을 사용하도록 정의한다.
server{
listen 80;
server_name your_domain;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/ubuntu/myproject/myproject.sock;
}
}
방금 만든 Nginx 서버 블록 구성을 활성화 하기 위해 해당 파일을 sites-enabled 디렉토리에 링크한다.
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Nginx를 설치하면, 프로세스는 sites-available 디렉토리에 default라는 서버 블록 구성 파일을 자동으로 설정하고, 그 파일과 sites-enabled 디렉토리 사이에 심볼릭 링크를 만든다. 이 심볼릭 링크를 그대로 둘 경우, 기본 설정으로 인해 사이트가 로딩되지 않으므로 다음 명령어로 이 링크를 제거한다.
$ sudo unlink /etc/nginx/sites-enabled/default
Nginx 재시작
1. Nginx syntax error 확인
sudo nginx -t
2. Nginx 재시작
$ sudo systemctl restart nginx
어플리케이션 HTTPS 적용
서버로의 트래픽이 안전하게 유지되도록, 도메인에 대한 SSL 인증서를 얻어야 한다. Let's Encrypt에서 무료 인증서를 얻어서 적용 할 수 있다.
1. Certbot과 Certbot의 Ningx 플러그인 설치
$ sudo apt install certbot python3-certbot-nginx
2. Cerbot을 사용한 SSL 인증서 적용
$ sudo certbot --nginx -d your_domain -d www.your_domain
3. HTTP를 통한 접근 차단
$ sudo ufw delete allow 'Nginx HTTP'
🐬 참고
'# Development > DevOps' 카테고리의 다른 글
[Nginx] Ubuntu Nginx SSL 인증서 설정하기 (HTTPS 연결) (0) | 2023.07.07 |
---|---|
[Nginx] Header Server 정보 수정하기, 지우기 (0) | 2023.06.28 |
[Nginx] Nginx란 무엇인가? (0) | 2023.02.14 |
[WSGI] WSGI란? (0) | 2023.02.13 |