Dev

uWSGI 설치 & Emperor 설정 | Ubuntu 서버 세팅, 이 순서대로 하면 끝 (12)

KingdomPillar 2025. 4. 11. 08:00
반응형

uWSGI 빠르고 유연한 Python 앱 배포

서버 세팅을 하면서 가장 많이 서버를 리셋하게 만든 건, 다름 아닌 이녀석 uWSGI였다.
특히 Emperor 모드 설정까지 포함하면, 권한 문제, 디렉토리 구조, 서비스 등록까지 한 번에 잘 되는 일이 드물었다.

여기 적는 이 순서를 그대로 따라가기만 하면 나처럼 삽질은 하지 않아도 될 거다.
(uWSGI로만 서버를 몇 번은 초기화했는지… 그 기억을 교훈 삼아 하나씩 정리해본다.)


1. uWSGI 설치

uWSGI는 Python 패키지로 설치되며,
현재 어떤 Python 환경에 설치하느냐가 매우 중요하다.
특히 pyenv를 사용 중이라면, 먼저 원하는 Python 버전이 선택되어 있는지 확인하자:

pyenv versions
현재 선택된 버전 앞에는 * 표시가 붙는다.
예: * 3.12.6 (set by /home/USERNAME/.pyenv/version)

 

이 상태에서 아래 명령어를 실행하면,
uWSGI는 pyenv가 선택한 버전의 환경에 정확히 설치된다:

pip install uwsgi
uwsgi --version  # 설치 확인
⚠️ 주의: sudo pip install은 절대 사용하지 말 것!
시스템 전역 Python 환경에 설치되면서 충돌이나 예기치 않은 오류를 일으킬 수 있다.
반드시 pyenv로 선택한 사용자 환경에서 설치해야 한다.

 

 

2. Emperor 사전 세팅

uWSGI Emperor는 여러 개의 uWSGI 인스턴스를 효율적으로 관리할 수 있도록 도와주는 관리자다.
아래 명령어로 Emperor가 사용할 디렉토리를 만들고 권한을 설정하자:

sudo mkdir -p /etc/uwsgi/vassals/
sudo chown -R www-data:www-data /etc/uwsgi/vassals/

sudo mkdir -p /run/uwsgi/
sudo chown www-data:www-data /run/uwsgi/
sudo chmod 770 /run/uwsgi/

 

 

3. 프로젝트용 uWSGI 설정 파일 생성

각 프로젝트마다 개별 설정 파일이 필요하다. 예를 들어 tistory 프로젝트라면:

sudo vi /etc/uwsgi/vassals/tistory.ini

 

다음 내용을 입력한다:

[uwsgi]
chdir = /home/USERNAME/tistory
module = config.wsgi:application

socket = /run/uwsgi/tistory.sock
chmod-socket = 660
vacuum = true

home = /home/USERNAME/tistory/.venv
daemonize = /var/log/uwsgi/tistory.log
enable-threads = true
master = true
uid = www-data
gid = www-data
  • chdir: Django 프로젝트 경로
  • home: Python 가상환경 경로
  • daemonize: 로그 파일 경로 (사전에 로그 디렉토리를 생성해야 함)

아래 명령어로 로그 디렉토리를 생성하자:

sudo mkdir -p /var/log/uwsgi/

 

 

4. uWSGI Emperor 서비스 등록

uWSGI를 systemd 서비스로 등록해서 서버 부팅 시 자동 실행되도록 설정한다:

sudo vi /etc/systemd/system/uwsgi.service

 

아래 내용을 입력한다:

[Unit]
Description=uWSGI Emperor service

[Service]
EnvironmentFile=/home/USERNAME/tistory/.env
ExecStart=/home/USERNAME/.pyenv/versions/3.12.6/bin/uwsgi --emperor /etc/uwsgi/vassals

Restart=on-failure
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog

[Install]
WantedBy=multi-user.target

 

  • EnvironmentFile: uWSGI 실행 시 불러올 환경 변수 파일의 경로
    .env 파일 안에는 DJANGO_SETTINGS_MODULE이나 SECRET_KEY, DATABASE_URL 등 프로젝트 실행에 필요한 민감한 값들이 들어간다.
    autoenv 또는 dotenv 같은 도구를 사용하는 경우에도, systemd는 셸 환경이 아니기 때문에 명시적으로 파일을 지정해줘야 한다.
  • ExecStart: 실제 uWSGI 실행 경로
    여기에는 pyenv로 설치된 Python 버전의 uwsgi 실행 파일 절대 경로를 지정한다.
    다음 명령어로 확인할 수 있다:
which uwsgi

예: /home/USERNAME/.pyenv/versions/3.12.6/bin/uwsgi

systemd는 로그인 셸과 달리 pyenv를 자동으로 인식하지 못하므로, 경로를 명확히 적어야 한다.

  • --emperor: 이 옵션은 Emperor 모드를 사용한다는 의미, uWSGI 설정 파일(.ini)의 경로
    지정된 디렉토리(/etc/uwsgi/vassals) 안에 있는 .ini 설정 파일들을 자동으로 감지하고 실행한다.
    여러 개의 프로젝트를 운영할 때, 각각의 .ini를 이 디렉토리에 넣기만 하면 uWSGI가 알아서 관리해준다.

 

 

5. uWSGI 서비스 실행

이제 서비스를 등록하고 실행한다:

sudo systemctl daemon-reload
sudo systemctl enable uwsgi
sudo systemctl start uwsgi

 

정상적으로 실행되었는지 확인하려면:

sudo systemctl status uwsgi

uwsgi status 확인

Active: active (running) 문구가 보인다면 성공! 😆


마무리

Django 앱을 배포하는 여정에서 가장 복잡한 관문 중 하나가 바로 uWSGI 설정이다.
특히 Emperor 모드까지 활용하면 여러 프로젝트를 한 서버에서 유연하게 관리할 수 있지만, 그만큼 초기 설정이 까다롭다.

하지만 이 단계를 잘 통과해두면, 이후 배포와 운영이 훨씬 깔끔하고 안정적으로 굴러간다.
이제 다음 글에서는 Nginx와 uWSGI를 연결해서, 외부 요청을 Django 앱으로 안전하게 전달하는 과정을 이어서 살펴보자.
서버는 점점 실전에 가까워지고 있다.


 

반응형