ABOUT ME

Baptist / Web Developer / Musician @KingdomPillar

Today
Yesterday
Total
  • uWSGI 설치 & Emperor 설정 | Ubuntu 서버 세팅, 이 순서대로 하면 끝 (12)
    Dev 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 앱으로 안전하게 전달하는 과정을 이어서 살펴보자.
    서버는 점점 실전에 가까워지고 있다.


     

    반응형
The one who is victorious I will make a pillar in the temple of my God.