Django Web Framework on Ubuntu

일단 들이대~·2024년 9월 3일

같은 실수를 반복하지 않기 위해...

물론 나도 그럴 수 있지만... 다른 분들의 블로그등에서 참조하는 내용들이 정말
사소한 오타 하나 때문에 안되는 경우가 많다.
그래서 어쩔수 없이 자신만의 페이지를 만드는 것 같다.

1. Installing Linux Server

Ventoy라는 툴이 가장 쓰기 쉬움.
1) 8GB 정도 되는 USB 미디어를 준비 후,
2) Ventoy 툴을 다운받아 USB 미디어를 포맷하고,
3) Ventoy라고 이름지어진 드라이브 안에,
4) 리눅스 ISO 이미지를 복사한 후,
5) 미디어를 USB 단자에 연결한 상태로 시스템 재부팅
6) 재부팅중에 부팅 미디어 선택 메뉴 진입시켜 리눅스 설치

2. Installing Nginx Web Server

// 리눅스 시스템에서 업데이트 할 거 있나 확인부터
$ sudo apt(apt-get) update
// nginx 설치
$ sudo apt install nginx
// 설치된 Nginx 확인

3. pyenv 설치

// curl 부터 설치
$ sudo apt install curl

// Pyenv 설치
//---위키독스에서는 이거였는데(Before)--
// https://wikidocs.net/10936#_1
//--------------------------
$ curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash

//---요새는 이걸로 바뀌었나봄(After)-------------------------------
// https://velog.io/@dlsrbs98/pyenv%EB%A5%BC-%ED%86%B5%ED%95%B4-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0
//-------------------------------------------------------------
$ curl https://pyenv.run | bash

4. pyenv용 환경변수 삽입 to .zshrc

// 내 홈 디렉토리에 있는 .zshrc 파일 편집
$ vi ~/.zshrc

// 무조건 맨 아래에 작성.

export PATH="/home/[장고폴더 관리자]/.local/bin:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

// 어디는 if 문 없이 그냥 넣게 되어 있는데...
// 난 에러가 나길래 if 문 있는걸 찾아서 넣었더니 깔끔해짐
// https://stynxh.github.io/2020-07-10-solve-pyenv-activate-error-korean/
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

eval "$(pyenv virtualenv-init -)"

쉘을 재실행 할 수 있는 방법으로 재실행(로그아웃 후 로그인을 하던가, source 를 쓰던가)

5. pyenv 로 Python 설치

나는 어차피 리눅스 서버에 여러 버전 쓸 일은 없기에 큰 신경 안 쓰고, 최신 버전의 파이썬을 설치

// pyenv 로 설치 가능한 버전 확인하기
$ pyenv install --list

// 목록 쫘악 ~
3.10.11
~~~
3.12.4
~~
anaconda-1.4.0

// 파이썬 3.12.4 설치한다고 하면,
$ pyenv install 3.12.4

Global/Local 설정 나한테는 중요하지 않음

6. pyenv 로 가상환경 만들기

// 아래와 같은 명령어 형식을 사용하여 가상환경 생성
//$ pyenv virtualenv [파이썬 버전] [가상환경 이름]
$ pyenv virtualenv 3.12.4 venv3124

// 생성된 가상환경은 위의 환경변수 설정에 의해
// 본인의 홈 디렉토리 아래의 .pyenv 폴더에 생길것임

7. Django 프레임웤 돌릴 폴더 만들기

원하는 위치에 폴더를 생성하되, 리눅스 시스템에서 중요한건 권한!!
이것땜에 맨날 뭐가 안됨.

// 아파치 서버 설치하면 www 디렉터리가 생성되는건가...?
$ cd ~/www
$ mkdir web_test

8. 가상환경 Auto ON/OFF 시스템 만들기

방금 만든 폴더로 들어가서 pyenv 명령으로 가상환경 만들면,
폴더를 나가면 가상환경에서 나오고, 들어가면 다시 가상환경으로 진입하는
가상환경 Auto ON/OFF 시스템이 생성된다.

$ cd web_test 
web_test$ pyenv local venv3124
(venv3124)web_test$ cd ..
$ 

9. 가상환경에서 파이썬 플러그인 설치

장고 환경을 만들것이므로, 장고 관련된 것만 설치

// pip 또는 pip3 업그레이드
(venv3124)web_test$ pip(3) install --upgrade pip

// 장고 프레임웤 설치
(venv3124)web_test$ pip(3) install django

// uWSGI 설치
// 테스트 할 때에는 장고 프로젝트의 wsgi.py를 써서
// python manage.py runserver 0.0.0.0:8000 등을 쓰는데,
// 실제 배포 서버에서는 따로 wsgi를 붙여준다 함.
(venv3124)web_test$ pip(3) install uwsgi

// 혹은 gunicorn 이란것도 설치한다 함
(venv3124)web_test$ pip(3) install gunicorn

10. 위키독스 따라서 장고 프로젝트 생성

// web_test 디렉터리 안에 repo와 run 디렉터리를 생성
// git 으로 작업하기 편하게 하려고 이런 구조를 만드는 듯
// https://wikidocs.net/6611

(venv3124)web_test$ mkdir repo run
(venv3124)web_test$ chown [장고폴더관리자:www-data] run
(venv3124)web_test$ cd repo

// 실제 conf 에는 프로젝트 파일이 아니라 설정 파일이 들어간다는군.
// 그래서 프로젝트 이름을 쓰면 [프로젝트명]-[프로젝트명(하위폴더)]
// 처럼 생기는 것.
// 맨 뒤에 . 도 일부러 현재 디렉토리를 기준으로 생성하라고 하는거임.
(venv3124)web_test/repo$ django-admin startproject conf .

-----------------------------------------------
프로젝트_이름/
    repo/
        conf/
            __init__.py
            settings.py
            urls.py
            wsgi.py
        manage.py            
    run/
-----------------------------------------------

11. STATIC_ROOT 디렉터리 지정

repo/conf/settings.py 파일의 끝에 다음 줄 추가.

import os	// 이거 추가
~~~~	// 기존 내용
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')		// 이거 추가

12. 마이그레이션

(venv3124)web_test/repo$ ./manage.py makemigrations
(venv3124)web_test/repo$ ./manage.py migrate

13. admin 사용자 추가

(venv3124)web_test/repo$ ./manage.py createsuperuser

14. static 데이터 모으기

(venv3124)web_test/repo$ ./manage.py collectstatic

15. uWSGI 구동 테스트

// uwsgi	-- http [:포트번호]
//			--home [가상환경 경로]
//          --chdir [manage.py가 들어있는 프로젝트 디렉터리
(venv3124)web_test/repo$ uwsgi --http :8000 --home /home/[사용자]/.pyenv/versions/venv3124 --chdir /home/[사용자]/web_test/repo --module conf.wsgi

16. uWSGI 옵션파일 만들기

$ touch /home/[장고폴더관리자]/web_test/run/uwsgi.ini
$ vi /home/[장고폴더관리자]/web_test/run/uwsgi.ini

파일에 붙여넣을 내용
------------------------------------------------
[uwsgi]
uid = [장고폴더관리자]
base = /home/%(uid)/web_test

home = --home /home/[장고폴더관리자]/.pyenv/versions/venv3124
chdir = %(base)/repo
module = conf.wsgi:application
env = DJANGO_SETTINGS_MODULE=conf.settings

master = true
processes = 5

socket = %(base)/run/uwsgi.sock
chown-socket = %(uid):www-data
chmod-socket = 666
vacuum = true
-------------------------------------------------

장고용 폴더를 만들 때도 uwsgi.ini 건들때도, nginx 설정할 때도,
사용자가 누구인지가 아주 중요하다. 이게 서로 안 맞으면 Permission 에러가 계속 뜬다.
이것땜에 폴더 소유자 계속 바꿔주고 Nginx.conf 파일과 이 uwsgi.ini 파일의 사용자 이름
맞춰주고, 사용자 서브 그룹도 추가해주고... 별 짓을 다했다.

sudo chmod g+rwx -R [장고폴더] // 라던가
sudo chown -R [장고폴더관리자]:www-data [장고폴더] //같은 명령을 몇번이나 썼다.

uwsgi 데몬화 하는것 때문에 이것저것 건들다
sudo chown -R www-data:www-data [장고폴더] 로 했더니 안되던 기능이 또 되네... 암튼 권한 문제땜에 짜증남...ㅠㅠ

17. uWSGI 실행 확인하기

(py3124)web_test/run$ uwsgi --ini uwsgi.ini

설정이 제대로 되었다면, uwsgi가 동작한다

18. 서비스 등록 스크립트 생성

이것은 리눅스에 Daemon처럼 서비스에 uwsgi 를 등록하는 것 같다.

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

------------------------------------------------
[Unit]
Description=uWSGI Emperor service

[Service]
ExecStart=/home/[장고폴더관리자]/.pyenv/versions/venv3124/bin/uwsgi \
        --emperor /home/[장고폴더관리자]/web_test/run
User=[장고폴더관리자]
Group=www-data
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog

[Install]
WantedBy=multi-user.target
------------------------------------------------

19. uWSGI 서비스 등록

$ sudo systemctl start uwsgi
$ sudo systemctl enable uwsgi

django source 를 수정해도 실제 서버에 반영시키려면, uWSGI를 재시작 해주어야 한다.
그래서, 서비스를 nginx 웹서버처럼 서비스(데몬)에 등록시키고, 아래와 같은 명령으로 uwsgi를 재시작 해 주어야 내 코드 수정사항이 서버에 반영된다.

$ sudo systemctl restart uwsgi
또는
$ sudo service uwsgi restart

20. uWSGI 서비스 구동 확인

$ sudo systemctl status uwsgi

구동 실패시 에러 로그는 /var/log/syslog 에서 확인 가능하다 하는데...
"그냥 설정파일 몇번째 라인에서 오류 났음" 정도.
Nginx 로그랑 같이 보면서 잡아야 함. 터미널 4개 정도 띄워놓고 확인했었음.

21. nginx 사이트 설정 추가

upstream 이름은 uwsgi_pass 이름과 같다.

$ sudo /etc/nginx/sites-available/web_test

------------------------------------------------
upstream django {
    server unix:/home/[장고폴더관리자]/web_test/run/uwsgi.sock;
}

server {
        listen 8000;
        server_name XXX.XXX.XXX.XXX;

        location = /favicon.ico { access_log off; log_not_found off; }

        location /static/ {
                root /home/[장고폴더관리자]/web_test/repo;
        }

        location / {
            include         /etc/nginx/uwsgi_params;
            uwsgi_pass      django;
        }
}
------------------------------------------------

22. nginx에 사이트 추가

upstream 이름은 uwsgi_pass 이름과 같다.

$ sudo ln -s /etc/nginx/sites-available/web_test /etc/nginx/sites-enabled

23. nginx 설정 문법검사 및 재기동

$ sudo nginx -t
// 위 명령에서 문제가 없으면
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

$ sudo sytemctl restart nginx

24. 방화벽 해제

$ sudo ufw allow 8000
$ sudo ufw allow 'Nginx Full'

솔직히 위의 것은 안해봤다. 난 그 전에 이미 방화벽을 해제해 놓은 상태라...

  • 실행중에 ModuleNotFoundError: No Module named 'encodings' 에러가 뜨면,
    거의 대부분 파이썬 실행파일 경로를 어딘가에서 잘못 준 것이다.
  • 우선 여기서 일단락, 위키 독스의 "한 서버에 여러 Django 애플리케이션" 부분은 현재로선 읽지 않겠다.ㅋ
  • uwsgi 에 대해 정리 잘 되어있는 블로그
    https://twpower.github.io/41-connect-nginx-uwsgi-django
profile
밥벌이를 위한 처절한 몸부림

0개의 댓글