일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- self-signed
- 네이버카페
- ue4dumper
- Frida
- 안전결제
- 보이스피싱 #대검찰청 #명의도용 #비밀번호 #계좌번호 #공공기관 #가짜검찰청
- 거래사기
- 허리디스크
- react
- 중고나라
- 변태는
- shell_gpt
- open redirect
- speed-measure-webpack-plugin
- XSS
- 척추관협착증
- MongoDB #NoSQL #CreateUser #DropUser #mongod #mognod.conf
- intelmac
- 모의해킹
- 취약점
- Sequoia
- CJ대한통운 #쿠팡 #통관번호오류 #통관고유번호오류 #안주원팀장 #모건인베스트
- Malware Sample
- 채팅환전사기
- 많다..
- ssrf
- CryptoJS
- NUGU
- 로맨스스캠
- esbuild
- Today
- Total
annyoung
Ubuntu Apache wsgi with Python3.7.5, Flask and Virtualenv 본문
Devops 삽질기...
위 이미지를 보면 아무것도 안한 상태의 Ubuntu Apache는 wsgi python을 2.7.x로 로드한다.
현재 주어진 개발 환경은 3.7.x의 virtualenv를 사용해야 하므로 3.7.x로 컴파일된 wsgi를 사용해야 한다.
wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.5.tar.gz
tar xvf 4.6.5.tar.gz
cd mod_wsgi-4.6.5
./configure --with-python=/usr/bin/python3.7
make
make install
configure에서 Python.h가 없다고 에러가 나는 경우엔 apt-get install python3.7-dev를 하도록 한다.
wsgi가 설치 되었으므로 이제 apache.conf에 LoadModule을 넣어줄 차례다.
/etc/apache2/apache.conf의 맨 마지막 줄에 LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so 를 추가 하도록한다.
추가한 후에 VirtualHost를 추가해줘야 하므로 /etc/apache2/sites-available로 이동한다.
필자는 ssl을 적용시킬 예정이므로 다음과 같이 000-default.conf를 수정하도록 하겠다.
SSL Redirection을 사용하는 경우
# 000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName localhost
ServerAlias localhost.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.localhost.com [OR]
RewriteCond %{SERVER_NAME} =localhost.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
localhost를 자신의 도메인으로 수정하도록 한다.
#default-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName localhost
ServerAlias localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/mysite/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mysite/privkey.pem
WSGIDaemonProcess myapp user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/onland/app.wsgi
Alias /static/ /var/www/onland/app/static/
<Directory /var/www/onland>
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
</IfModule>
SSL Redirection을 사용하지 않는 경우
# 000-default.conf
<IfModule mod_ssl.c>
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName localhost
ServerAlias localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIDaemonProcess myapp user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/onland/app.wsgi
Alias /static/ /var/www/onland/app/static/
<Directory /var/www/onland>
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
</IfModule>
현재 프로젝트의 디렉토리 구조
onland
├── app
│ ├── __pycache__
│ ├── admin
│ │ └── __pycache__
│ ├── api
│ │ ├── __pycache__
│ │ └── parser
│ │ ├── MonthlySeries
│ │ │ └── __pycache__
│ │ ├── WeeklySeries
│ │ │ └── __pycache__
│ │ └── __pycache__
│ ├── login
│ │ └── __pycache__
│ ├── main
│ │ └── __pycache__
│ ├── register
│ │ └── __pycache__
│ ├── static
│ │ ├── css
│ │ └── js
│ └── templates
│ └── __init__.py
├── assets
│ ├── js
│ └── sass
├── app.wsgi
└── myapp.py
전체적인 디렉토리 흐름인데 내 프로젝트의 경우 app.wsgi가 myapp을 참조하고 myapp은 app 디렉토리의 __init__.py에서 create_app 함수를 가져와 app 객체를 생성한다. 더 쉽게 보고싶다면 https://github.com/miguelgrinberg/flasky를 확인해보면 알기 쉬울 것이다.
# app.wsgi
import sys
sys.path.insert(0, '/var/www/onland')
python_home = '/var/www/onland/virtualenv'
activate_this = python_home + '/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
from myapp import app as application
app.wsgi는 위와같이 넣어주면된다.
1~2번 라인은 환경변수를 집어넣어주고.
4~7번 라인은 virtualenv의 경로를 집어 넣어주는 부분이다.
9번 라인은 myapp라는 python 파일에서 app 객체를 import 하고 application이라고 로드한다. (wsgi 규약상 무조건 application라고 써야한다.)
# virtualenv/bin/activate_this.py
import sys
import site
python_home = '/var/www/onland/virtualenv'
python_version = '.'.join(map(str, sys.version_info[:2]))
site_packages = python_home + '/lib/python%s/site-packages' % python_version
site.addsitedir(site_packages)
prev_sys_path = list(sys.path)
site.addsitedir(site_packages)
new_sys_path = []
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
app.wsgi에서 activate_this.py라는 virtualenv wrapper를 실행하도록 되어 있는데 위 행동은 환경 변수에 virtualenv site-packages를 추가해주는 역할을 한다.
# myapp.py
from app import create_app
app = create_app()
myapp.py는 app 디렉토리의 __init__.py에서 create_app 함수를 가져와 Flask app 객체를 리턴받는다.
# app/__init__.py
import os
from flask import Flask
from flask_restful import Api
def create_app():
app = Flask(__name__)
app.secret_key = '1234' or os.urandom(24)
api = Api(app)
# Add login views
from .login import login as login_blueprint
app.register_blueprint(login_blueprint)
from .api import Login, Register, Logout
api.add_resource(Login, '/api/login')
api.add_resource(Register, '/api/register')
api.add_resource(Logout, '/logout')
return app
위에서 언급한 미구엘씨가 작성한 flasky를 보면서 디렉토리 구조를 이해하면 훨씬 보기 편하다.
위와 같이 설정이 끝나면 service apache2 restart를 날려주면 적용 끝.
혹시나 안된다면 댓글을 달아주세요. 해결 해드리도록 하겠습니다.
Please add comment on this post when you got some errors.