내 포트폴리오 사이트 만들어서 AWS에 올리기 2편. docker, nginx, uwsgi 사용하기

     

 

유튜브 - 

 

 

목차

2022.05.08 - [Study/python] - 내 포트폴리오 사이트 만들어서 AWS에 올리기 1편. Django, startbootstrap, AWS, EC2

2022.05.08 - [Study/python] - 내 포트폴리오 사이트 만들어서 AWS에 올리기 2편. docker, nginx, uwsgi 사용하기

 

 

지난 시간에 EC2위에 장고를 쌩으로 띄웠는데요, 이번 시간엔 docker와 nginx를 이용해서 보다 멋있게(?) 띄워보겠습니다. 이번엔 코딩보다는 devops영역이라고 할까? 설정을 만지는 부분이 많습니다.

 

시작해 볼까요?

 

uwsgi, nginx docker 설정

 

사실 이 부분은 이미 제 블로그에 자세하게 적혀있습니다.

서버개발자가 되는법 [2] - 서버 개발환경 셋팅, Nginx와 uWSGI 설치해서 연결하기 + docker로 mysql 띄우기 (tistory.com)

서버개발자가 되는법 [2_1] - django, nginx 도커로 구동하기 (tistory.com)

이론은 위에 블로그를 참고하시면 될 것 같습니다.

 

여기서는 우리가 만든 포트폴리오 장고 프로젝트를 uwsgi를 연결해서 docker로 띄우고, 또 다른 docker로 nginx를 띄우면 됩니다. 즉 docker를 두 개를 띄우는 건데, 하나는 nginx, 다른 하나는 장고 프로젝트(+uwsgi)입니다. 먼저 장고 쪽을 건드려봅시다. 

 

장고에 requirements.txt에서 uwsgi를 추가합니다. 나중에 docker를 만들면 자동으로 requirements.txt를 보고 패키지를 설치할 텐데, 여기에 uwsgi가 있어야 설치가 됩니다.

 

uwsgi 추가

터미널에서 문서 편집이 익숙하지 않으신 분이 있을 수 있는데,, vim을 활용하면 됩니다. vi requirements.txt 명령어를 입력하면 텍스트 에디터 화면이 뜨고, 여기서 i를 누르고 추가하면 됩니다. 추가가 끝나면 esc 누르고 :wq를 하면 저장하면서 종료됩니다. vim 활용법에 대해서는 구글링 하셔서 참고해주세요~!

 

이렇게 requirements.txt에 uwsgi를 추가했다면, 이제 uwsgi 설정을 만들어줍니다. 우리가 만든 프로젝트 안에 uwsgi.ini를 만듭니다.

여기에 만듭니다

파일을 만드는 것도 vi {파일 이름} 하면 만들어집니다. uwsgi.ini에 다음 내용을 적습니다.

 

[uwsgi]
socket = /srv/popol/apps.sock
master = true
processes = 1
threads = 2
chdir = /srv/popol
module = popol.wsgi
logto = /var/log/uwsgi/uwsgi.log
log-reopen = true
logfile-chmod = 664
vacuum = true
listen = 4000
ignore-sigpipe=true
ignore-write-errors=true
disable-write-exception
reload-on-rss = 128

 

제가 사용하던 세팅을 그대로 들고 와서 별 의미 없는 세팅도 있는데, 가장 중요한 것은 socket과 chdir입니다. socket은 uwsgi가 어떻게 웹서버와 통신할지 정하는 부분인데, 여기서는 파일 소켓을 사용할 예정입니다. 경로는 제맘대로 입력한 것인데 /srv/popol이라는 경로를 사용했습니다. chdir와 socket의 경로가 일치해야 합니다. 그리고 module에는 여러분의 프로젝트 이름. wsgi로 해주셔야 합니다. 저는 프로젝트 이름이 popol이기 때문에 popol.wsgi를 사용했습니다.

 

요렇게 uwsgi.ini 설정 파일을 만들었으면 Dockerfile을 만듭니다. uwsgi.ini와 같은 경로에 vi Dockerfile로 파일을 만들고 아래 내용을 입력합니다.

 

FROM python:3.7.9

ENV PYTHONUNBUFFERED 1

RUN mkdir /srv/popol

ADD . /srv/docker-server

WORKDIR /srv/docker-server

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

EXPOSE 80

 

자 이제 장고에 docker설정은 끝났습니다. 이제 프로젝트 폴더 밖으로 나와서 nginx를 세팅합니다. nginx라는 폴더를 만듭니다.

 

nginx 폴더 만들기

nginx에도 몇 개의 설정 파일이랑 Dockerfile을 만들어주면 되는데 일단 nginx.conf라는 파일을 만들고 아래를 입력합니다. 

user root;
worker_processes 1;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/sites-enabled/*;
}

 

아래는 nginx-app.conf

upstream uwsgi {
    server unix:/srv/popol/apps.sock;
}

server {
    listen 80;
    server_name localhost *.amazonaws.com;
    charset utf-8;
    client_max_body_size 128M;

    location / {
        uwsgi_pass      uwsgi;
        include         uwsgi_params;
    }

    location /media/ {
        alias /media/;
    }

    location /static/ {
        alias /static/;
    }
}​

 

upstream uwsgi에 들어가는 내용이 uwsgi.ini에서 socket이라고 선언했던 부분입니다. 이 소켓을 이용해서 nginx와 uwsgi가 통신하게 됩니다.

 

server {}에서는 static경로를 잡아준 거 특이한데, 요 static경로를 잡아주지 않으면 이미지가 안 뜨게 됩니다. 또 uwsgi를 사용하기 때문에 location /에서 uwsgi_pass라는 걸 사용하는데, 이건 uwsgi 말고 다른 걸 사용해서 nginx를 띄워보신 분한테는 생소할 수 있습니다. 

 

요롷게 기본 세팅 파일 두 개를 만들고 Dockerfile을 만듭니다.

 

FROM nginx:latest

COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx-app.conf /etc/nginx/sites-available/

RUN mkdir -p /etc/nginx/sites-enabled/\
    && ln -s /etc/nginx/sites-available/nginx-app.conf /etc/nginx/sites-enabled/

CMD ["nginx", "-g", "daemon off;"]

파일구조

nginx에 파일 3개를 만들었으면 이제 docker-compose파일만 만들면 됩니다. docker-compose는 도커들을 한꺼번에 관리할 수 있는 툴입니다. nginx폴더와 popol폴더 위에 docker-compose.yml파일을 만듭니다.

 

version: '3'
services:

    nginx:
        container_name: nginx
        build: ./nginx
        image: popol/nginx:v1
        restart: always
        network_mode: "host"
        ports:
          - "80:80"
        volumes:
          - ./popol:/srv/popol
          - ./log:/var/log/nginx
          - ./popol/static/:/static
        depends_on:
          - django
    django:
        container_name: django
        build: ./popol
        image: popol/django:v1
        restart: always
        command: uwsgi --ini uwsgi.ini
        volumes:
          - ./popol:/srv/popol
          - ./log:/var/log/uwsgi

 

설정 파일에 내용들은 docker-compose 공식문서를 보시면 알 수 있습니다. 여기서 중요한 건 

nginx:와 django: 두 개가 있는데 depends_on을 통해 django가 먼저 뜨고 nginx가 뜨게 되어있다는 점. 그리고 각각 volumes:에서 도커 안에 폴더와 서버의 폴더를 연동시켜주었다는 점이 중요합니다. 다른 건 거의 거의 기본 설정들이라서 docker-compose에 대해 따로 찾아보시면 쉽게 아실 수 있는 내용입니다.

 

자 이제 docker-compose를 실행시키면 되는데, ubuntu에 docker와 docker-compose가 설치가 안되어있습니다. 

 

먼저 도커 설치는 아래 명령어를 입력하면 됩니다.

 

curl -fsSL https://get.docker.com/ | sudo sh
sudo usermod -aG docker $USER # 현재 접속중인 사용자에게 권한주기

 

도커 컴포즈 설치는 아래 명령어를 입력합니다.

sudo curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

 

자 그럼 docker와 docker-compose를 입력하면 뭐라 뭐라 뜹니다. 여기서 docker-compose.yml파일이 있는 곳에서 docker-compose build를 입력해줍니다.

 

요래요래 설치합니다.

 

여기서 에러가 날 수 있는데, 권한이 없어서 그렇습니다. 위에서 sudo usermod -aG docker $USER # 현재 접속 중인 사용자에게 권한 주기 요거를 하고 나서 putty를 재접속하면 아마 정상적으로 실행이 될 거예요. 

 

build를 하면 nginx이미지랑 django이미지를 열심히 굽습니다. 처음 구울 때는 좀 오래 걸립니다. 다 구워졌으면 아래처럼 메시지가 뜹니다.

 

build 성공

 

자 이제 docker-compose up -d 명령어를 이용해 docker를 띄울 수 있습니다. 

 

실행중

docker-compose ps를 이용하면 현재 떠있는 docker의 상태를 볼 수 있습니다. 둘 다 Up으로 되어있으면 성공!

 

자 이제 다시 한번 포트폴리오에 접속해 볼까요?

 

잘 접속되쥬?

 

자 이제 아까와 다르게 쌩 장고가 아니라 웹서버인 nginx를 경유해서 장고가 실행 중입니다. log폴더에 가보면 access.log와 error.log가 있는데, 이 두 개는 nginx가 남기는 로그입니다. 반대로 uwsgi.log가 있는데 이건 uwsgi 즉 장고에서 남기는 로그입니다. 

 

로그들

홈페이지에 몇 번 접속해보면서 로그를 보면 nginx가 먼저 남고 uwsgi가 나중에 남는 것을 볼 수 있습니다. (거의 0.001초 차이정도..?)

 

이렇게 웹서버인 nginx와 docker를 이용해서 포트폴리오를 띄웠습니다~!! 이제 이게 왜 돌아가는지 열심히 config파일을 까 보시고, 이것저것 바꿔가면서 테스트를 해보세요~! 떠있는 서버 CPU에 따라 워커 프로세스를 늘려보거나 줄여보시면서 웹서버와 웹 애플리케이션 서버가 어떻게 돌아가는지 알아보시면 꿀잼입니다 ^오^

 

 

AWS route53 도메인 설정

 

자 이제 공짜 도메인이 아니라 AWS에서 제공하는 route53을 사용해보겠습니다.

 

일단 route53을 쓰기 전에, 로드밸런서를 세팅해놔야 합니다. 우리는 인스턴스를 하나 띄워놔서 사실 필요 없긴 한데, route53에 붙이려면 이게 필요합니다. EC2 메뉴 좌측 아래에 Load Balancers 메뉴를 누릅니다.

 

LB

저는 하나를 쓰고 있어서 하나가 나오는데, 여러분은 없겠죠? 여기에 Create Load Balancer 버튼으로 새 로드밸런서를 만듭니다.

 

처음 누르면 어떤 LB를 만들 건지 묻습니다. 우리는 ALB를 만듭니다.

 

ALB
이름정하기

로드밸런서는 이름을 정하고 AZ라고 하는 걸 선택해야 하는데, 4개 중에 두 개를 고르면 됩니다. AZ는 AWS에서 장애 시 대응책으로 서버를 여러 군대로 분산시켜놓은 거라고 생각하시면 됩니다. 서울엔 4개의 AZ가 있고 거기서 2개 이상을 고르면 됩니다. 한쪽이 장애가 나면 다른 쪽에서 서비스가 되거든요. 여기서는 일단 우리 인스턴스가 어떤 AZ에 있는지 보고 그거를 하나 고르시고, 다른 건 아무거나 고르시면 됩니다. 

C에 있네

제 ec2는 ap-northeast-2c에 있기 때문에 c를 하나 고르고, 다른 건 a를 고르겠습니다.

 

az 선택

 

마지막으로 타깃그룹이라는 것을 정해야 합니다. 타깃그룹은 우리가 만든 로드밸런서가 어떤 인스턴스들에게 연결될지 정하는 설정입니다. 

 

타겟그룹

 

Craete target group으로 하나를 만들어줍니다. 

 

target-group 생성

이름만 고르면 됩니다. 나머진 디폴트 설정. 다음을 누르면 어떤 인스턴스를 선택할지 나옵니다.

 

선택하세요

선택하면 아래로 이동되면서 타깃그룹에 속하게 됩니다. 저는 3개가 있는데 여러분은 하나만 있겠죠?

 

아래로 이동

인스턴스를 선택하고 Include as pedning below를 누르면 아래로 이동합니다. 이제 create target group 버튼을 누르면 됩니다.

 

타겟그룹 생성

만들어진 타깃그룹은 좌측 Target Groups 메뉴에서 확인 가능합니다.

 

다시 LB설정으로 가면 우리가 만든 타깃 그룹을 선택할 수 있습니다.

 

새로고침 한번 하면 됩니다.

이제 Create를 누르면 만들어집니다.

 

완료
Load Balancers 메뉴에서 보입니다

 

자 이제 Route53에 가서 도메인을 만들고 우리가 만든 LB를 연결시키면 됩니다.

 

route 53

 

route 53을 검색하면 서비스가 나옵니다. 페이지로 이동하면 EC2와 비슷한 화면이 나오는데, 여기서 도메인 이름을 정해서 살 수 있습니다.

 

좌측에 Domains라는 메뉴에서 Registered domains메뉴에 들어가면 도메인을 정해서 살 수 있고, 가격이 나옵니다.

 

도메인 리스트 보기

 

저는 이미 도메인이 있기 때문에 하나가 나오고 있습니다. 새로 만들려면 Register Domain을 누르면 됩니다.

 

재미있는 도메인 만들기

여기서 도메인 이름을 이것저것 해보면 만들 수 있는지, 불가능한지, 대체 가능한 게 뭐가 있는지 나옵니다. 추가로 가격도 나오는데, 연가 격입니다. 1년에 10달라러면.. 음 만 얼마 정도죠? 이 정도면 한국 도메인보다 쌉니다. ㅎㅎㅎ 

뒤에 com 말고 다른 게 붙으면 더 쌉니다.. 보니까 link는 5달러네요 개꿀.

 

아무튼 이렇게 만들 수 있는 도메인이 있으면 선택을 해서 continue를 하면 돈을 지불하고 1~2일 정도 소요돼서 도메인이 생깁니다. 그럼 좌측 hosted zone을 이용해서 도메인 설정을 할 수 있습니다.

 

호스트존

 

제가 가지고 있는 도메인을 이용해서 서브 도메인을 하나 파서 우리가 아까 만든 로드밸런서와 연결시켜보겠습니다. 도메인 이름을 누르면 서브도메인 설정하는 화면이 나오는데, 여기서 Create record를 누르면 됩니다.

 

새로 하나 파기
심플

그럼 라우팅 종류를 고르는데, 저희는 심플 라우팅이면 충분합니다.

 

세부 설정

그다음이 중요한데, 서브도메인 이름과 레코드 타입, 그리고 아래 우리가 만든 ALB를 연결해주고, 헬스체크 옵션은 꺼줍니다. 우리가 따로 헬스체크 로직을 안 만들었기 때문에 ㅎㅎㅎ 

 

Create

자 이제 만들면 끝입니다. 한번 제가 설정한 도메인으로 들어가 보겠습니다.

 

읭??

 

접속이 안되네요?

 

이것저것 보니 ALB에 보안 그룹이 이상한 것을 발견했습니다.

route53 -> alb -> ec2 이런 구조인데 ec2는 80번 포트가 열려있지만 alb에서 80번 포트가 안 열려 있군요 

 

보안그룹

alb 처음 만들 때 보안 그룹이 default로 만들었는데, 거기에 80번 포트가 추가가 안되어있었습니다. 다시 80번 포트를 허용하는 보안 그룹을 설정해줍니다. 

 

완벽

 

자 이제 route53에서 제공하는 도메인으로 연결되네요~!! 모든 게 성공~!!

 

이번 도메인 연결 작업은 단순히 도메인이 아니라 중간에 lb도 껴서 상~~~ 당히 devops의 영역이었습니다. 물론 현업 devops의 경우 더 복잡한 설정이 있고, 네이밍 규칙이나 태깅 규칙도 있기 때문에 복잡합니다 @_@. 여기서는 간단하게만 사용해 봤습니다. 

 

 

 

정리하며

 

이번 포스팅에서는 지난 시간에 만들었던 프로젝트를 docker와 nginx를 이용해서 띄우고, aws에 route 53을 이용해서 도메인도 붙이고, 라우팅 설정까지 완료했습니다. 블로그에는 글로 쓰느라 너무 함축적인데, 자세한 설명이나 내용은 유튜브 영상으로 대체하겠습니다. 

 

참고로 이번에 다룬 내용은 아주 가볍게 다루었기 때문에 추가적으로 많이 찾아보셔서 공부하시는 걸 추천드립니다. nginx나 docker, docker-compose, alb 등을 찾아보시면 서버 지식이 쑥쑥~ 향상되실 거예요~~!

 

그럼 포폴 띄우기 포스팅은 여기서 끝입니다. 안녕~~~

 

 

 

 

반응형

댓글

Designed by JB FACTORY