• HJ
    ActionMaskTech. Blog
Information
  • About
Blog
  • 전체
    13
  • AI
    3
  • Project
    5
  • Tip
    5
  • Tag
  • Github
  • RSS
  • ©2025 ActionMask. All Rights Reserved.
  1. Home

Python Flask를 위한 Gunicorn + NGINX 설정 방법

Ubuntu에서 Flask 어플리케이션을 Nginx와 Gunicorn을 이용해 서빙해보자.
Tip
2024-08-24 13:46
8분

linux
ubuntu
tip
gunicorn
flask
python
nginx
In this article
  • 개요
  • Gunicorn 설치
  • 시스템 서비스 설정
  • NGINX 설정
  • 마무리

Information
Ubuntu 환경 (Debian 리눅스) 기준 가이드입니다.

개요

WSGI(Web Server Gateway Interface)는 웹서버와 어플리케이션이 통신하기 위한 인터페이스입니다. 웹서버의 요청을 어플리케이션으로 전송해주는 역할을 합니다.
Gunicorn은 Python 어플리케이션을 위한 WSGI입니다. Flask 프레임워크로 작성된 어플리케이션을 웹서버와 통신을 하기 해서 서비스를 안정적으로 서빙할 수 있도록 해줍니다.

Warning
본 가이드는 Python 가상환경이 세팅되어 있는 것을 기반으로 합니다.

Python 가상 환경은 프로젝트 폴더에서 python3-venv 패키지를 통해 아래와 같은 명령어로 세팅할 수 있습니다. 이외에도 가상 환경은 Conda와 같은 패키지를 이용할 수 있으며, Docker와 같이 독립적인 컨테이너 환경을 기반으로 작업해도 무방합니다.

python3 -m venv [가상환경저장폴더]

Gunicorn 설치

Flask 어플리케이션이 작성되어 있다면, 동일 가상환경에서 gunicorn 패키지를 설치합니다.

(venv) $ pip install gunicorn

만일, flask 어플리케이션의 이름이 project라고 가정합니다. 프로젝트 폴더의 구조는 다음과 같습니다.
참고로, __init__.py 파일을 이용하여 패키지 디렉토리 구조로 구성하는 것을 추천합니다. 파이썬에서 패키지로써 인식되도록 하는 특별한 파일입니다. 이 파일은 해당 디렉토리가 패키지임을 나타내며, 패키지를 초기화하는 데 사용될 수 있습니다.

project
├── project
│   ├── __init__.py
│   ├── static
│   ├── templates
│   └── views
├── venv
├── requirements.txt
└── wsgi.py

다음과 같이 프로젝트 루트 폴더에 wsgi.py 파일을 작성합니다.

# wsgi.py 파일
from project import app
 
if __name__ == "__main__":
    app.run()

시스템 서비스 설정

gunicorn 패키지 설치와 시작 파일이 작성되었다면 다음과 같이 동작 여부를 테스트해 볼 수 있습니다.
5000번 포트로 테스트 설정해봅니다. (방화벽이 설정되어 있다면 외부에서 접속 시 방화벽에서 포트를 열어줘야 합니다.)

# 프로젝트 루트 폴더에서 수행 (가상환경 활성화 후)
(venv) $ gunicorn --bind 0.0.0.0:5000 wsgi:app

아래와 같은 결과를 볼 수 있습니다.

Output
[2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4
[2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419)
[2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync
[2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

웹 브라우저에서 http://localhost:5000 또는 http://127.0.0.1:5000 주소로 접속해서 flask 웹 어플리케이션이 정상적으로 동작하는지 확인합니다.

Ctrl + C로 서비스를 중단하고, 시스템 서비스를 등록해줍니다.

이제, 아래와 같이 시스템 파일을 등록해줍니다.

sudo vi /etc/systemd/system/[서비스이름].service
[Unit]
Description=[서비스 설명]
After=network.target
 
[Service]
User=ubuntu # 사용자 계정
Group=www-data # NGINX 계정 그룹
WorkingDirectory=/var/www/[프로젝트 명]/flask # 웹 어플리케이션 루트 패스
Environment="PATH=/var/www/[프로젝트 명]/flask/venv/bin" # Python 가상 환경 실행파일 패스
ExecStart=/var/www/[프로젝트 명]/flask/venv/bin/gunicorn --workers 3 --preload --bind unix:/tmp/[소켓이름].sock -m 007 wsgi:app
 
# OOM 등 상황 대비하여 자동 재시작 설정
Restart=always
RestartSec=5
TimeoutStopSec=20
KillMode=process
SuccessExitStatus=SIGKILL
MemoryMax=2G
OOMScoreAdjust=-500
 
[Install]
WantedBy=multi-user.target

설정 내용에서 ExecStart 부분의 설명을 좀 더 덧붙이자면, 아래와 같습니다.

--worker 3 gunicorn의 워커 수를 3개로 지정한다는 의미입니다.
일반적으로 workers = 2 * CPU 코어수 + 1와 같은 공식을 적용합니다. 예를 들어, 4코어 CPU라면 권장값은 9개입니다. 하지만, 이 공식은 단순한 I/O 바운드 웹 앱 기준이고, 메모리 사용이 높은 서비스에는 적절하지 않을 수 있습니다.
서버 환경에 맞춰서 적정한 수치로 조정하길 권장합니다.

Gunicorn은 기본적으로 워커마다 앱을 개별로 로딩합니다. --preload 옵션을 사용하면 마스터 프로세스에서 한 번만 모델을 로드하고, 이를 fork() 방식으로 자식 워커들에게 전달합니다. 이 옵션으로 오히려 빠른 응답성과 메모리 효율성이 향상될 수 있습니다.
하지만, 이 옵션은 multiprocessing을 사용하거나 대형 AI 모델을 탑재하는 경우 사용이 권장되지 않습니다.

옵션 마지막 부분은 유닉스 소켓 파일을 생성하고 바인딩 하는 부분입니다. 소켓 파일에 대해 umask를 007로 세팅 (소유자와 그룹에 접근 권한 부여)합니다.

이제 서비스를 등록하고 시작합니다.

sudo systemctl start [서비스명]
sudo systemctl enable [서비스명]

아래 명령어를 통해 서비스의 상태를 확인할 수 있습니다.

sudo systemctl status [서비스명]

또는

sudo service [서비스명] status

NGINX 설정

이제 NGINX 가상 호스트 설정을 해줍니다. HTTP 통신만 가정하겠습니다.

먼저 아래와 같이 가상 호스트 설정 파일을 만들어 줍니다.

sudo vi /etc/nginx/site-available/[웹서비스 명칭]

아래와 같이 Reverse Proxy 서버로 설정합니다.

server {
    listen 80;
    listen [::]:80;
 
    server_name project.com www.project.com; # 도메인 설정
 
    location / {
        include proxy_params;
        proxy_pass http://unix:/tmp/[소켓파일 명].sock;
    }
 
}

파일을 저장하고 나와서 아래와 같이 실제 enabled 폴더에 링크를 생성해 줍니다.

sudo ln -s /etc/nginx/sites-available/[웹서비스 명칭] /etc/nginx/sites-enabled

NGINX 서비스를 재시작합니다.

sudo service nginx restart

마무리

SSL 설정이나 기타 NGINX 설정들을 사용하는 환경에 맞춰서 추가/수정할 수 있습니다.

지금까지 간단한 Gunicorn 설정 방법을 알아보았습니다.

문의사항이나 잘못된 부분이 있으면 댓글로 남겨주시기 바랍니다.

감사합니다.

Tip 카테고리의 다른 글
Vercel 배포 시 Serverless Function 250MB 제한 오류
Vercel 배포 시 Serverless Function 250MB 제한 오류
Next.js 배포 시 Serverless Function의 용량이 과도하게 잡히는 문제
2025-06-28 21:54
Next.js 프로젝트에서 MDX 코드 블럭 꾸미기
Next.js 프로젝트에서 MDX 코드 블럭 꾸미기
rehype-pretty-code 플러그인으로 MDX 코드 블럭을 꾸며보자.
2025-06-08 20:31
Ubuntu 설치 후 짜잘한 설정 팁
Ubuntu 설치 후 짜잘한 설정 팁
개인적으로 주로 하는 설정 작업을 정리해 보았습니다.
2023-03-02 11:36
Let's Encrypt 설치 및 자동 갱신 (feat. Cloudflare)
Let's Encrypt 설치 및 자동 갱신 (feat. Cloudflare)
무료 SSL 인증서를 설정하고 자동 갱신하자.
2022-02-16 17:34