All Articles

ncloud 인스턴스 생성하고 nginx, uwsgi, django, mysql 설치하기

ncloud 서버 인스턴스 만들기

ACG 생성. 나중에 8001 포트 추가함

조금 기다리면 상태 필드가 운영중으로 바뀐다. 메일로도 알람이 옴.

퍼블릭 IP 생성하기

포트포워드 설정하기

서버 접속용 관리자 아이디, 비밀번호 받기

우분투 서버에 접속 후 본인이 쓰기 편한 비밀번호로 변경할 수 있긴 하지만 혹시 모르니 이 비밀번호도 어디 잘 적어두자.

우분투 서버 접속

ssh -l root -p {외부 포트 번호} {서버 접속용 공인 IP}

최초 접속이라면

“Are you sure you want to continue connecting (yes/no)?”

이라는 문구가 뜰 텐데 yes 입력하고 계속 진행한다.

접속 후 ‘관리자 비밀번호 확인’에서 얻은 관리자 이름(root)과 비밀번호를 입력한다. 로그인한 상태에서 passwd 명령어를 입력하면 비밀번호를 변경할 수 있다.

sudo 명령 실행 시 ‘sudo: unable to resolve host {호스트 이름}’ 같은 메시지가 뜨면 etc 폴더 안 hostname 파일과 hosts 파일을 확인하고 호스트 이름을 통일해준다. hosts에서는 127.0.1.1 옆에 있는 것이 호스트 이름이다.

nginx 설치

sudo apt-get update

업데이트 후 nginx 설치

$ sudo apt-get install -y nginx

nginx 버전을 확인해보자.

$ nginx -v
$ nginx version: nginx/1.10.3 (Ubuntu)

브라우저를 켜서 공인 IP 주소로 접속했을 때 아래 화면이 뜨면 nginx 웹서버가 제대로 설치된 것이다. 서버 접속용 공인 IP와는 다르니 주의할 것.

nginx browser test

Ubuntu 16.04에 Python 3.8 설치

Python 3.8 설치에 필요한 라이브러리를 먼저 설치한다.

$ sudo apt-get install build-essential checkinstall
$ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
  libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev

Python 3.8 설치

$ cd /opt
$ sudo wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
$ sudo tar xzf Python-3.8.1.tgz
$ cd Python-3.8.1
$ sudo ./configure --enable-optimizations
$ sudo make altinstall

버전 확인

$ python3.8 -V
Python 3.8.1

python 명령어를 쳤을 때 Python 3.8이 기본으로 실행되도록 설정을 바꿔준다.

$ update-alternatives --install /usr/bin/python python /usr/local/bin/python3.8 1

제대로 설정됐는지 확인해보자. 파이썬 버전 확인 명령어를 아래와 같이 입력한다.

$ python -V
Python 3.8.1

설정이 잘 되었다.

Python 3.8 버전 설치에 도움받은 곳

virtualenv 가상환경 세팅

virtualenv를 설치한다.

$ sudo apt install virtualenv

파이썬 3.8을 사용하는 가상환경을 만들어준다. 가상환경 이름은 test로 했다.

$ virtualenv test --python=python3.8

만든 가상환경을 실행한다.

$ source test/bin/activate

그런데 이런 에러가 난다. 매뉴얼대로 해도 항상 에러가 나더라. 신기하다.

-bash: test/bin/activate: No such file or directory

cd test/bin으로 들어가면 activate가 없고 python python3 python3.8 이 세 개만 달랑 있다. 스택 오버플로우에서 이 명령어를 써보라길래 일단 입력해봤다.

$ python3.8 -m venv test

에러인가 하는 메시지가 떠서 다시 test/bin 경로로 들어가봤더니 activate가 생겨있었다…!? 왜지??

Unable to symlink '/usr/local/bin/python3.8' to '/root/test/bin/python3.8'

이 메시지는 왜 떴는지 모르겠다. 아무튼 source test/bin/activate 명령어를 다시 입력하니까 가상환경이 잘 실행됐다. 이제 여기에 장고를 설치하면 된다.

Miniconda 가상환경 세팅

virtualenv를 써도 되지만 익숙한 미니콘다도 설치해보려고 한다.

$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ chmod +x Miniconda3-latest-Linux-x86_64.sh
$ ./Miniconda3-latest-Linux-x86_64.sh

위치는 일단 root에 설치했다.

$ source .bashrc

이러면 명령 라인 앞에 (base)가 생겨야 하는데 나는 왜 안 생기냐.. 일단 진행해보겠다.

$ sudo apt-get update
$ sudo apt-get upgrade

mysqlclient 설치 전 gcc 먼저 설치해야한다. 안 그러면 mysqlclient 설치 시 오류 난다.

$ sudo apt-get install gcc
$ Unable to locate package libmysqlclient-dev

이제 미니콘다로 파이썬 3.8 버전을 사용하는 가상환경을 만들어보자. 로컬에서 하던 것과 똑같이 하면 된다. 가상환경 이름은 condatest로 했다.

$ conda create -n condatest python=3.8

만약 여기서 conda 명령어를 찾을 수 없다는 에러가 뜨면 bash 설정파일에 추가해줄 것이 있다.

$ echo ". /root/miniconda3/etc/profile.d/conda.sh" >> ~/.bashrc

나는 root에 미니콘다를 설치했으므로 저 경로로 썼고, 다른 곳에다 설치했다면 conda.sh 파일이 있는 경로를 써주면 된다. 이제 conda.sh 파일 경로가 .bashrc 파일에 추가됐다. 이제 가상환경을 다시 만들어보면 정상 작동할 것이다.

$ conda activate condatest

가상환경을 실행하면 명령라인 제일 앞에 가상환경 이름이 뜨는 것을 확인할 수 있다. 여기서는 (condatest)가 뜨면 맞는 것이다.

Django, uwsgi 설치

Django를 설치해야하므로 pip를 설치한다.

$ sudo apt-get install python3-pip

pip가 최신 버전(20.2.2)이 아니라고 해서 업그레이드 해줬다.

$ pip install --upgrade pip

대망의 장고 설치

$ pip install django

uwsgi 설치

$ pip install uwsgi

만약 uwsgi 설치할 때 command errored out with exit status 1 오류가 난다면,

$ apt-get update && apt-get install gcc-4.8 && rm /usr/bin/gcc && ln -s /usr/bin/gcc-4.8 /usr/bin/gcc

를 실행한 후에 pip으로 다시 uwsgi를 설치하면 된다.

MySQL 설치

설치할 수 있는 mysql server 버전을 체크한다.

$ sudo apt-cache search mysql-server

일단 5.7 버전을 설치해준다. 중간에 root 사용자의 패스워드를 설정하는 화면이 나온다. 설정하고 싶은 비밀번호를 입력하면 된다.

$ sudo apt-get install mysql-server-5.7

설치가 잘 되었는지 확인해보자.

$ netstat -ntlp | grep mysqld
tcp    0    0 127.0.0.1:3306     0.0.0.0:*        LISTEN      16003/mysqld

뭐가 나오는 거 보니 잘 된 것 같다. 이제 mysql을 실행해보자.

$ mysql -u root -p

설치 시 지정한 비밀번호를 입력하면 mysql이 실행된다.

mysql characterset 설정

한글 입력 시 깨지는 문제를 해결하기 위해 characterset을 설정해준다.

mysql 설정 파일이 있는 경로로 이동한다.

cd /etc/mysql/conf.d

mysql.cnf 파일을 열어서 원래 있던 [mysql]을 지우고 새 설정을 붙여넣는다. vim을 사용했다.

vi mysql.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
character-set-server=utf8
collation-server=utf8_general_ci
init_connect = set collation_connection = utf8_general_ci
init_connect = set names utf8

[mysql]
default-character-set=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
default-character-set=utf8

[client]
default-character-set=utf8

[mysqldump]
default-character-set=utf8

mysql 재시작 후, 다시 root로 로그인해서 설정이 잘 반영됐는지 확인한다.

$ sudo /etc/init.d/mysql restart
$ mysql -u root -p

mysql 실행 후,

mysql> status
...
Server characterset:	utf8
Db     characterset:	utf8
Client characterset:	utf8
Conn.  characterset:	utf8
...

characterset이 utf8로 잘 저장됐다.

mysql 설치에 도움 받은 곳

Django, MySQL 연동

장고 프로젝트 초기 세팅글을 참고해 그대로 진행했다.

$ pip install mysqlclient

설치 후 장고 프로젝트 메인 폴더 settings.py에서 DATABASES 설정을 mysql로 맞춰줬다. 마이그레이션 후 mysql에서 테이블 확인을 해보니 django 기본 테이블들이 잘 생성된 것을 확인했다.

미니콘다 말고 virtualenv를 쓸 때 pip install mysqlclient로 설치가 되지 않아서 스택 오버플로우에서 찾은 다른 방법을 시도했다. 내 파이썬은 3.8 버전이니 3.6 부분만 3.8로 수정해서 실행했다.

$ sudo apt-get install python3.8-dev libmysqlclient-dev

여기서 그대로 설치가 되면 좋고, 만약 이런 오류가 뜨면,

E: Unable to locate package python3.8-dev
E: Couldn't find any package by glob 'python3.8-dev'
E: Couldn't find any package by regex 'python3.8-dev'

아래 명령어를 차례로 입력하고 모든 것이 설치된 후에 다시 mysqlclient를 설치한다.

$ sudo add-apt-repository ppa:jonathonf/python-3.8
$ sudo apt-get update

uwsgi로 장고 서버 띄우기

python manage.py runserver 0:8001로 서버를 띄워주고 브라우저에서 확인해보는데 장고 로켓이 보이지 않는다… 서버 띄우는 과정 자체에는 문제가 없는데 뭐가 문제일까? ACG에서 8001번 포트도 허용했어야 하나 싶어서 추가해줬는데도 안 된다. 뭐가 문제지? 내일 다시 찾아보자. 세팅 진짜 너무 어렵다어흐어흐어으어우

아니다 된다! 이게 맞는진 모르겠지만 ncloud 공인 IP주소에 내 포트번호 8001을 붙이니까 로켓이 보인다 만세!!!! (8000은 개츠비 블로그에 할당해놔서 영구결번임)

django runserver test

이제 uwsgi를 이용해 서버를 띄워보자. 장고 프로젝트 폴더(manage.py가 있는 폴더)에 uwsgi.ini 파일을 만들어준다.

$ vi uwsgi.ini
[uwsgi]

chdir = /root/project-test/project1
module = project1.wsgi
socket = /root/project-test/project1/project1.sock
chmod-socket = 666
vacuum = true
home = /root/miniconda3/envs/condatest
virtualenv = /root/miniconda3/envs/condatest
daemonize = /root/project-test/project1/uwsgi.log
die-on-term = true
  • chdir : 장고 프로젝트 폴더 경로
  • module : 장고 프로젝트를 생성하면서 만들어진 wsgi.py 파일을 지칭
  • socket : 장고 프로젝트 폴더에 생성할 소켓 파일
  • home, virtualenv : 가상환경 경로. 미니콘다/아나콘다를 쓴다면 conda env list로 경로를 확인할 수 있다.
  • daemonize : 장고 프로젝트 폴더에 생성할 로그 파일

ini 파일을 만들어준 뒤 소켓 파일과 로그 파일을 생성한다.

$ uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini

라는 메시지가 뜨면 잘 생성된 것이다. 이제 서버를 띄워보자.

$ uwsgi --http :8001 --module project1.wsgi

브라우저에서 ncloud 공인 IP주소 + 포트 번호로 들어가면 장고 로켓을 확인할 수 있다.

uwsgi server test

그냥 런서버랑 다른 로켓이다. 같아보이지만 아무튼 다르다.

nginx와 uwsgi 연동하기

$ vi /etc/nginx/sites-available/default
upstream django {
  server unix:///root/project-test/project1/project1.sock;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name 공인IP주소 도메인;
  charset utf-8;

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

  location /static {
    alias /root/project-test/project1/static;
  }
}
  • upstream djangoserver 항목에는 소켓 파일 경로 지정한다.
  • server_name에는 공인 IP주소와 도메인을 써준다.
  • location /static에는 장고 프로젝트 폴더 경로를 써준다. static 폴더가 생기는 모양
$ sudo nginx -t

만약 여기서 에러가 나면 default 파일에 뭔가 오타가 있거나 경로지정이 잘못된 것이다. 다시 한번 살펴보자.

$ sudo service nginx restart

블로그에서는 nginx 재시작 후 공인 IP 주소로 접속하면 장고 로켓이 뜰 거라고 했는데 안 뜬다. uwsgi를 실행해줘야 한다는 블로그 글을 보고 sudo service uwsgi start를 했더니 uwsgi.service 파일이 없다 어쩌고 하더라.

Warning: uwsgi.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Job for uwsgi.service failed because the control process exited with error code. See "systemctl status uwsgi.service" and "journalctl -xe" for details.

이리저리 찾아보니 uwsgi.service 파일을 만들어줬어야 했다.

$ vi /etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor service

[Service]
ExecStart=/root/miniconda3/envs/condatest/bin/uwsgi \
         --emperor /root/project-test/project1
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog

[Install]
WantedBy=multi-user.target
  • ExecStart에는 uwsgi경로를 쓰고 --emperor에는 장고 프로젝트 폴더 경로를 써준다. uwsgi 경로를 모르겠다면 which uwsgi로 알아낼 수 있다.

이렇게 uwsgi.service 파일을 만들어준 후,

$ sudo systemctl start uwsgi

를 쳤는데, 또 같은 에러가 떴다.

Warning: uwsgi.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Job for uwsgi.service failed because the control process exited with error code. See "systemctl status uwsgi.service" and "journalctl -xe" for details.

에러 메시지를 다시 잘 읽어보니 Run ‘systemctl daemon-reload’ to reload units. 이런 말이 있네? 시키는대로 해보자.

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

차례로 실행 후 uwsgi가 잘 돌아가고 있는지 확인해봤다. 이전에는 Fail이라고 떴었다.

$ systemctl status uwsgi

uwsgi status

드디어 active (running) 글자가 보인다! 만세!

+) 근데 이제 포트번호 없이 공인 IP로만도 접속이 되어야 하는데 안 된다. 뭐가 문제인지 모르겠다. 이리저리 하라는대로 설정을 바꿔봐도 안 됨 ㅠㅠ… 내일 처음부터 다시 해봐야하나 하하