개인적으로 GUI 툴들을 매우 좋아한다. CUI로 동작하는 경우 많은 명령어를 외워야 하는데, 내가 외우는 것을 좋아하지 않다보니 마우스로 사용가능한 GUI 툴들을 좋아한다. 

전에는 자주 사용하는 DB가 MySQL 이었는데, 이제는 PostgreSQL을 사용하고 있다. MySQL의 경우, Oracle에서 제공하는 MySQL Workbench 이 있어서 잘 이용하고 있었다. PostgreSQL의 경우, pgadmin 가 있다. 그런데, 이상하게 이 툴이 나에게 잘 맞지 않는다는 느낌이 있다. 그래서 한동안 계속 툴을 찾다가 dbeaver 라는 툴을 발견했다. 

 dbeaver(https://dbeaver.io/) 는 여러 DB를 지원한다. 그 중 하나가 PostgreSQL 이다.  이 툴은 여러 DB를 지원하다보니 설정할 때 해당 DB에 많는 자바 드라이버를 다운받는다. 그리고 PostgreSQL을 사용시에는 PostgrelSQL 과 PostgrelSQL (Generic) 이 두가지가 있는데 그냥 버전에 뭔가 전용으로 보인다. 그래서 기능이 더 많다. 그래서 이 Connection 을 설정하는게 더 편리하다. 

 이 툴은 jvm 위에서 동작하는 툴이라 Mac, Windows 를 모두 지원한다. 

 DB를 사용하다보면 DB를 백업하고 다시 Import 할 일이 많다. 이 기능은 이 툴이 제공하지 않고 기존 postgresql 을 이용해야 한다. 다만 이 툴을 통해 좀 더 편하게 이용할 수 있다. 이 설정을 위해 connetion settings 에서 local client 에서 설정을 해야 한다. 


 


 DLib는 machine learning algorithms 을 가지고 있는 툴킷이다. (http://dlib.net/ ) 이 자체는 CPP 라이브러리이나 파이썬으로 해당 라이브러리를 이용할 수 있다. 기본적으로 많은 기능이 제공되는데 이 중, 내가 가장 흥미를 느낀 기능은 face landmark 추출 기능이다. face landmark 는 얼굴의 특정지점을 추출하는 기능이다. DLib 가 기본적으로 제공하는 기능은 눈썹, 눈, 코, 입, 얼굴 아래형태이다. 해당 라이브러를 이용하면




이 처럼 얼굴의 위치를 잡아준다. 물론 오차는 약간 있다. 직접 학습을 하게 만들 수 있지만 학습데이터를 만드는 것도 많은 작업이 필요한지라 기존 데이터를 이용하는게 더 편하다. 



해당 라이브러리를 이용해 특정 지점에 스티커를 놓는 기능을 만들어 보았다. https://github.com/yiunsr/imglst 에서 소스를 확인 할 수 있고  http://imglst.labstoo.com/demo/landmark 에서 테스트 해 볼 수 있다. 기능이 라는게 별거 없는데, 얼굴 추출 기능은 http://dlib.net/face_landmark_detection.py.html 에 있는 기능을 이용했다. 이 기능은 원래 비디오 인데 적당히 사진을 이용할 수 있도록 수정했다. 


 대부분은 작업은 HTML5 Canvas 작업들이 더 힘들었다. dlib 는 이미지 위치만 잡아 주지 저렇게 점 까지 찍어 주지 못한다. 점까지 찍어 주고 숫자 출력하는게 더 힘들었다. 


 

 이 이외에 face morhping(http://imglst.labstoo.com/demo/morhping) 하는 기능도 샘플로 넣었다. 이 기능은 (https://github.com/alyssaq/face_morpher ) 의 기능을 이용했다. 두 얼굴을 합쳐서 중간 얼굴을 만드는 기능이다. 결과적으로 하고 싶은 것은 저 중간 얼굴을 실제 사진에 넣는 것이다. ( https://www.learnopencv.com/face-swap-using-opencv-c-python/ 이 기능 처럼 face swap 을 잘 적용하면 될 것 같은 느낌이다. ). 이 부분은 좀 더 공부가 필요할 것 같다. 

 

아래 세팅 설정들은 AWS EC2, Virtualbox 내 우분투 설치, conoha(https://www.conoha.jp/ko/ ) 를 설정하면서 사용된 설정들이라, 어떤 경우, 맞지 않을 수 있다는 것을 주의하자. 그리고 내가 의식적으로 하는 작업이나 패키지 설치들이 있기 때문에 필수 적이지 않는 것도 꽤 많다. 

(그런데 다 같은 Ubuntu 16.04 버전인데 조금씩 차이가 나는지 모르겠다. 아무래도 호스팅업체에서 제공하는 버전 자신들 서버에 맞게 조금씩 수정을 거친 것 같은 느낌이다. ) 


설정을 하는 경우 여러가지 설정파일을 생성하게 된다. 간혹 하나의 서버에 여러 프로젝트 서비스를 돌리는 경우가 있을 수 있기 때문에(나는 특히 이런 경우가 참 많았다. ) 가능한 한, 프로젝트 명에 맞추어 ini,  pid , sock 파일 또는 리소스를 생성하는게 좋다. 내 경우에는 같은 프로젝트로 test 서버, 스테이징서버 같은 것을 한 서버에 운영하는 경우, 프로젝트명_test,  프로젝트명_staging 이런 식으로 구별해서 이름을 정하는 편이다. 그리고 내가 사용한 파일이름이나 리소스이름은 임의적인 것이므로 원하는 대로 변경할 수 있다. 


1. 시간설정


1-1. timezone 설정


콘솔에 date 를 치면 시간 뒤에 붙는 세자리의 영문자를 통해서 timezone 을 알 수 있다. 

timezone 설정은 서비스에 따라서 크게 뭘로 해도 문제가 안될 수도 있고 될 수도 있는 부분이라 본인의 서비스에 맞게 잘 설정해야 한다. 그리고 서비스와 관련이 없더라도 로그 볼 때의 기준이 되는지라 팀이나 관리를 하는 나라를 고려 할 필요가 있다. 

 내가 했던 서비스의 경우 django setting 의 timezone 에 의해 동작하는 경우가 많은 지라 이 서버 timezone이 크게 중요하지는 않았다. 그래서 그냥 Asia/Seoul 로 설정하는 편이다.


sudo timedatectl set-timezone Asia/Seoul 

단순히 timezone 리스트를 확인 하고 싶은 경우

timedatectl list-timezones

로 확인 하면 된다. 

1-2. 주기적으로 시간 서버로 부터 시간을 맞추도록 설정
그리고 컴퓨터 시간일지라도 조금씩 오차가 발생하기 마련이다.  이 오차가 쌓이면 꽤 큰 차이의 시간 차가 생긴다. 어떤 서비스의 경우 시간차이 때문에 오류가 생길 수 있다. 그리고 관리하는 서버들 간의 시간이 차이가 발생하면 오류를 분석하기 어려워질 수도 있고, 오류도 발생할 수도 있다. 

그래서 정확한 시간을 알고 있는 다른 서버로 부터 시간을 받아올 수 있도록 설정이 필요하다. 

ntp(네트워크 타임 프로토콜) 라는 서비스가 돌아가는지 확인 해 보자.

ps -ef | grep ntpd 


결과

ntp       9154     1  0  2017 ?        00:07:10 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 111:117

root     11308 11188  0 00:16 pts/0    00:00:00 grep --color=auto ntpd


위 명령어를 입력했을 때,  결과가 2줄이 나온다면 걱정하지 말고 다음 내용은 무시하자.

 grep 이 부분의 결과만 나온다면 ntp 서비스가 나온느 것이 아니라서 주기적으로 시간을 맞출 수 있도록 설정이 필요하다. 


sudo service ntp start 

를 이용해서 서비스를 돌린다. 


AWS 의 경우 아래 링크를 참고해서 더 정확한 시간 설정을 하는 것을 추천한다.
https://aws.amazon.com/ko/blogs/korea/keeping-time-with-amazon-time-sync-service/

이 방법이 사용되지 않는다면 단발성으로 
sudo rdate -s time.bora.net
을 이용할 수 있다. (time.bora.net 은 많이 사용하는 서버이다.

이 방법을 crontab 을 이용해서 밤 12시에 하루에 1번 주기적으로 실행시키는 방법도 있다.


2. 기본적인 패키지 설치
리눅스를 사용하다보면 컴파일해서 설치할 일이 많다. 내가 직접 컴파일(빌드)을 하지 않더라도 진행과정에 컴파일(빌드)하는 동작이 들어가는 경우가 많다. 그래서 기본적인 개발환경을 세팅할 필요가 있다. 이 때를 위해 build-essential  를 설치한다.  pip install 하는 경우 꽤 많은 경우 자동으로 컴파일 해서 설치하는 경우가 많으니 필수이다. 

리눅스에서 뭐뭐뭐 -dev 형태로 된 패키지를 설치하는 경우가 있다. 이 경우는 라이브러리 인 경우가 많다. ( https://stackoverflow.com/questions/1157192/what-do-the-dev-packages-in-the-linux-package-repositories-actually-contain ). 어째든 뭔가 빌드해서 설치하는 경우가 사용된다. 간혹 이러한 dev 패키지가 설치되지 않으면 빌드하다 무슨무슨 .h 파일이 없다고 하면서 에러가 뜨는 경우가 발생한다. 


# 기본적인 빌드 환경 제공

sudo apt-get -y install build-essential      


# 파이썬 관련 패키지 설치 할 때 꼭 필요.

sudo apt-get -y install python-dev


# 파이썬 mysql 관련 패키지 설치시 필요

sudo apt-get install -y  libmysqlclient-dev


# 파이선 이미지 관련 라이브러리에서 필요, Pillow 같은 라이브러리 설치시 필요함

sudo apt-get install -y libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk

# 소스 관리툴 git 를 위해 사용함 
sudo apt-get install git 





3. nginx 설치
 nginx 를 사용하는 경우, 소스다운로드 받을 디렉토리가 /usr/share/nginx  안인 경우가 많다. nginx 를 설치하면 해당 경로를 자동으로 만들어주기 때문에 
nginx 를 먼저 설치하는 편이다. 

sudo apt-get -y  install nginx






4. 소스 다운로드
일반적으로 소스배포는 git를 이용하는 편이다. 그리고 git를 사용할 때는 배포용 전용 아이디를 만들어서 read 만 되게 관리한다.

소스 경로는   /usr/share/nginx/[프로젝트명] 식으로 하는 편이다.
cd /usr/share/nginx/[프로젝트명]
로 git로 소스를 다운받을 위치로 이동한다. 


github 의 경우
sudo git clone https://아이디@github.com/github프로젝트경로  .
맨 끝의 .(점) 의 경우 현재 디렉토리에 넣겠다는 의미이다. 맨 끝의 점이 없는 경우 새롭게 디렉토리가 생성된다. 


이를테면 
sudo git clone htttps://yiunsr@github.com/yiunsr/re2view.git .   
이런식으로 git의 경로는 https://github.com/yiunsr/re2view.git 이런식이다. 
 
bitbucket 의 경우
sudo git clone https://아이디@bitbucket.org/bitbucket프로젝트경로      .
으로 github 와 유사하다.  역시 맨 끝에 현재 위치에 다운받으라는 의미로  .(점)이 들어 있다. 

일반적으로 파이썬으로 만들어 프로그램 또는 서버는 virtualenv 로 가상환경을 설정해서 만들어진다. 나의 경우 실제 서버에서도 이런 방식으로 하는 편이다. 테스트 환경의 경우, 특히나 한 서버에 여러 서비스를 올리는 경우가 많았기 때문에 서로의 서비스가 영향을 받지 않도록 하려고 virtualenv 를 사용하는 편이다. 따라서 이 경우 pip freeze 한 결과파일 파일을 두고 다시 세팅하는 편이다. 이런 환경이 없다면 이번 기회에 이런 방식으로 사용하기를 추천한다. 


5. python 라이브러리 및 virtualenv 설정
요즘에는 파이썬이 2버전과 3버전 모두 탑재되는 경우가 많다. 그래서 설치가 되어 있다고 가정하고 진행한다.
(아주 최신 버전을 고려할 경우 따로 컴파일 후 설치할 필요가 있다. )

아래 설명은 python2.7 기준이다. python3 버전은 차후에 여기 아래에 추가 하겠다. 

python 패키지 관리자 pip 를 설치하고 pip 를 통해 virtualenv 를 설치한다.

apt-get install -y python-pip

pip install virtualenv

 


나 같은 경우 따로 설치한 프로그램은 /opt/ 에 넣는 편이다. 그래서 python virtual 환경 경로도 /opt/env/  아래 두는 편이다. 

우선 해당 디렉토리 까지 만든다. 그리고 가상환경을 만든다. 

cd /opt/

mkdir py_envs

cd py_envs

virtualenv --no-site-packages --distribute vtest

 


이 다음 중요한 것이 있다.
꼭 가상환경을 설정하기 전에
sudo -s   
를 해서 꼭 root 접속 필요하다.
sudo 를 이용해서  pip로 파이썬 패키지를 설치하면,  path 가 맞지 않아서 뭔가 제대로 동작하지 않았다. 

sudo -s            ### 꼭 root 접속 필요(sudo 를 이용한 pip 를 화면 path 가 맞지 않는다. 

source /opt/py_envs/vtest/bin/activate 를 이용해서 해당 상태를 활성화 시킨다.


그리고 자신에게 필요한 패키지를 설치한다. 경우에 따라서는 아래 git 를 통해 소스를 다운받은 후에 

pip install -r requirements.txt

식으로 pip freeze  를 한 결과를 저장해둔 파일을 이용해 한 방에 설치할 수도 있다.



6. uwsgi 설치 및 설정 

uwsgi 는 Djanog 와 wsgi 방식으로 연동시켜준다.  Nginx 없이  uwsgi + Django 만으로도 실서비스가 가능하다. 그리고 uwsgi 도 어떠한 이유로 죽을 수 있고 경우에 따라서는 컴퓨터가 어떠한 이유로 죽어서 재부팅 할 수도 있다. 이를 위해 죽을 때 다시 살릴 수 있고 부팅할 때 자동으로 동작할 수 있도록 해야 하는데 이 때 사용하는게 요즘은 systemd 이다. 이 연동을 하기 위해 uwsgi를 Emperor Mode로 사용해야 한다. 


우선 uwsgi 를 설치한다.

# (virtualenv 를 이용한 상태가 아니어야 한다. ) 

sudo pip install uwsgi



uwsgi 환경 설정을 할 수 있는 파일 생성한다. (차후 다른 프로젝트도 같이 돌아가는 경우, 이 경로에 다른 이름으로 파일을 생성한다. _

sudo mkdir -p /etc/uwsgi/sites

cd /etc/uwsgi/sites/


## 환경설정 파일 생성

sudo vim [프로젝트명].ini    



==== [프로젝트명].ini ====
[uwsgi]

#한 서버에 여러 프로젝트 파일을 올린 경우, 이 port 가 절대 겹치면 안된다. 
# 아래 있는 socket의 .sock 파일 대신 Nginx와 연결할 때 사용할 수도 있다.
# 실제로 이 port 를 통해 외부에 접속할 수 있다. 
http-socket = :9001  
master=True
pidfile=/tmp/[프로젝트명].pid  

chmod-socket=666
socket=/tmp/uwsgi_[프로젝트명].sock  #Nginx 와 연동할 때 연결되는 부분이다. 
processes = 2  ## 생성된 process 개수, 일반적으로 process 개수와 맞게 생성한다.
vacuum=True
#max-requests=5000

### 해당 경로에 Django의 wsgi.py 경로가 있어야 한다. 
wsgi-file = /usr/share/nginx/[프로젝트명]/djanog내_경로/wsgi.py  

## request 할 때 body를 제외한 사이즈,  기본사이즈는 4k 인데, 16k 로 늘렸다. 
## datatable.js 를 매우 애용하는데, 이 때, 여려 옵션들을 이용하면 Get Method 인데도 엄청 많은 parameter 가 전달되어 
## 크게 늘렸다. 
buffer-size=65535  


virtualenv = /opt/py_envs/virtual_env를생성한 경로    ## 여기서는 /opt/py_envs/vtest
touch-reload = /usr/share/nginx/[프로젝트명]/djanog내_경로/wsgi.py
logto = /var/log/uwsgi/[프로젝트명].log
chdir=/usr/share/nginx/[프로젝트명]
logfile-chown=www-data
logfile-chmod = 644

## 실제 이 경로는 Django Project에서 어떤 곳에 static 이 위치에 있는지에 달려있다.
static-map = /static=/usr/share/nginx/[프로젝트명]/static  

========



위에서 tocuh-reload 는 서비스를 다시 시작하지 않아도 해당 파일의 수정일자에 변경이 있으면 자동으로 서비스가 동작하도록 하는 부분이다.  만일 다른 부분이 다 수정되어 있는데도, 해당 파일의 수정일자가 변경되지 않는다면 메모리에 올라간 시스템이 적용되지 않고 계속 적용된다. 
그래서 내경우는 wsgi.py 파일의 주석을 변경하고 git 에 commit 해 두고 나중에 git pull 할 때 자동으로 수정하도록 한다. 경우에 따라서는 version.txt 파일을 만들어 운영하는 것도 좋은 방법이라고 생각한다. 
딱히 해당 파일의 변경사항이 없을 때는
sudo touch  /usr/share/nginx/[프로젝트명]/djanog내_경로/wsgi.py
touch 명령어도 최종수정일자를 갱실해 주면 된다. 


다음은 위 ini 파일에서 로그 파일 까지의 디렉토리를 생성해 줘야 한다. 해당 파일이 없으면 에러가 발생하기 때문에 실행전에 꼭 log 디렉토리를 만들어 두어야한다. 

uwsgi 전용 log 파일 경로 생성

sudo mkdir -p /var/log/uwsgi

sudo touch  /var/log/uwsgi/[프로젝트명].log #touch 는 파일이 없는 경우 빈 파일을 생성해 주기도 한다. 

sudo chown  -R  www-data.www-data /var/log/uwsgi/


여기 까지 작업을 했다면 uwsgi 를 돌려볼 수 있다.
시작 
uwsgi  --uid www-data  --gid www-data  --ini /etc/uwsgi/sites/[프로젝트명].ini &

정지
uwsgi --stop /tmp/[프로젝트명].pid

으로 돌릴 수 있다. 에러가 발생하면 로그파일 생성한 곳( /var/log/uwsgi/[프로젝트명].log )으로 가서 로그 확인이 필요하다. 
꼭 시작 명령어로 돌렸으면 정지 명령어로 종료해야 한다.
( kill 명령어로 죽였다면 다시 돌릴려면 /tmp/[프로젝트명].pid 파일을 삭제해야 돌아간다. 해당 pid 파일이 있는 상태로 다시 시작을 시키면 pid 파일이 있어서 이미 프로세스가 돌아가고 있다고 생각해서 시작하지 않는다. ) 

http-socket 를 설정하고 방화벽(리눅스내 ufw 방화벽, 그리고 서비스에서 제공하는 방화벽 모두 open 되어야 한다.) 이 open 되어 있다면 외부에서 접속할 수 있다. 이 접속까지 되어야 다음 설정을 진행할 수 있다. 


7.   uwsgi 의  systemd 설정
uwsgi 도 프로그램이기 때문에 죽을 수 있고 재부팅 마다 시작 설정(uwsgi  --uid www-data  --gid www-data  --ini /etc/uwsgi/sites/[프로젝트명].ini &
 ) 을 하는 것을 정말 귀찮기 때문에 systemd 를 설정해 준다.

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


==== uwsgi.service ====

[Unit]
Description=uWSGI Emperor service
After=syslog.target

[Service]
ExecStart=/usr/local/bin/uwsgi  --emperor /etc/uwsgi/sites

Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]

WantedBy=multi-user.target 

========


ExecStart=/usr/local/bin/uwsgi  --emperor /etc/uwsgi/sites
에서 uwsgi 가 경로가 다르면 오류가 발생할 수 있다. 만일 그렇다면 which uwsgi 로 경로를 확인 할 수 있다.

설정 파일을 만들었으니 이제 systemd 에 부팅시에도 동작할 수 있도록 하자
sudo systemctl enable uwsgi # 부팅시 자동시작
(만일 부팅시 자동 시작을 막고 싶으면 sudo systemctl disable uwsgi  

이제
sudo service uwsgi 형태로 서비스를 관리 할 수 있다. 

서비스 시작
sudo service uwsgi start   # 이 명령어가 안된다면    sudo systemctl start uwsgi     로 사용할 것

서비스 중지
sudo service uwsgi stop   # 이 명령어가 안된다면    sudo systemctl stop uwsgi     로 사용할 것

서비스 재시작(stop + start)
sudo service uwsgi restart   # 이 명령어가 안된다면    sudo systemctl restart uwsgi     로 사용할 것

서비스 재로드(환경설정 파일만 재로딩)
sudo service uwsgi reload   # 이 명령어가 안된다면    sudo systemctl reload uwsgi     로 사용할 것


만일 uwsgi  --uid www-data  --gid www-data  --ini /etc/uwsgi/sites/[프로젝트명].ini &
로 프로세스가 돌아가고 있다면 sudo service uwsgi start   가 안될 수도 있으니 꼭 종료하고 동작시키자. 


8. nginx 설정

uwsgi 만으로도 서비스는 동작시킬 수 있지만, nginx 을 통해 보안기능을 좀더 확보하고, static 리소스(css, js, 이미지 파일들)를 접근하는데 더 안정적으로 동작하고,  여러 다양한 기능(gzip 기능 같은 것)을 이용할 수 있기 때문에 nginx 를 uwsgi 앞에 둔다. 
이렇게 nginx 를 사용하는 경우, reverse proxy 를 사용한다고 합니다. 

우선 로그 포멧 및 gzip 사용을 위해 아래 주소에 로그 포맷을 추가 한다. 

sudo vim /etc/nginx/nginx.conf

 

==== nginx.conf ====

http{


    ## gzip 관련 주석 해제

    gzip on;

  gzip_disable "msie6";

   

  gzip_vary on;

  gzip_proxied any;

  gzip_comp_level 6;

  gzip_buffers 16 8k;

  gzip_http_version 1.1;

  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;


   …….


     log_format  post_log '$remote_addr - $remote_user [$time_local]    "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                       '"$http_user_agent" $request_time "$request_body"'



     …


}


========


log_format   의 경우 필요없는 경우 추가 할 필요 없다. 해당 코드는 웹에서 Post method 로 보낼 때에도 log 파일이 보일 수 있도록 하는 설정에 대한 포멧이다. 여기서 설정을 했다고 해서 post_log 가 보이는 것은 아니고 그냥 포멧을 지정하는 것이기 때문에 우선 추가한다. 



만일 SSL 인증서를 적용하는 경우라면 해당 인증서에 나와있는 가이드와 아래 코드와 적절히 조화가 필요하다. 이 부분은 case 가 너무 많은지라 가이드 하기 어렵다.... 


이제 /etc/nginx/sites-available/

내에 실제 설정 파일 추가한다. 따로 설정파일이 없는 경우 /etc/nginx/sites-available/default   파일의 설정대로 동작한다. 


설정파일이름은 프로젝트명으로 하기보다는 domain 으로 많이 이용하는 편이다. 그런데 거기에 따른 영향이 딱히 없기 때문에 그냥 구별할 수 있을 정도로 정하면 된다.

vim /etc/nginx/sites-available/[프로젝트명 또는 domain]


==== [프로젝트명 또는 domain ]
server {
    listen 80;
    server_name [domain];
    client_max_body_size 100M; ## 크기가 작을 경우 업로드 할 때 제한이 생길 수 있다. 

    root /usr/share/nginx/[프로젝트명]/;
    access_log /var/log/nginx/[프로젝트명]_access.log;
    access_log /var/log/nginx/[프로젝트명]_post.log   post_log;

    error_log /var/log/nginx/[프로젝트명]_error.log;

    location /static/ {
        alias /usr/share/nginx/[프로젝트명]/static/;   ## django 내 static 경로를 맞춰야 한다. 
    }

    location / {
        uwsgi_pass unix:/tmp/uwsgi_[프로젝트명].sock;
        include uwsgi_params;
    }

    
}

 


 access_log /var/log/nginx/[프로젝트명]_post.log   post_log;

이 부분이 들어갈 경우 Post Method 가 들어가 있는 부분에 로그가 출력되기 때문에 로그파일이 꽤 크게 생성된다.

내 경우 테스트 서버의 경우 디버깅을 위해 넣는다. (사내에서만 돌아가는 서비스 인 경우에도 넣는 편이다. ) 
실서버의 경우 굳이 해당 부분을 넣을 필요가 없을 것 같다. 


listen 80;
이 부분은 열리는 포트이다. 일반적으로 80포트이나, SSL 이 이용되는 경우 443 포트를 이용할 수 있다. 

server_name 은 실제 사용하는 domain, 없는 경우 public ip 주소를 사용할 수 있다. server_name 을 여러가 나열하거나 domain 과 ip 를 같이 사용할 수 도 있다.  그럴 경우   
server_name  www.labstoo.com   imglst.labstoo.com    m.labstoo.comm;
이런 식으로 옆으로 나열 하면 된다.

uwsgi_pass 부분은 uwsgi 에서 만든 sock 파일과 매칭되어야 정상적으로 동작한다. 

이제 nginx 를 돌려보자. nginx 는 설치시 자동으로 service 로 등록되기 때문에 serivce 명령어를 사용할 수 있다. 

시작
 sudo service nginx start

종료
 sudo service nginx stop

웹브라우저로 접속시 503 에러가 나면 nginx 에서 uwsgi 연결이 잘못된 것이다.



8. (옵션) 로그 관리 설정

서버를 운영하다보면 많은 로그가 생성된다. 이 경우 로그파일이 크면 서비스가 동작하지 않을 수도 있다. (로그파일을 만들지 못해 서비스가 동작하지 않는 경우가 있다. hard 가 작은 경우 이런 case 를 몇 번 겪어 봤다.) 

그래서 로그를 압축하고 너무 오래된 로그는 지우도록 설정한다. 

uwsgi 의 경우 이미 되어 있는 설정이 없기 때문에 설정이 필요하다. 

로그 관리의 경우 /etc/logrotate.d  내 설정이 되어 있다.

nginx 의 경우 이미 로그 설정이 되어 있다. 그러나 기본적인 설정이기 때문에 설정변경이 필요하다. 

sudo vim /etc/logrotate.d/nginx


==== nginx ====

/var/log/nginx/*.log {

        daily

        missingok

        rotate 30

        compress

        delaycompress

        notifempty

        create 0640 www-data adm

        sharedscripts

        prerotate

                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \

                        run-parts /etc/logrotate.d/httpd-prerotate; \

                fi \

        endscript

        postrotate

                invoke-rc.d nginx rotate >/dev/null 2>&1

        endscript

        dateext

}

 ========


dialy 는 파일이 나눠어 지는 시간단위 이다.   daily / weekly/ monthly  같이 사용할 수 있다. 

rotate 의 경우 로그파일을 관리할 개수이다. dialy 로 관리되기 때문에 30일 까지 관리된다.

dateext 는 파일이 따로 분리 될 때  날짜를 확장자로 사용하겠다는 의미이다. 



다음은 uwsgi 용 로그 설정이 필요하다. uwsgi 의 경우 생성되는 파일이 없어서 생성해야 한다.

 sudo vim /etc/logrotate.d/uwsgi


==== uwsgi ====
"/var/log/uwsgi/*.log" "/var/log/uwsgi/*/*.log" {
  copytruncate
  daily
  rotate 30
  compress
  delaycompress
  missingok
  notifempty
  dateext
}

========


로 설정하면 된다.


logrotate 의 경우 해당 동작이 crontab 에 의해 동작한다.  

(/etc/cron.daily/logrotate 파일이 존재한다. ) 





모든 설정이 끝났다. 혹시 추가 사항이 있는 경우 계속 최종수정일을 고쳐가면서 수정하도록 하겠다. 
혹시 잘못된 설정이나 더 좋은 방법 있으면 댓글을 남겨두기 바란다. 


최종수정일  2018년 03월 02일