DigitalOcean에 Django 프로젝트 배포하기 (2)

2020. 03. 05 IT/컴퓨터 > Django

DigitalOcean에 Django 프로젝트 배포하기 (1)

 

#10. Droplet이 성공적으로 만들어졌다면 등록한 이메일로 root 계정의 초기 암호가 배달된다.

DigigalOcean에서 제공하는 콘솔을 이용하거나 별도의 SSH 클라이언트를 이용해서 만들어진 droplet 의 IP 주소를 이용해 접속을 한다. SSH 인증을 사용했다면 추가적인 절차가 필요하지만 일단 지금은 password 방식으로 로그인하기로 한다.

Login 프롬프트에 root 를 입력하고 처음 주어진 암호를 입력하면, 암호를 리셋하라는 프롬프트가 뜨니 새 암호를 설정해 준다.

 

#11. 이후

$ apt update

명령으로 우분투 서버 업데이트 사항이 있는지 확인하고 업데이트를 적용해 준다. 

 

업그레이드 가능한 패키지가 있는 경우

$ apt upgrade

명령으로 업그레이드도 같이 해 주는 것이 좋겠다.

업그레이드 중 다음과 같은 메세지가 나오면서 이미 설치된 프로그램에 대해 어떻게 할 것인지 묻는 경우가 있는데, 특별한 경우가 아니라면 그냥 현재 설치된 버전을 유지하는 것으로 선택하자.

 

업그레이드 후

$ apt autoremove

를 실행하면 필요 없게 된 파일들을 제거해준다.

 

 

#12. 새로운 유저를 생성해준다.

Root 계정으로 진행해도 되지만, 프로젝트마다 다른 id를 사용하는 것이 편리한 점이 있고, root 계정은 권한이 너무 커서 의도치 않게 치명적인 실수를 저지를 위험이 있으므로 봉인해 두고 새로 만든 계정으로 프로젝트 배포를 진행하는 것이 좋겠다.

$ adduser 원하는id

식으로 원하는 아이디를 추가하고 패스워드를 설정해 준다. 일단 지금은 sitemaster 라고 지정해 주었다. 이후 이름과 전화번호등 사용자 정보를 입력하는 프롬프트가 뜨지만 입력하지 않아도 아이디 생성은 된다.

 

#13. 생성된 sitemaster 에 관리자 권한을 주어야 한다.

$ usermod -aG sudo sitemaster

를 입력해준다. 이렇게 하면 관리자 권한을 얻게 되는데, 이렇게 처리해 준 사용자는 실행하려는 명령어 앞에 sudo 라는 명령어를 덧붙여서 관리자 권한의 작업을 할 수 있다.

 

#14. 우분투에는 UFW firewall 이라는 방화벽이 포함되어 있어 이를 이용할 수 있는데, 이것과 별도로 DigitalOcean 사이트에서도 방화벽 설정을 할 수 있다. 두 가지 방화벽을 같이 사용하는 경우 충돌이 있을 수 있기 때문에 둘 중 하나만 사용하는 것을 권장하고 있다.

UFW를 이용하기 위해서는 설치된 다른 app 들을 ufw 허용 리스트에 등록해 주면 되는데,

$ ufw app list

명령어로 설치된 app 들을 확인하고,

$ ufw allow 앱이름

명령으로 해당 앱이 방화벽을 통과할 수 있도록 설정해 준다. 

그 후

$ ufw enable

명령으로 방화벽을 활성화해 주면 된다.

현재 방화벽의 상태를

$ ufw status

명령으로 확인할 수 있다. OpenSSH 는 우리가 만든 서버와의 SSH 통신을 가능하게 해 주는 서비스이므로 방화벽을 통과할 수 있게 등록해 준다.

 

 

#15. 이제 새로 생성한 id 로 다시 접속한다. 새로 세션을 열어 접속해도 되고,

$ su - sitemaster

명령을 입력해 사용자를 전환해도 된다. - 다음에 빈칸이 하나 있으므로 정확히 입력하자. (su: switch user)

 

#16. 우선 파이썬 관련된 패키지, postgresql 과 nginx, curl 등 서버 관련된 패키지들을 설치해 준다. 우분투 서버에는 파이썬 2와 3이 모두 설치되어 있지만, Django 버전 3은 파이썬 3.6 이후만 지원하므로 가급적 최신 버전의 장고와 파이썬 3을 이용하는 것이 좋겠다.

현재 프로젝트는 DB를 Sqlite3 를 이용하고 있어서 postgresql 관련 패키지는 당장은 필요 없지만, 향후 프로젝트가 커져서 데이터베이스를 이전할 경우에 대비해서 설치해주었다.

사실 sqlite 도 개인 블로그용 데이터를 저장하는데는 충분하고, 파일 하나로 전체 DB를 다 옮기는 것이 가능해서 소규모 프로젝트에는 편리한 점도 있기 때문에 아직까지는 굳이 바꿀 필요를 못 느끼고 있다. 그리고 이전에 Heroku에서 postgresql 을 설정하다가 골머리를 앓은 기억이 있어 일단 지금은 건드리지 않으려고 한다..

 

$ sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

명령으로 설치해준다.

 

 

#17. 이제 새로운 Django 프로젝트를 위한 가상환경을 만들어주어야 한다. 

$ sudo -H pip3 install --upgrade pip

명령으로 pip를 최신버전으로 업그레이드해 주고, 

$ sudo -H pip3 install virtualenv

명령으로 가상환경을 만들어 주는 virtualenv 패키지를 설치한다.

 

$ git clone 원격repository주소

명령어로 GitHub 에 미리 올려둔 프로젝트를 다운받자. 프로젝트가 성공적으로 clone 되어 해당 프로젝트의 디렉토리가 생성된 것이 확인되면 그 디렉토리로 이동한다.

 

$ virtualenv 가상환경이름

식으로 해당 프로젝트의 가상환경을 만들어준다. virtualenv 명령 뒤의 가상환경 이름은 다른 이름들과 관련되지 않는 독립된 이름이므로 임의로 지정해 주면 된다. 일단 deploy_env 라고 지정해 주었다.


가상환경이 만들어졌으면

$ source deploy_env/bin/activate

명령을 통해 가상환경을 활성화시켜준다. 명령 프롬프트 앞에 (deploy_env) 와 같이 만들어준 가상환경의 이름이 표시되면 정상적으로 활성화된 것이다.

(deploy_env)$

 

 

 

이유는 잘 모르겠는데 virtualenv 가 잘 작동하지 않는 경우가 있다. 패키지를 설치해도 가상환경 안에서 보이지 않거나, 아니면 반대로 가상환경에서 pip list 를 해 봐도 밖에 있는 패키지들이 전부 보이거나 하는 등의 이상 동작이 생기고 python 2와 python 3가 섞여서 가상환경 안에서도 python 3 버전을 이용하려면 python3 명령어를 이용해야 하는 등..이럴 때는 virtualenv 대신 venv를 사용해 보면 해결될 때도 있다.

 

venv는 파이썬 3버전에는 포함되어 있는 것으로 알고 있지만, 어쩐 일인지 DigitalOcean 에서 제공하는 우분투 서버에서는 다음 명령을 이용해서 설치해 주어야 한다.

$ sudo apt-get install python3-venv

venv를 설치해 주고 나면 다음 명령어로 가상환경을 만들어 준다.

$ python3 -m venv deploy_env

환경이 만들어 졌으면 activation 하는 방법은 virtualenv 와 같다.

$ source deploy_env/bin/activate

 

 

 

#18. 이제 Django 및 필요한 패키지들을 가상환경 내에 설치해 준다. 가상환경이 활성화되지 않은 경우 파이썬3 버전의 패키지를 설치하려면 꼭 pip3 을 이용해 설치해야 하지만, 일단 파이썬 3 버전의 가상환경이 활성화된 후에는 설치 프로그램 이름이 pip3 이 아닌 pip 이므로 명령어도 pip3 이 아니라 pip install program 식으로 해야 한다.

경우에 따라서 가상환경 내의 pip가 구 버전인 경우가 있으므로, 우선

(deploy_env)$ pip install --upgrade pip

를 실행해 pip를 최신 버전으로 업그레이드 해 준다.

 

이후

(deploy_env)$ pip install django gunicorn psycopg2-binary

로 django, gunicorn 을 설치해준다. psycopg2-binary 는 Postgresql 과 python 을 연결해주는 어댑터 패키지로, postgresql 을 당장 사용하지 않는 경우는 설치하지 않아도 되겠다.

어떨때는 위의 패키지들을 동시에 설치하려고 하면 퍼미션이 없다는 등의 오류를 내면서 가상환경 내에 설치가 되지 않는 경우도 있는데, 이때는 각각의 패키지를 따로 설치해 보면 설치가 되는 것 같다.

 

프로젝트에 사용된 다른 패키지를 requirement.txt로 freezing 해 놓은 경우에는

(deploy_env)$ pip install -r requirements.txt

로 해당 패키지들을 설치해준다.

 

Django 프로젝트의 root 디렉토리는 manage.py 가 존재하는 디렉토리이고, root 디렉토리 아래에 프로젝트 메인 디렉토리에 들어가면 settings.py, wsgi.py, urls.py 등의 파일이 있을 것이다. 여기서 settings.py 에 설정을 추가해주어야 한다.

우선 서버에서의 접근을 허용해야 하므로 만들어진 droplet 의 IP 주소를 ALLOWED_HOST에 추가해 주어야 한다. 커스텀 도메인을 사용하는 경우 www.example.com, example.com 등으로 도메인도 같이 추가해 준다. Nginx 를 이용해서 서비스를 구동하는 경우 'localhost'도 추가해 주어야 한다. 127.0.0.1은 Django 내장 테스트용 서버인 runserver 를 구동할 때 쓰인다.

[ settings.py ]
ALLOWED_HOSTS = [
    '127.0.0.1',
    'www.example.com',
    'example.com',
    '159.65.136.71',
    'localhost',
]

 

같은 settings.py 파일 안에 css, js 및 image 파일 등의 static 파일들이 어디에 위치하는지 Nginx에게 알려주기 위해서 STATIC_ROOT 설정을 추가해 준다.

[ settings.py ]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
    STATIC_DIR,
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

 

나중에 블로그 글에 업로드될 이미지등을 저장하는 media 폴더도 같이 설정해준다.

[ settings.py ]
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

 

settings.py 파일을 저장해 주고, 최초로 데이터베이스에 migration 을 해 주기 위해 다음 명령어들을 입력한다. manage.py 가 있는 프로젝트 루트 디렉토리에서 해야 한다.

(deploy_env)$ python manage.py makemigrations
(deploy_env)$ python manage.py migrate

 

프로젝트를 관리할 관리자 ID를 다음 명령어로 만들어준다.

(deploy_env)$ python manage.py createsuperuser

 

프로젝트 내에 있는 static 파일들을 STATIC_ROOT에 지정한 디렉토리로 모아주기 위해 다음을 실행한다.

(deploy_env)$ python manage.py collectstatic


이제 Django 쪽에서의 준비가 다 되었다. 프로젝트가 잘 뜨는지 테스트를 해 보기 위해 Django 의 내장 테스트용 서버인 runserver를 이용해서 프로젝트를 띄워 본다. runserver가 이용하는 8000번 포트를 개방하기 위해 ufw 설정을 다음과 같이 update 해 주고

(deploy_env)$ sudo ufw allow 8000

 

다음 명령으로 프로젝트를 구동한다.

(deploy_env)$ python manage.py runserver 0.0.0.0:8000

이런 화면이 보이면 서버가 구동된 것이고, 이 상태에서 외부 브라우저를 통해 

 

프로젝트 IP:8000을 입력했을 때 프로젝트의 index 화면이 보이면 제대로 작동하는 것이다.

 

그렇지만 지금은 테스트용 runserver에서 구동한 것이므로 이 상태로 서비스를 할 수는 없고, 본격적으로 서비스를 구동하기 위해서는 웹 서버인 Nginx 와 파이썬 WSGI (web service gateway interface) 서버인 gunicorn 세팅을 해 주어야 한다.

다음편에..

DigitalOcean에 Django 프로젝트 배포하기 (3)



최근 글 목록