apache wsgi, proxy, ssl 사용시 문의
안녕하세요?
저는 PHP 아마츄어 제작자인데, 2~3년전 부터 파이썬에 관심을 갖게되어
님의 저서를 비롯하여 몇 권의 서적을 뒤적이며 공부하게 되었고,
파이썬 프로그램에 익숙해 지고자 기존에 제작하여 운영중인 PHP 웹 프로그램을
플라스크를 사용하여 완전히 새로 만들었습니다.
localhost에서는 문제없이 작동하는데, 기존 PHP 웹 프로그램이 담겨있는
임대 서버에 올리는 것에서 몇 달을 소비하고 있습니다. (님의 저서가 apache를 예로 들었으면 좋았을텐데요.. ^^)
몇 달간 여러가지 난관을 거쳐오며, 이제 거의 해답 즈음에 다가선 것 같은데,
마지막 남은 문제는 파이썬 커뮤니티에서 찾아야 할 것 같습니다.
(국내에선 파이썬 질의응답 커뮤니티가 너무 부족하게 느껴져요..ㅠㅠ)
문의 드릴께요..
기존 웹서버는 아파치로 http://abc.com/~ 을 보내면 ssl이 적용되어 https://abc.com/~ (/var/www/html/) 에 있는
PHP 프로그램이 실행됩니다.
플라스크로 새로운 앱을 만들었고 위치는 (/var/www/py/) 입니다.
원하는 것은 url에 "/py/"를 붙일 경우(https://abc.com/py/~) apache proxy에서 5000번 포트로 연결하여
wsgi로 연결된 플라스크 앱이 실행되는 것입니다. 여기까지는 성공하였습니다만,
이후 플라스크 앱에서 리다이렉션 할 경우
http://abc.com/~ 을 호출하여 PHP 경로로 들어가서 오류가 나고,
"/py/"를 붙여야 진입하는 플라스크로 다시 돌아가지 않는다는 것 입니다.
플라스크에서 경로를 지정할 때 url 접두어로 "/py/"을 붙일 방법이 있을 것 같은데..... 모르겠네요..
참고로 http://abc.com:5000 으로 접속할 때는 localhost처럼 모든 플라스크 프로그램이 원활하게 작동합니다.
(https://abc.com:5000 은 안되는데, ssl을 사용해야 하므로 http:// 경로는 허용하지 말아야 합니다.)
아래는 제 소스입니다. 현재 운영중인 서버이므로 도메인은 abc.com으로 임의 수정해서 올립니다.
■ 디렉토리 구조
var
└ www
└ html : php 프로젝트 디렉토리
└ py : python 디렉토리
└ python : python 패키지 디렉토리
└ py : python flask 프로젝트
■ httpd.conf
Listen 443 # ssl.conf 내용
<VirtualHost *:443>
DocumentRoot "/var/www/html"
ServerName abc.com:443
ServerAdmin admin@abc.com
SSLEngine on # http:// -> https://
<Location /py>
ProxyPass http://abc.com:5000/ # abc.com/py/ -> abc.com:5000 (-> flask 프로세스)
ProxyPassReverse http://abc.com:5000/
</Location>
SSLProxyEngine on
SSLProtocol all -SSLv3
SSLCertificateFile "/usr/sbin/conf/ucert/abc.com.crt"
SSLCertificateKeyFile "/usr/sbin/conf/ucert/abc.com.key"
SSLCertificateChainFile "/usr/sbin/conf/ucert/abc.com_ChainBundle.crt"
SSLCACertificateFile "/usr/sbin/conf/ucert/ADDTRUST_EXTERNAL_CA_ROOT.crt"
</VirtualHost>
Listen 80 # httpd.conf 내용
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot /var/www/html
ServerName abc.com # http://abc.com -> https://abc.com -> /var/www/html/ 경로의 php 프로세스 실행
ServerAlias www.abc.com # http://www.abc.com -> https://abc.com -> /var/www/html/ 경로의 php 프로세스 실행
php_flag register_globals on
ProxyRequests Off
ProxyPreserveHost On
<Location /py> # http://abc.com/py/ -> https://abc.com/py/ -> abc.com:5000 -> /var/www/py/ 경로의 flask 프로세스 실행
ProxyPass https://abc.com:5000/
ProxyPassReverse https://abc.com:5000/
</Location>
</VirtualHost>
Listen 5000
<VirtualHost *:5000> # abc.com:5000 일 경우
ServerName py.abc.com
DocumentRoot /var/www/py
WSGIDaemonProcess py user=apache group=apache processes=5 threads=5 python-home=/var/www/py python-path=/var/www/py/bin:/var/www/py/lib64/python3.6/site-packages:/var/www/py/lib/python3.6/site-packages
WSGIProcessGroup py
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
WSGIScriptAlias / /var/www/py/py.wsgi # /var/www/py/ 경로의 flask app 가동
<Directory /var/www/py>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/py/py/static # flask에서 /static 의 경로는 /var/www/py/py/static bootstrap 및 css 파일 경로
<Directory /var/www/py/py/static>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
■ py.wsgi
import sys
sys.path.insert(0, "/var/www/py")
sys.path.append("/var/www/py/lib/python3.6/site-packages")
sys.path.append("/var/www/py/lib64/python3.6/site-packages")
from py import create_app
application = create_app()
■ flask login.py
from flask import Blueprint, render_template, request, session, redirect, url_for
from checker import check_logged_in #session['id']를 확인하여 로그인 유무 파악
from DBcm import UseDatabase, ConnectionError, CredentialsError, SQLError #데이타베이스 연동 모듈
bp = Blueprint('login',__name__,url_prefix='/')
log = Log()
@bp.route('/')
@bp.route('/login', methods=['POST', 'GET'])
def login() -> str:
if request.method == 'GET':
return render_template('/login.html')
elif request.method == 'POST':
user_id = request.form['id']
user_pw = request.form['pw']
with UseDatabase('dict') as cursor:
_SQL = f"""
select id,pw,admin_pw,secret,active,nickname,move_from
from user
where id='{user_id}' and (pw='{user_pw}' or admin_pw='{user_pw}')
"""
cursor.execute(_SQL)
row = cursor.fetchone()
if row is None:
return redirect('login')
else :
session['id'] = row['id']
if row['admin_pw'] == user_pw:
session['admin'] = True
else:
session['admin'] = False
return redirect('/main_list') #여기를 "/py/main_list"로 해도 안되더군요
return render_template('/login.html')
윤찬석 님 778
M 2022년 1월 10일 9:40 오전
3개의 답변이 있습니다. 1 / 1 Page
완전 해결 했습니다.
위의 댓글과 같이 버츄얼호스트를 수정해 주고,
파이썬 프로그램에서 redirect나 render_template 에서는 "/py/"를 붙이면 안됩니다.
하지만 template 폴더의 html 파일의
윤찬석 님
M 2022년 1월 11일 7:30 오후
여러가지 방법이 있네요.
다음을 참고해 보세요.
https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes
박응용 님
2022년 1월 10일 9:52 오전
일단 한가지 알아낸거
httpd.conf 버츄얼호스트에서 443 ssl 포트하고 80포트에
<Location /py> -> <Location /py/>
로 바꿔야 하네요.. 그리고 template 폴더 html 파일의
윤찬석 님
M 2022년 1월 10일 4:51 오후