'잡다한 프로그래밍'에 해당되는 글 6건

스파크 임시

NLP 2018. 4. 18. 17:54

모든 스파크 애플리케이션은 클러스터에서 다양한 병렬 연산을 수행하는 드라이버 프로그램으로 구성되어있다.


드라이버 프로그램들은 연산 클러스터에 대한 연결을 나타내는 SparkContext 객체를 통해 스파크에 접속한다.

쉘에서 이 SparkContext 객체는 자동으로 sc라는 변수에 만들어진다.


SparkContext 객체를 하나 만들었다면 그것으로 RDD를 만들어 낼 수 있다.

전 포스트에서 쓴 코드를 보면 텍스트파일 각 라인을 표현하는 RDD를 만들기 위해

sc.textFile()을 호출했었다. 그러고 나면 그 라인에 count() 같은 다양한 연산을 수행해 볼 수 있다.


이런 연산들을 수행하기 위해 드라이버 프로그램들은 보통 Executor(익스큐터)라 불리는 다수의 노드를 관리한다.




위의 사진은 스파크의 분산 실행을 위한 컴포넌트의 모양새이다 (출처: 러닝 스파크)


스파크가 클러스터에서 어떻게 실행되는지 알 수 있다.

'NLP' 카테고리의 다른 글

Spark RDD란 무엇인가?  (923) 2018.04.18
Spark를 설치 실행해보자  (934) 2018.04.18
파이썬으로 텍스트 마이닝 하기 (쓰는중..)  (1347) 2018.04.16
블로그 이미지

ZeroFlag

,

Spark RDD란 무엇인가?

NLP 2018. 4. 18. 16:23

RDD란 무엇인가?


R(Resilient)

D(Distributed)

D(Dataset)


R <- 데이터 손실 문제발생 시 다시 생성할 수 있다. (유실된 파티션을 재연산해 복구한다)

D <- 메모리를 이용하여 분산처리를 한다.

D <- 파일을 통해 가져올 수 있는 데이터셋 제공


따라서 Spark에서 제공하는 RDD라는 놈은 Spark에서 기본적인 데이터 단위라고 볼 수 있다.

(분산되어 있는 컬렉션)



자 그럼 RDD를 생성하여 보자


Spark QuickStart 에서보면 예제가 바로 나온다.


자 그럼 스파크를 실행시키고 예제를 한줄 한줄 입력하여 어떠한 결과가 나오는지 알아보자


# lines라는 RDD를 README.md 파일을 가져와서 만든다. (txtFile)

Scala : val lines = sc.textFile("README.md")

Python : lines = sc.textFile("README.md")

-출력결과 --> lines: org.apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[1] at textFile at <console>:24


# lines에 할당된 아이템의 갯수를 센다.

Scala : lines.count()

Python : lines.count()

-출력결과 --> res0: Long = 103


# lines에 있는 첫번째 라인에 해당하는 아이템을 불러온다.

Scala : lines.first()

Python : lines.first()

-출력결과 --> res1: String = # Apache Spark


! : 스파크 쉘이 구동될때 자동으로

SparkContext 생성후 sc라는 변수에 할당을 해준다.


그래서 sc를 직접 선언하지않고 사용할 수 있다.

sc변수가 어떻게 선언되었는지 알고싶으면 터미널에 sc를 입력하면 알 수 있다.

-출력결과 --> res2: org.apache.spark.SparkContext = org.apache.spark.SparkContext@69ed96e1



'NLP' 카테고리의 다른 글

스파크 임시  (1378) 2018.04.18
Spark를 설치 실행해보자  (934) 2018.04.18
파이썬으로 텍스트 마이닝 하기 (쓰는중..)  (1347) 2018.04.16
블로그 이미지

ZeroFlag

,

1. Spark 다운로드 하기


http://spark.apache.org/downloads.html


위 주소를 브라우저 주소창에 입력한다.



위와 같은 창이 뜬다면 맞게 들어온 것이다.


보면 1,2,3,4 단계로 나뉘는데

3단계 까지만 하면 된다.


1. 자신이 원하는 스파크의 버전을 나타낸다.

   콤보 박스 형태이기 때문에 마우스로 클릭해서 고를 수 있다.


2. 같이 설치할 하둡의 버전을 나타낸다

    마찬가지로 콤보 박스 형태로나온다.


3. 선택이 끝나면 3번에 있는 파란색 텍스트를 클릭하면 다운로드 페이지로 넘어가게 된다.




이런 페이지가 뜨는데 맨 위 미러링크를 클릭하면 파일을 다운로드 하게 된다.



2. 스파크 압축풀기


다운르드가 완료되면 spark-2.3.0-bin-hadoop2.7.taz 라는 파일이 생성되어 있을 것이다.


맥일 경우 대부분 다운로드에 저장이되는데 다운로드 파일을 자신이 지정한 디렉토리로 옮겨주면 된다.


필자는 다운로드후 바탕화면에 Spark 라는 디렉토리를 생성하여 옮겨주었다.


그리고 압축을 풀어준다.


압축을 풀어주는 방법은 간단한데 


tar -xf spark-2.3.0-bin-hadoop2.7.tgz


위의 명령어를 입력하면 쉽게 압축이 풀릴 것이다.


압축을 풀고나면 ls 명령어를 통해 파일들이 멀쩡하게 있는지 확인해보자


LICENSE README.md conf jars python

NOTICE RELEASE data kubernetes sbin

R bin examples licenses yarn


이런식으로 나타난다면 정상이다.



3. 스파크를 실행해보자


스파크는 Scala 또는 Python을 사용하여 실행할 수 있다.

(만일 현재 보고있는 경로가 압축을 풀고난 디렉토리가 아닐경우 경로를 이동해주어라)

(명령어 : cd spark-2.3.0-bin-hadoop2.7 을 입력하면 된다.)


파이썬을 이용한 쉘을 열려면

bin/pyspark


Scala를 이용한 쉘을 열려면

bin/spark-shell


실행후의 화면



이렇게 뜬다면 정상적으로 실행된것이다.

'NLP' 카테고리의 다른 글

스파크 임시  (1378) 2018.04.18
Spark RDD란 무엇인가?  (923) 2018.04.18
파이썬으로 텍스트 마이닝 하기 (쓰는중..)  (1347) 2018.04.16
블로그 이미지

ZeroFlag

,

파이썬으로 가능한 기본적인 처리방법들


제 .1 방법 : 공란처리


영어나 한글 일본어 등등 텍스트의 경우 공란(Space Bar)는 단어와 단어를 구분하는 기능을 수행한다.

하지만 문자 입력의 실수, 또는 온라인 텍스트 수집 과정의 오류로 공란이 2개이상 발견되는 경우가 있다.

Ex(예) : 파이썬으로 가능한 기본적인 처리방법들 <- 정상

   : 파이썬으로  가능한 기본적은  처리방법들 <- 공란이 2개씩 쓰여진 문자열


2개 이상의 공란이 연달아 발견되는 경우 해당 공란을 1개로 축약시키는 방법이다.


코드는 간단하게 짤 수 있다.


# 입력하여 출력해본다.


str_text_before = '덩          기덕 쿵       더러러러 쿵 기덕 쿵          덕'

print(str_text_before)

출력결과 -->           기덕 쿵       더러러러 쿵 기덕 쿵         


# split() 처리를 통해 리스트로 만들어 준다.


str_text_after = str_text_before.split()

print(str_text_after)

출력결과 --> ['덩', '기덕', '쿵', '더러러러', '쿵', '기덕', '쿵', '덕']


# split() 처리가된 텍스트(리스트)를 join 함수를 이용하여 처리


complete_text = " ".join(str_text_after)

print(complete_text)

출력결과 --> 덩 기덕 쿵 더러러러 쿵 기덕 쿵 덕


이렇게 공란 처리가 가능하다.


제 .2 방법 : 대 소문자 통일하기


한국어 텍스트에서는 해당사항이 없지만, 영문의 경우에는 대.소문자를 구분한다.

영어의 경우 문장의 첫 단어의 첫문자, 거유명사의 첫 문자, 축양어인 경우 대문자를 사용하며

다른 경우는 소문자를 사용한다.

그러나 대문자는 문장의 특정부분을 강조하는 경우에도 종종 사용된다.


Ex(예)

'President Trump plays the trump.' <-- 이 문자열을 보면 앞의 트럼프는 대통령 트럼프를 나타내고

뒤의 트럼프는 트럼프 카드게임을 나타낸다.


이것을 어떻게 구분할까?

간단하게 하고싶다면 replace 를 사용하면 된다.


str_text = str_text.replace('Trump', 'Trump_unique')

print(str_text)

출력결과 --> President Trump_unique plays the trump.


이렇게 대통령 트럼프와 게임 트럼프를 구분할 수 있다.


이 외의 방법은

str_text = 'President Trump plays the trump.'

print(str_text)


for key in (('Trump', 'Trump_unique'), ('plays', 'uniquePlays')):

str_text = str_text.replace(*key)

print(str_text)


출력결과 --> President Trump_unique uniquePlays the trump.


이렇게 하면 여러개의 문자열을 한번에 변경 할 수 있다.


이렇게 구분이 가능해지면

이제 대문자로 하든 소문자로 하든 처리를 한다.


처리는 아주 간단하다 문자열 뒤에 lower()또는 upper()를 붙여주면 된다.


print(str_text.lower())

출력결과 --> president trump_unique uniqueplays the trump.


print(str_text.upper())

출력결과 --> PRESIDENT TRUMP_UNIQUE UNIQUEPLAYS THE TRUMP.


제 .3 방법 : HTML코드 제거하기


# &pos, &gt, &lt 등의 HTML 문자열을 제거하여 준다.

# 의존성 from bs4 import BeautifulSoup

Ex(예)


str_html = '&gt asdfasdfasdf &lt'


html_str = BeautifulSoup(str_html, 'html.parser').get_text()

print(html_str)

출력결과 --> asdfasdfasdf


이렇게 HTML에서 남은 찌꺼기를 처리할 수 있다.



제 .4 방법 : 특수문자와 숫자표현 제거하기


텍스트가 데이터에서는 숫자가 아닌 문자로 표현된 자료는 물론 숫자로 표현된 자료도 포함된다.

그렇다면 텍스트 데이터에서 숫자가 의미를 가질 수 있고 의미를 가지지 않을 수도 있다.

이게 상당히 애매한 문제인데 무조건적으로 숫자를 제거하면 정보의 왜곡될 가능성이 높다.


대부분 텍스트 마이닝을 적용한 상당수 연구자들은 숫자를 제거하거나, 모든 숫자를 하나로 통합하는 방식으로 또는 텍스트를 사전처리 적용을 한다.


숫자를 제거하고 제거안하고는 마이닝할 텍스트에 따라 다르다.


Ex(예)

str_text = 'President?#Trump!plays...the&^%trump.'

print(str_text)

출력결과 --> President?#Trump!plays...the&^%trump.


sub_text = re.sub('[^a-zA-Z]', ' ', str_text)

print(sub_text)

출력결과 --> President  Trump plays   the   trump


특수문자나 숫자가 있던자리에 공백이 덕지덕지 끼여있는데 위에있는 공란처리로

처리하면 될것이다.



제 .5 방법 : 불용어 처리하기


모든 인간의 자연어는 외부 세계 대상에 대한 지시어와 이 지시어들을 연결하는 기능어가 존재한다.

예를들어 I am a boy 와 같은 문장에서 a라는 단어는 boy라는 명사가 셀 수 있는 명사임을 알려주는 기능을 한다.

흔히 boy라는 명사는 구체적인 의미를 전달하는 경우가 많지만, a라는 부정관사에서는 구체적인 의미를 찾기 쉽지 않다.

한국어 역시 마찬가지이다. "나는 남자다." 라는 문장에서 '남자'는 명사 형태의 어간은 의미를 갖지만, '다' 라는 서술격 조사에서는 의미론적으로 특별한 의미를 찾기 쉽지 않다.


영어의 경우 a, an, the 등과 같이 빈번하게 사용되나 구체적인 의미를 찾기 어려운 단어들을 불용어

라고 부른다.


고로 문장에서 의미가 딱히없는 단어들을 제거하는 방법을 알아보자


Ex(예)

STOPWORDS = ['a','able','about','across','after','all','almost','also','am','among',

'an','and','any','are','as','at','be','because','been','but','by','can','cannot',

'could','dear','did','do','does','either','else','ever','every','for','from','get',

'got','had','has','have','he','her','hers','him','his','how','however','i','if','in',

'into','is','it','its','just','least','let','like','likely','may','me','might','most',

'must','my','neither','no','nor','not','of','off','often','on','only','or','other','our',

'own','rather','said','say','says','she','should','since','so','some','than','that','the',

'their','them','then','there','these','they','this','tis','to','too','twas','us','wants',

'was','we','were','what','when','where','which','while','who','whom','why','will','with',

'would','yet','you','your','ourselves','between','yourself','again','once','during','out',

'very','having','yours','such','itself','s','each','themselves', 'until', 'below','through',

'don','more','himself','down','above','both','up','ours','before','same','yourselves','over',

'now','under','herself','myself','those','few','t','being','theirs','against','doing','further','here']


def remove_stop_words(wordlist, stopwords=STOPWORDS):

marked = []

# ask for sentence if wordlist is empty

if not wordlist:

sentence = raw_input("type a sentence: ")

wordlist = sentence.split()

for key in wordlist:

if key.lower() in stopwords:

# marked.append('')

pass

else:

marked.append(key)

return marked



wordlist = 'President Trump between plays the trump.'.split()


marked_list = remove_stop_words(wordlist)

print(marked_list)


complete_text = " ".join(marked_list)

print(complete_text)


대략적인 불용어 처리가 이렇게 할 수 있다.

'NLP' 카테고리의 다른 글

스파크 임시  (1378) 2018.04.18
Spark RDD란 무엇인가?  (923) 2018.04.18
Spark를 설치 실행해보자  (934) 2018.04.18
블로그 이미지

ZeroFlag

,

hello.c File

#include <stdio.h>


int main()

{

printf("hello world\n");

return 0;

}


1.1 정보는 비트와 컨텍스트로 이루어 진다.


hello 프로그램은 프로그래머가 에디터로 작성한 소스 프로그램이다.

이 프로그램은 소스파일로 생명을 시작하며, hello.c라는 텍스트 파일로 저장된다.

소스 프로그램은 0과 1로 표시되는 비트들의 연속이며, 바이트라는 8비트 단위로 구성된다.

각 바이트는 프로그램의 텍스트 문자를 나타낸다.


대부분 문자들은 ASCII 표준을 사용하여 표시한다.

아스키 표준은 각 문자를 바이트 길이의 정수 값으로 나타낸다.

예를들면 65는 A 66은 B 이런식으로 나타낸다.


이는 C 자료형인 char형과 int형에 대해 형변환을 시켜보면 알 수 있다.


hello.c 처럼 오로지 아스키 문자들로만 이루어진 파일들을 텍스트 파일이라고 부른다.

그 외 다른 0과 1로 이루어진 파일들은 바이너리 파일이라고 한다.


hello.c 의 표시방법은 기본개념을 분명히 보여준다.

모든 시스템 내부의 정보 디스크파일, 메모리 상의 프로세스, 데이터, 네트워크를 통해 전송되는 데이터는 비트들로 표시된다.

서로다른 객체들을 구분하는 유일한 방법은 이들을 바라보는 컨텍스트에 의해서다.

일례로 다른 컨텍스트에서는 동일한 일련의 바이트가 정수, 부동소수, 문자열 또는 기계어 명령을

의미할 수 있다.


1.2 프로그램은 다른 프로그램에 의해 다른 형태로 번역된다.

hello.c 프로그램은 인간이 그 형태로 바로 이해하고 읽을 수 있기 때문에 고급 C 프로그램이다.

그러나 hello.c를 시스템에서 실행시키려면, 각 C 문장들은 다른 프로그램들에 의해

저급 기계어 명령으로 번역되어야 한다. 이 기계어들은 실행 가능한 목적 프로그램이라는 형태로

합쳐져서 바이너리 디스크 파일로 저장된다.

목적 프로그램은 실행가능 목적 프로그램이라고도 불린다.


컴파일러 드라이버는 유닉스 시스템에서 다음과 같이 소스파일에서 오브젝트 파일로 번역한다.

$> gcc -o hello hello.c

여기서 gcc는 컴파일러 드라이버이다.

gcc 컴파일러는 소스파일 hello.c를 읽어서 실행파일인 hello로 번역한다.

이 번역과정은 총 4개로 분류되는데 아래에서 알아보자


1.3 컴파일 시스템

컴파일 시스템은 총 4가지 과정을 거친다.

_1. 전처리 단계 : 전처리기 는 본래의 C 프로그램을 #문자로 시작하는 디렉티브에 따라 수정한다.

  예를 들어 hello.c 파일 첫 줄의 #include<stdio.h.>는 전 처리기에게 시스템 헤더

  파일인 stdio.h를 프로그램 문장에 직접 삽입하라고 지시한다. 그 결과 일반적으로

  .I 의 확장자로 끝나는 새로운 C프로그램이 생성된다.

_2. 컴파일 단계 : 컴파일러는 텍스트파일 hello.i를 텍스트파일인 hello.s로 번역하며,이 파일에는

   어셈블리어 프로그램이 저장된다.

   이 프로그램은 다음과 같은 main 함수의 정의를 포함한다.

  1 main:

  2    subq        $8, %rsp

  3    movl        $.LCO, %edi

  4    call           puts

  5    movl        $0, $eax

  6    addq        $8, %rsp

  7    ret

ret 은 모든 함수가 시작될때 만들어지는 함수의 포인터이며 함수가 리턴하거나 끝났을때

다시 돌아오는 스택상의 주소이다.


_3. 어셈블리 단계 : 다음에는 어셈블러가 hello.s를 기계어 명령어로 번역하고, 이들을 재배치

      가능한 목적프로그램의 형태로 묶어서 hello.o라는 목적파일에 그 결과를

      저장한다.

      이 파일은 메인함수의 명령어들을 인코딩하기 위한 17바이트를 포함하는

      바이너리 파일이다.

      hello.o 파일을 텍스트 편집기로 열어보면 쓰레기같은 데이터로 보일 것이다.

_4. 링크단계 : hello 프로그램이 C 컴파일러에서 제공하는 표준 C 라이브러리에 들어있는 printf

      함수를 호출하는것에 주목할 필요가 있다.

      printf 함수는 이미 컴파일된 별도의 목적파일인 printf.o 에 들어 있으며,

      파일과 어떤 형태로든 결합되어야 한다. 링커 프로그램이 이러한 통합작업을 수행

      하며 그 결과 hello 파일은 실행가능 목적파일 즉 실행되어 메모리에 적재, 시스템에

      의해 실행되게 된다.


1.4 컴파일 시스템이 어떻게 동작하는지 이해하는것은 메우 중요하다.

hello.c  처럼 간단한 프로그램의 경우 컴파일 시스템이 정확하고 효율적인 기계어 코드를 만들어 줄 거라고 기대할 수 있다.

하지만 반드시 그리되리라는 보장은 어디에도 없다.


프로그램 성능 최적화하기:

최신 컴파일러들은 복잡한 도구로 대개 우수한 코드들을 생성한다.

프로그래머로서 효율적인 코드를 작성하기 위해서 컴파일 내부 동작을 알 필요는 없다.

하지만 C 프로그램 작성 시 올바른 판단을 하기 위해서는 기계어 수준 코드에 대한 기본적인 이해를

할 필요가 있으며, 컴파일러가 어떻게 C 문장들을 기계어 코드로 번역하는지 알 필요가 있다.


예를들면  switch 문은 if-else 삼항연산자 문을 연속해서 사용하는 것보다 언제나 더 효율적인가?

while 루프는 for 루프문 보다 더 효율적인가?

포인터 참조가 배열 인덱스보다 더 효율적인가? 등등 여러가지 의문을 가질때가 많다.


링크에러 이해하기: 

경험에 의하면 가장 당황스러운 프로그래밍 에러는 링커의 동작과 관련되어 있으며, 큰 규모의 소프트웨어 시스템을 빌드하려는 경우에 더욱 그렇다.

예를들면 링커가 어떤 참조를 풀어낼 수 없다고 할 때는 무엇을 의미하는가?

정적 변수와 지역변수의 차이는 무엇인가? 만일 각기 다른 파일에 동일한 이름의 두 개의 전역변수를 정의한다면 무슨일이 일어나는가? 정적 라이브러리와 동적 라이브러리의 차이는 무엇인가? 등등

왜 링커와 관련된 에러들은 실행하기 전 까지는 나타나지 않는것인가? 등등 이다.


보안 약점:

오랫동안 버퍼 오버플로우 취약성이 인터넷과 네트워크상의 보안 약점의 주요 원인으로 설명되었다.

이 취약성은 프로그래머들이 신뢰할 수 없는곳에서 획득한 데이터의 양과 형태를 주의깊게 제한해야 할 필요를 거의 인식하지 못하기 때문에 생겨난다.

안전한 프로그래밍을 배우는 첫 단계는 프로그램 스택에 데이터와 제어정보가 저장되는 방식 때문에

생겨나는 영향을 이해하는 것이다.


1.5 프로세서는 메모리에 저장된 명령어를 읽고 해석한다.

지금까지 hello.c 소스 프로그램은 컴파일 시스템에 의해 hello 라는 실행가능한 목적파일로 번역되어 디스크에 저장되었다.

이 실행파일을 유닉스 시스템에서 실행하기 위해서 쉘 이라는 응용프로그램을 그 이름에 입력한다.

$> ./ hello

hello world

$>

쉘은 커맨드라인 인터프리터로 프롬포트를 출력하고 명령어 라인을 입력받아 그 명령어를 실행한다.

만일 명령어 라인이 내장 쉘 명령어가 아니면 쉘은 실행파일의 이름으로 판단하고 그 파일을 로딩하여 실행해 준다. 그래서 이 경우에 쉘은 hello 프로그램을 로딩하고 실행한 뒤에 종료를 기다린다.

hello 프로그램은 메세지를 화면에 출력하고 종료한다.

그 후 쉘은 프롬포트를 출력해 주고 다음 입력 명령어 라인을 기다린다.


프롬포트란 무엇인가? : $ <--- 이 놈이 프롬포트이다

루트 권한일 경우 # 으로 표기된다.


1.5.1 시스템의 하드웨어 조직

hello 프로그램을 실행할 때 무슨 일이 일어나는지 설명하기 위해서는 전형적인 시스템에서의 하드웨어 조직을 이해할 필요가 있다.


버스 :

시스템 내를 관통하는 전기적 배선군을 버스라고 하며, 컴포넌트들 간의 바이트 정보들을 전송한다.

이 버스는 일반적으로 워드 라고 불리는 고정크기의 바이트 단위로 데이터 들을 전송한다.

한 개의 워드를 구성하는 바이트수는 시스템마다 보유하는 기본 시스템 변수이다.

대부분 컴퓨터들은 4바이트(32비트) 8바이트(64비트) 크기의 워드를 갖는다.

버스는 시스템버스 메모리버스 IO버스가 존재한다.


워드 : cpu가 한번에 처리할 수 있는 단위


입 출력 장치 :

입출력 장치는 시스템과 외부세계와의 연결을 담당한다.

예를들면 시스템은 입출력 장치를 가지고 있다.

입력용 키보드 마우스 웹캠 마이크 출력용 모니터, 디스크드라이브, 프린터 등등

처음에 실행가능 파일인 hello프로그램은 디스크에 저장되어 있다.

각 입출력 장치는 입출력 버스와 컨트롤러나 어댑터를 통해 연결된다.

이 두장치의 차이는 패키징에 있는데, 컨트롤러는 디바이스 자체가 칩셋이거나 시스템의 인쇄기판

(메인보드) 에 장착된다.

어댑터는 메인보드의 슬롯에 장착되는 카드이다.


메인 메모리 : 


이후 좀 쉬고와서 다시쓰겠슴


블로그 이미지

ZeroFlag

,

준비물 : 버추얼박스(오라클) / Vagrant


우선 홈 디렉토리로 이동합니다.

cd ~


작업 디렉토리를 생성합니다.

mkdir workspace


작업 디렉토로 이동

cd workspace


박스 디렉토리 이동

mkdir ubuntu17


Vagrantfile 생성

vi Vagrantfile


vi를 통해 아래의 문장을 작성합니다.

# -*- mode: ruby -*-

# vi: set ft=ruby :


# 가상환경 메모리와 cpu 코어

MEMORY = 4096

CPU_COUNT = 2

 

# Vagrant.configure(vagrantfile_api_version) do |config| <— config 정의

Vagrant.configure("2") do |config|

# 다운받을 os환경 박스위치

  config.vm.box = "bento/ubuntu-17.10” <— 정의한 config 사용

# 네트워크 포트포워딩 아웃

  config.vm.network "forwarded_port", guest: 80, host: 80

  config.vm.network "forwarded_port", guest: 8000, host: 8000

# 네트워크 IP 설정

  config.vm.network "private_network", ip: "192.168.123.45”

# 버추얼 박스 연동

  config.vm.provider "virtualbox" do |vb|

      vb.customize ["modifyvm", :id, "--memory", MEMORY.to_s]

      vb.customize ["modifyvm", :id, "--cpus", CPU_COUNT.to_s]

  end

end


다음문장을 insert 모드에서 Esc를 눌러 변경 후
:w 로 저장 후 :q를 하여 나가자
귀찮으면 :wq 동시에 써도 상관없다.

자 이제 Vagrant 를 작동시켜 보자
vagrant up 을 타이핑 하자

그럼 아래와 같은 로그가 뜨면서 실행이 될 것이다.

Bringing machine 'default' up with 'virtualbox' provider...

==> default: Importing base box 'bento/ubuntu-17.10'...

==> default: Matching MAC address for NAT networking...

==> default: Checking if box 'bento/ubuntu-17.10' is up to date...

==> default: Setting the name of the VM: ubuntu17_default_1516348815097_87757

==> default: Clearing any previously set network interfaces...

==> default: Preparing network interfaces based on configuration...

    default: Adapter 1: nat

    default: Adapter 2: hostonly

==> default: You are trying to forward to privileged ports (ports <= 1024). Most

==> default: operating systems restrict this to only privileged process (typically

==> default: processes running as an administrative user). This is a warning in case

==> default: the port forwarding doesn't work. If any problems occur, please try a

==> default: port higher than 1024.

==> default: Forwarding ports...

    default: 80 (guest) => 80 (host) (adapter 1)

    default: 8000 (guest) => 8000 (host) (adapter 1)

    default: 8001 (guest) => 8001 (host) (adapter 1)

    default: 22 (guest) => 2222 (host) (adapter 1)

==> default: Running 'pre-boot' VM customizations...

==> default: Booting VM...

==> default: Waiting for machine to boot. This may take a few minutes...

    default: SSH address: 127.0.0.1:2222

    default: SSH username: vagrant

    default: SSH auth method: private key

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: Warning: Connection reset. Retrying...

    default: Warning: Remote connection disconnect. Retrying...

    default: 

    default: Vagrant insecure key detected. Vagrant will automatically replace

    default: this with a newly generated keypair for better security.

    default: 

    default: Inserting generated public key within guest...

    default: Removing insecure key from the guest if it's present...

    default: Key inserted! Disconnecting and reconnecting using new SSH key...

==> default: Machine booted and ready!

==> default: Checking for guest additions in VM...

==> default: Configuring and enabling network interfaces...



The following SSH command responded with a non-zero exit status.

Vagrant assumes that this means the command failed!


/sbin/ifdown 'eth1' || true

/sbin/ip addr flush dev 'eth1'

# Remove any previous network modifications from the interfaces file

sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre

sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tac | sed -e '/^#VAGRANT-END/,$ d' | tac > /tmp/vagrant-network-interfaces.post


cat \

  /tmp/vagrant-network-interfaces.pre \

  /tmp/vagrant-network-entry \

  /tmp/vagrant-network-interfaces.post \

  > /etc/network/interfaces


rm -f /tmp/vagrant-network-interfaces.pre

rm -f /tmp/vagrant-network-entry

rm -f /tmp/vagrant-network-interfaces.post


/sbin/ifup 'eth1'


Stdout from the command:




Stderr from the command:


bash: line 4: /sbin/ifdown: No such file or directory

bash: line 20: /sbin/ifup: No such file or directory



에러가 없다면 다행이지만 이렇게 에러가 날 수도 있다.

자 그럼 에러를 처리해 보자


해결방법:

친절하게 한 외국인 양반이 여기에 대해 해결을 한 상태이다.

좌표 : https://github.com/cilium/cilium/issues/1918


우선 에러를 해결하기위해 버추얼박스에 실행되어 있는

ubuntu17 을 실행시킨다.


그럼 검은 콘솔화면에서 이놈이 가르쳐주지도 않은 ID와 PW를 요구한다.




당황하지 말자

ID : vagrant

PW : vagrant

이다.



올바르게 입력하면  Welcome to Ubuntu 라고 반겨준다.


자 이제 문제를 해결 하여야한다 아주 간단하다.

저 콘솔창에 sudo apt-get install ifupdown 을 입력한다.

이제 ifupdown 패키지가 설치된다.



이런식으로 에러없이 설치되면 잘 설치 된 것이다.


자 이제 이놈을 버추얼박스에서 종료하고 다시 터미널 창으로 이동하자.



자 이제 터미널 창에서 다시 vagrant up을 입력해보자



다음과 같이 정상동작 하는것을 볼 수 있을 것이다.


자 이제 본격적으로 접속 해 보자


vagrant ssh 를 입력해보자



잘 작동한다. 이제야 기본적인 vagrant 과정이 끝났다.

지금까지 만들어둔 환경을 보존하기위해 스냅샷을 찍어둔다.


참고 : vagrant 의 명령어가 몇개 더 존재한다.

일단 Dic으로 나열하여 설명하겠습니다.


Vagrantfile : vagrant 의 기본 세팅파일

vagrant up : vagrant 의 기본 세팅파일에 명시된 기준으로 vagrant를 실행 (가상머신을 실행한다)

vagrant halt : vagrant 종료 (가상머신을 완전히 종료한다.)

vagrant reload : vagrant 재부팅 이라고 보면된다.

vagrant ssh : vagrant 내의 가상머신을 연결한다.


자 이제 본격적으로 Django + uwsgi + nginx 를 연동하여 웹 서버에 기본적으로 빌드 해 보자

vagrant ssh (vagrant box) 에서 진행합니다.


홈 디렉토리로 이동

cd ~


프로젝트 디렉토리 생성

mkdir project


프로젝트 디렉토리 이동

cd project


virtualenv 설치

sudo apt-get install virtualenv


설치가 완료되면

virtualenv를 통해 python3 구축

virtualenv -p python3 venv

: 다음 명령어를 실행하면 venv 라는 폴더가 만들어 진다.


virtualenv 활성화

source venv/bin/activate

. venv/bin/activate

위 / 아래 둘 중 하나를 사용하면 된다.

사용시 터미널 커서경로 쪽에

(venv) 경로$ 로 커서가 보일 것이다.


pip3를 설치합니다 (없다는 가정하에 - 있으면 상관없다)

sudo apt-get install python3-pip


Django 를 설치한다 (현재 필자가 사용하는 버전은 : version 2.0.1 이다.)

pip3 install Django


django 프로젝트를 생성해보자

jango-admin.py startproject main

: 다음 명령어를 실행하면 main라는 디렉터리가 만들어 질 것입니다.


Django 프로젝트로 이동

cd main


ls -al 명령어를 실행해보면

메인 디렉토리에는 main과 manage.py 가 있을 것입니다.


uwsgi 설치

pip3 install uwsgi


python <-> uwsgi 연동 테스트를 위한 파일 생성

touch test.py

vi test.py


아래에 내용을 적어준다.

def application(env, start_response):

    start_response('200 OK', [('Content-Type','text/html')])

    return [b"Hello World"] # python3


대략적인 내용은 이렇다

리퀘스트를 날려서 돌아오는 리스폰을 받으면 Hello Wrold를 반환하라는 의미이다.


여튼 입력 후 저장한다


주의 : 포트가 겹칠경우 문제가 발생할 수 있습니다.

python <-> uwsgi 연동테스트

uwsgi --http :8000 --wsgi-file test.py




이제 django를 테스트해볼까요

우선 djnago를 테스트하기 전 django 세팅을 조금 맞춰줘야 합니다.


vi main/settings.py

위 명령어를 실행하면 세팅목록이 쭉 보입니다.

그 중 ALLOWED_HOSTS = [ ] 가 보입니다.


이 ALLOWED_HOSTS 는 IP나 포트의 접근제한을 할 수 있는 영역입니다.

우선 테스트니 모든제한을 풀어줍니다.

ALLOWED_HOSTS = ['*']


저장하고 나왔다면 테스트를 해 보자

python3 manage.py runserver 0.0.0.0:8000

제대로 진행되었다면 아래와 같이 잘 실행되고 있음을 확인할 수 있습니다.


django <-> uwsgi 연동 테스트

uwsgi --http :8000 --module main.wsgi


위와 같이 뜬다면 정상적으로 작동하고 있는것이다.


nginx 를 설치해보자

sudo apt-get install nginx


nginx 실행

sudo service nginx restart


nginx 실행상태 확인

sudo service nginx status


nginx 설정파일 생성하기

touch main_nginx.conf

vi main_nginx.conf


# mysite_nginx.conf


# 미들웨어에 연결하는 통신방법 포트통신 소켓통신 있는데

# 소켓통신으로 하겠다고 선언

# the upstream component nginx need to connect to

upstream django {

        server unix:///tmp/main.sock; # for a file socket

        #server 127.0.0.1:8001; # for a web port socket (we'll use this first)

        }


# configuration of the server

server {

# 포트 8000번대 리슨으로

# main_nginx.conf 이동

# 이것을 uwsgi 보내고

# 소켓통신을

        #the port your site will be served on

        listen  8000;

        # the domain name it will serve for

        server_name mroom.kr; # substitute your machine's IP address or FQDN

        charset utf-8;


        # max upload size

        client_max_body_size 75M;       #adjust to taste

        #client_max_body_size 4G;

        #keepalive_timeout 5;


        # Django media

        location /media {

                # your Django project's media files - amend as required

                alias /home/vagrant/project/main/media;

        }


        location /static {

                # your Django project's static file - amend as required

                alias /home/vagrant/project/main/static;

        }


        # Finally, send all non-media requests to the Django server.

        location / {

                uwsgi_pass django;

                # the uwsgi_params file you installed

                include /home/vagrant/project/main/uwsgi_params;

        }

}


심볼릭 링크를 만들어 이어준다. available <--- 저장고 같은 존재이다.

sudo ln -s /home/vagrant/project/main/main_nginx.conf /etc/nginx/sites-available/


vi 를 이용하여 settings.py 에 다음을 추가한다.

vi main/settings.py


STATIC_ROOT = os.path.join(BASE_DIR, "static/")


static 콜렉터를 사용

python3 manage.py collectstatic


static collect를 하는 이유 : 

원래 프로젝트 하단에 static 을 두는게 아니라 기본적으로

어플리케이션 하단에 static 디렉토리를 두어야 한다.

manage.py runserver를 실행하면 하단에 위치한 static 디렉토리를 읽어서

css, js 같은 애들을 불러오는데 wsgi는 어플리케이션마다 static폴더를 인식하지 못하기 때문에

존재하는 모든 static들을 한곳으로 모아주고 거기를 포인트하는 역할을 한다.


Reference : http://blog.hannal.com/2015/04/start_with_django_webframework_06/


아래와 같은 로그가 뜬다.


Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Regular-webfont.woff'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Light-webfont.woff'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/README.txt'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Bold-webfont.woff'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/LICENSE.txt'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-unknown.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-changelink.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-alert.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-deletelink.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/sorting-icons.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/LICENSE'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-clock.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/inline-delete.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-no.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-calendar.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-addlink.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/README.txt'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/selector-icons.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/search.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-unknown-alt.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/tooltag-add.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/calendar-icons.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-yes.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/tooltag-arrowright.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_off.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_on.svg'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/SelectFilter2.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/actions.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/cancel.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/timeparse.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/core.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/collapse.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/actions.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/popup_response.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/jquery.init.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/inlines.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/inlines.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/autocomplete.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate_init.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/change_form.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/calendar.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/SelectBox.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/collapse.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/urlify.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/LICENSE-XREGEXP.txt'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/xregexp.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/xregexp.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/select2.full.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/select2.full.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/LICENSE-SELECT2.md'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/mk.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/en.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ru.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/vi.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hr.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fa.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sr.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/zh-CN.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/zh-TW.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/el.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/he.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sk.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ca.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/da.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/gl.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/de.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pt-BR.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/es.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hi.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/it.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sr-Cyrl.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fi.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/az.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ja.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/is.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/km.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/tr.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/cs.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ro.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sv.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/bg.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ko.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fr.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/nl.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hu.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/eu.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ms.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/lt.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/th.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/lv.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pl.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/nb.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/et.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pt.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/id.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ar.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/uk.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/LICENSE-JQUERY.txt'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.min.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/fonts.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/responsive.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/dashboard.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/widgets.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/forms.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/autocomplete.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/login.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/base.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/responsive_rtl.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/rtl.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/changelists.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/select2.min.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/select2.css'

Copying '/home/vagrant/project/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/LICENSE-SELECT2.md'


그리고 static 디렉토리가 만들어지고, 디렉토리 안에는 admin 파일이 생성되어 있을 것이다.


media 폴더를 만들어 준다.

mkdir media


uwsgi_params 를 만들어 준다.

touch uwsgi_params

vi uwsgi_params


아래 내용을 입력하고 저장한다.

uwsgi_param  QUERY_STRING       $query_string;

uwsgi_param  REQUEST_METHOD     $request_method;

uwsgi_param  CONTENT_TYPE       $content_type;

uwsgi_param  CONTENT_LENGTH     $content_length;


uwsgi_param  REQUEST_URI        $request_uri;

uwsgi_param  PATH_INFO          $document_uri;

uwsgi_param  DOCUMENT_ROOT      $document_root;

uwsgi_param  SERVER_PROTOCOL    $server_protocol;

uwsgi_param  REQUEST_SCHEME     $scheme;

uwsgi_param  HTTPS              $https if_not_empty;


uwsgi_param  REMOTE_ADDR        $remote_addr;

uwsgi_param  REMOTE_PORT        $remote_port;

uwsgi_param  SERVER_PORT        $server_port;

uwsgi_param  SERVER_NAME        $server_name;


nginx 재시작
sudo service nginx restart

저장 창고에만 부여해주지 말고 실제로 동작하는 enabled에 링크를 넣어주자

sudo ln -s /home/vagrant/project/main/main_nginx.conf /etc/nginx/sites-enabled/


소켓을 이용한 uwsgi <-> test.py 연동테스트

uwsgi --socket /tmp/main.sock --wsgi-file test.py --chmod-socket=666




소켓을 이용한 uwsgi <-> django 연동테스트

uwsgi —socket /tmp/main.sock —module main.wsgi —chmod-socket=666



main_uwsgi.ini 만들어준다.

vi main_uwsgi.ini


[uwsgi]

chdir           = /home/vagrant/project/main

module          = main.wsgi

home            = /home/vagrant/project/venv

master          = true

processes       = 1

socket          = /tmp/main.sock

chmod-socket    = 666

vacuum          = true


입력 후 저장합니다.


ini 파일을 이용한 uwsgi <-> django 연동테스트

uwsgi --ini main uwsgi.ini



가상환경 비활성화

deactivate


uwsgi 시스템 전역에 설치하기

sudo pip3 install uwsgi


가상환경이 비활성화된 상태에서 ini파일을 이용한 uwsgi <-> django 연동테스트

uwsgi --ini main_uwsgi.ini



여기까지 되면 venv 가상환경 없이 실행이 가능해 진다.


엠페러 모드 설정을 위한 디렉토리 생성

sudo mkdir /etc/uwsgi

sudo mkdir /etc/uwsgi/vassals


엠페러 모드 설정을 위한 심볼릭 링크 생성

sudo ln -s /home/vagrant/project/main/main_uwsgi.ini /etc/uwsgi/vassals/

엠페러 모드로 uwsgi 실행 (권한상관없이 둘다 가능할 것이다.)

sudo uwsgi --emperor /etc/uwsgi/vassals/ --uid www-data --gid www-data

uwsgi --emperor /etc/uwsgi/vassals/ --uid www-data --gid www-data


로그 저장소 만들어 주기

touch /var/log/uwsgi-emperor.log


백그라운드에서 실행하기

sudo /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log


시스템 실행 확인하기

ps -ef | grep uwsgi


시스템 부팅 시 자동실행 설정

sudo vi /etc/rc.local

#!/bin/sh

sudo /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log

exit 0


우분투는 rc.local 서비스를 기본적으로 지원하지 않으니 트러블 슈팅을 참고

sudo vi /lib/systemd/system/rc-local.service

[Install]

WantedBy=multi-user.target

추가한다.


rc.local 권한 변경

sudo chmod +x /etc/rc.local

rc.local 활성화

sudo systemctl enable rc-local

rc.local 시작

sudo systemctl start rc-local.service

rc.local 상태확인

sudo systemctl status rc-local.service


서버 자동켜기 스크립트

#!/bin/sh

sudo /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log


오늘은 여기까지

블로그 이미지

ZeroFlag

,