nginx에서 flask로의 proxy pass (reverse proxy)

2019. 11. 20. 09:23Programming/Server

반응형

가볍고 속도가 빠른 Nginx를 메인으로 사용하고, 실제 API등의 처리는 호환성 및 라이브러리가 다양한 Flask를 사용하는 환경을 구축하게 됐다. 두 개의 서버가 돌아가고 있는 상황인데, 외부에서 Flask에 직접 설정할 수 없도록 로컬 포트를 할당해준다. 그리고 Nginx의 특정 패스로 접근하면, Flask로 proxy pass하여 Flask에서 내용을 처리하도록 설정한다.

우선은 Flask 샘플코드를 사용하여, 정상적으로 실행되는지 확인하자. 아래의 코드는 Flask의 특정 경로로 접근할 시, Plain text를 반환하는 코드이다.

from flask import Flask

app = Flask(__name__)

@app.route('/hi')
def hi():
 return 'hi!'

@app.route('/hello')
def hello():
 return 'hello!'

app.run(host='0.0.0.0', port='5000')

/hi로 접근하면 hi!를, /hello로 접근하면 hello!를 반환하는 Flask 샘플코드.

http://<server ip>:5000/hi를 요청하면 hi!가, http://<server ip>:5000/hello를 요청하면 hello!가 반환되는 샘플코드다. 현재는 외부포트에 바인딩했기 때문에 외부에서 직접 접속이 가능하다. 제대로 실행됐는지 확인해보자. 별다른 이상이 없다면, 브라우저에 hi!hello!가 출력되는 것을 확인할 수 있다. 여기까지 진행이 완료됐다면 로컬바인딩으로 변경하도록 하자. 로컬바인딩으로 변경하기 위해선 app.run(host='0.0.0.0', port='5000')로 설정한 값을 app.run(host='127.0.0.1', port='5000')로 변경하면 된다. 내부포트로 설정됐다면 동일하게 요청했을 때, HTTP 상태 코드값이 404로 반환된다. 여기까지 Flask의 설정은 끝.

다음은 nginx의 설정이다. nginx에 /flask/라는 경로로 요청이 들어올 경우, 이 요청에 대한 처리는 flask에게 넘길 것이다. 이를 위해서는 nginx의 server설정에 다음과 같이 location설정을 추가해주면 된다.

location /flask/ {
 proxy_pass http://127.0.0.1:5000;
}

/flask 경로로 들어온 요청에 대한 처리는, Flask에게 떠넘긴다.

이제 nginx를 실행시키고, http://<server ip>:<port>/flask/hi를 입력해보자. 아마 HTTP 상태 코드가 404로 반환될 것이다. Flask의 콘솔을 확인해보자.

* Running on http://127.0.0.1:5000/ (Press CTRL+C >to quit)
127.0.0.1 - - [02/Jan/1970 02:16:02] "GET /flask/>hi HTTP/1.0" 404 -

Flask로 요청이 proxy pass되긴 했는데, 경로가 /hi가 아닌 /flask/hi로 되어있다.

경로가 아무래도 이상하다. Nginx에게 /flask/hi로 요청했으니 Flask에게 /hi로 요청이 들어갈것으로 기대했지만, Nginx가 요청받은 경로 전체를 Flask에게 전달했기 때문에 이러한 일이 발생한 것이다.

Nginx의 proxy pass설정에 다음과 같이 rewrite구문을 추가하여, /flask/hi로 전달되는 경로에서 /flask를 지워주도록 하자.

location /flask/ {
 rewrite ^/flask(/.*)$ $1 break;
 proxy_pass http://127.0.0.1:5000;
}

/flask로 경로가 전달되면, /flask의 내용을 /flask 뒤에 따라오는 내용으로 재작성하겠다는 rewrite구문을 추가해준다.

설정파일을 저장하고 Nginx를 다시 실행한 뒤, 다시 한 번 http://<server ip>:<port>/hi로 요청해보자. hi!가 출력되는 것을 확인할 수 있다. 이렇게 간단하게 proxy pass의 설정이 가능하다.

Flask를 사용했지만 사실 다른 서버를 사용하더라도, 동일하게 proxy pass를 설정하여 nginx로 들어오는 요청에 대한 처리를 다른 서버에게 위임할 수 있다. :)

반응형