Docker 웹서버 구동시키기

nathan·2021년 11월 30일
0

Server

목록 보기
1/2

도커(Docker)를 활용하여 웹서버를 배포하고자 한다.


배경 :

  • 하나의 서버에서 모든 기능이 동작하는 Monolithic Architecture과는 반대인 Micro Service Architecture(MSA)를 통해 각각의 기능별로 서버를 쪼개는 방식을 소개해보고자 한다.
  • 이를 위해서 Docker를 이용할 것이다.
  • Docker를 이용하면 컨테이너로 서버를 운영/배포/관리를 용이하게 할 수 있고, 최근에는 컨테이너를 관리하는 툴(오케스트라)의 등장으로 MSA가 점점 유행처럼 되어가고 있다.
  • Docker로 서버를 구성한다고 해서 MSA가 이루어지는 것이 아니지만, 단순한 운영, 배포 측면에서 상당한 이점이 있기 때문에 dockernize가 추세로 떠오르고 있다.

목표 :

  • AWS를 이용하여 서버를 구축해보고 구축한 서버에 Docker 머신을 설치하여 nginx, uwsgi, django를 연결하여 구동해보고자 한다.

목차

    1. AWS EC2 인스턴스 생성 및 접속하기
    1. jupyter notebook 설치하기 및 HTTPS 적용해보기
    1. Dockerfile로 django 서버 구동해보기
    1. Dockerfile로 nginx 웹서버 구동해보기
    1. docker-compose로 nginx, uwsgi, django 연결하기
    1. AWS RDS로 데이터베이스 서버 구축해보기

1. AWS EC2 인스턴스 생성 및 접속하기

  • 왼쪽 배너에서 인스턴스를 클릭한 후 오른쪽 상단에 있는 '인스턴스 시작' 버튼을 누른다.

  • 그 중에서 Ubuntu Server 18.04 LTS 버전을 선택한다.

  • 이번 포스팅에서는 프리티어가 가능한 t2.micro 유형을 선택하여 진행한다.

  • 그리고 단계 3에서 인스턴스 세부 정보를 구성한다.

  • 네트워크는 이전에 생성된 VPC를 이용하였다. (만약 생성된 VPC가 없다면 오른쪽에 새 VPC 생성을 눌러 생성하자.)

    • VPC를 통해 IPv4 주소 범위를 지정해야 한다.
    • 여기서는 사설 IPv4 주소 범위인 192.168.0.0/16 로 CIDR을 지정해주었다.
  • 그리고 서브넷도 마찬가지로 선택한다. (만약 생성된 서브넷이 없다면 오른쪽에 새 서브넷 생성을 눌러 생성하자.)

    • 서브넷은 VPC 생성이후에 생성이 가능하다. (서브넷 생성시 이전에 생성된 VPC를 선택해야 한다.)
    • 서브넷은 추후 RDS로 데이터베이스를 구축할 때에도 필요하니 2개를 꼭 생성해놓자
    • 이 때 각 가용영역은 보안 및 장애조치 프로세스를 위해 꼭 달라야 한다. (ex. ap-northeast-2a, ap-northeast-2d)
  • 마지막으로 퍼블릭 IP 자동할당을 활성화하여 다른 컴퓨터에서 활성화된 서버를 볼 수 있도록 할 예정이다.

  • 단계 4, 5 : 스토리지 및 태그 추가는 기본 설정을 따르도록 한다.

  • 단계 6 : 보안그룹 설정 (중요)

    • 할당받은 IP 주소의 인스턴스에 액세스하도록 하기위해 필요한 부분이다.
    • 나중에 포트를 지정하고 관리를 하면서도 자주 보게 될 것이다.
    • 우선 당장 필요한 부분은 다음과 같다. (인스턴스를 생성하고나서 보안그룹을 수정할 수 있으니 지금 당장 필요한 포트를 모른다면 22포트만 지정해두자)
      • TCP프로토콜 / 포트범위 : 22 / 원본 : 0.0.0.0/0 (기본)
      • TCP프로토콜 / 포트범위 : 80 / 원본 : 0.0.0.0/0 (nginx)
      • TCP프로토콜 / 포트범위 : 8000 / 원본 : 0.0.0.0/0 (django)
      • TCP프로토콜 / 포트범위 : 9876 / 원본 : 0.0.0.0/0 (Mysql)
  • 이렇게하면 EC2 인스턴스가 성공적으로 만들어지고 키체인을 생성할 것인지 묻는다.

    • 기존의 키페어가 있다면 그것을 선택해도 좋다.
    • 만약 기존 키페어 생성된 것이 없다면, 새롭게 생성하자.
    • 이 키페어를 통하여 ubuntu에 접속할 것이다.
    • 여기서는 키페어 유형 RSA, 키페어 이름은 Docker_Tutorial로 설정해주었다.
    • 그리고 생성된 키페어를 다운 받는다.
    • 다운받은 키페어를 이번 프로젝트를 진행할 디렉토리를 생성하여 넣어준다.
    • 이 디렉토리에서 ubuntu에 접속하게 된다.
  • EC2 인스턴스 페이지에 가서 해당 인스턴스를 체크한 후 연결 버튼을 누르면 다음과 같은 창이 뜬다.

  • Terminal에서 우선적으로 아래 명령어를 통하여 키의 권한을 설정해준다. (이때 꼭 키페어가 있는 디렉토리 내에서 작업해야 한다.)

$ chmod 400 [키페어이름].pem
  • 그 이후 ssh 코드를 통해 접속을 시도한다.
$ ssh -i ~~~~~.compute.amazonaws.com

  • 위처럼 ubuntu에 정상적으로 접속됨을 확인할 수 있다.

2. jupyter notebook 설치하기 및 HTTPS 적용해보기

(1) jupyter notebook 설치하기

  • 콘솔창에서 서버에 접속하고 관리하는 것이 불편할 수 있다.

  • 따라서 jupyter notebook을 설치하여 서버 관리를 좀 더 간편하게 해보려고 한다.

  • jupyter notebook은 이러한 콘솔창이 아니라 웹 브라우저 환경에서 해당 서버를 관리할 수 있게 해준다는 점에서 매우 유용하다.

  • 아래의 코드를 ubuntu 환경에서 입력하여 jupyter notebook을 설치하여 보자.

  • 참고로 ubuntu 18.04 버전에서는 기본적으로 python3가 깔려있다.

$ sudo apt-get update	# apt-get을 활용하기 위해 업데이트
$ sudo apt-get install python3-pip # python 패키지를 이용하기 위해 python3-pip 설치
$ sudo pip3 install notebook # pip를 이용하여 jupyter notebook 설치
  • 아무나 jupyter notebook에 들어오는 것을 방지하고자 비밀번호를 설정하여 준다.
$ python3
>>> from notebook.auth impoert passwd
>>> passwd()  # 이렇게 비밀번호를 설정할 수 있다.
'hash code' # 여기서 나온 해시 코드 비밀번호를 잠시 저장해두자.
>>> exit()
  • 설정한 비밀번호를 활용하기 위해 jupyter 환경설정을 진행한다.
$ jupyter notebook --generate-config	# 환경설정 파일 생성
$ sudo vi /home/ubuntu/.jupyter/jupyter_notebook_config.py # 환경설정 파일 수정하기
  • /home/ubuntu/.jupyter/jupyter_notebook_config.py 의 맨 아래에 다음과 같은 코드를 넣어준다.
c = get_config()
c.NotebookApp.password = u'hash code' # 이전에 비밀번호 설정시 받았던 해시 코드 기입
c.NotebookApp.ip = '192.168.0.86' # 현재 서버의 ip를 넣어준다.
C.NotebookApp.notebook_dir = '/' # root 디렉토리 설정
  • jupyter notebook 실행
$ sudo jupyter-notebook --allow-root	# 외부에서 접속할 수 있도록 설정
밑에 ip 주소와 포트 정보가 나온다.
  • 나온 포트 정보를 EC2 인스턴스 보안그룹에서 포트 허용(TCP 8888)하여 주면 접속이 가능해진다.

  • 그 이후 EC2 인스턴스에 있는 퍼블릭 IPv4의 주소 + 포트 번호를 입력하여 웹에서 jupyter notebook에 접속하여 보자.

  • 여기에서 로그인하면 다음과 같은 창이 뜬다.

    • New 버튼을 누르면 Terminal도 실행할 수 있게된다.
    • 앞으로 콘솔창에서 말고 jupyter notebook으로 서버를 배포하고 관리해보려고 한다.
  • 그러나 이렇게 항상 서버를 켜고 ssh로 접속을 해서 jupyter notebook을 접속하기에는 매우 번거롭다.

  • 따라서 항상 jupyter notebook이 실행되도록 하여 이전 작업들을 반복적으로 하지 않으려고 한다.

  • 이를 위해서 아까 작업하던 터미널의 콘솔창에서 Ctrl + Z를 눌러 해당 jupyter notebook 서버를 잠시 종료 시켜 주고 $ bg를 입력하여 백그라운드 상태에서 돌아갈 수 있도록 한다.

  • 그리고 $ disown -h를 통해 소유권을 포기하게 하면 jupyter notebook이 항상 실행되고 있는 것이다.

  • 아래 코드를 통해 특정 포트 연결 상태를 확인할 수 있다.

$ sudo netstat -nap | grep 8888
  • 아래 코드를 통해서는 해당 포트 연결을 끊어낼 수 있다.
$ sudo kill -9 [포트 id]

(2) Https 적용하기

  • 일단 포트 연결을 해제한 이후 콘솔창에서 다음 코드를 입력하여 ssl용 디렉토리를 생성한다.
$ mkdir ssl
$ cd ssl
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout "cert.key" -out "cert.pem" - batch 
# 사설인증서 개인키 및 공개키 생성 (cert는 임의로 지은 이름입니다. / 유효기간 365일)
  • 개인키의 경우 다른 사람에게 절대 알려선 안된다.
  • 이제 이전에 만들었던 jupyter 환경 설정 파일을 열어 다음의 내용을 마지막에 추가한다.
  • $ sudo vi /home/ubuntu/.jupyter/jupyter_notebook_config.py
c.NotebookApp.certfile = u'/home/ubuntu/ssl/cert.pem'
c.NotebookApp.keyfile = u'/home/ubuntu/ssl/cert.key'
  • 위의 작업을 모두 끝냈다면 다시 jupyter notebook을 실행하면 된다.
$ sudo jupyter-notebook --allow-root
# https://192.168.0.86:8888/
  • 위와 같이 ssl이 잘 적용된 https로 잘 연결이 된 모습을 확인할 수 있다.

  • 사설인증서를 통해 ssl 인증을 한 것이기 때문에 크롬 브라우저에서는 신뢰하기 어렵다고 판단하여 접속할 수 없었다.. 따라서 safari를 통해 접속하게 되었다.

  • ssl이 적용된 상태로 서버 통신이 되기 때문에 중간에서 타 사용자가 서버 패킷을 가로챈다고 하더라도 우리가 서버에서 작성하는 코드가 무엇인지는 알 수 없다.

(3) 시스템 설정하기

  • 서버가 재부팅되더라도 jupyter notebook을 자동 실행할 수 있도록 만들어 보자.
  • 시스템 서비스로써 jupyter notebook을 설정하면 된다.
  • 우선 Ctrl + C를 통해 구동되고 있는 jupyter notebook 서버를 종료시키고 현재 jupyter notebook의 위치를 찾는다.
$ which jupyter-notebook
# /usr/local/bin/jupyter-notebook
  • 시스템 서비스를 등록하기 위해 서비스 파일을 작성해보자.
$ sudo vi /etc/systemd/system/jupyter.service
  • 서비스 파일 작성 코드
[Unit]
Description=Jupyter Notebook Server

[Service]
Type=simple
User=ubuntu
ExecStart=/usr/bin/sudo /usr/local/bin/jupyter-notebook --allow-root --config=/home/ubuntu/.jupyter/jupyter_notebook_config.py

[Install]
WantedBy=multi-user.target
  • 서비스 파일 구동하기
$ sudo systemctl daemon-reload
$ sudo systemctl enable jupyter
$ sudo systemctl start jupyter
  • 실행중인 jupyter server 확인하기
$ sudo system status jupyter

  • 만약 여기서 오류가 났다면 환경설정 파일을 다시 확인해볼 것을 추천한다.

  • jupyter server를 재시작하고자 할 때

$ sudo systemctl restart jupyter
  • 이를 통해 우리는 EC2 인스턴스를 재부팅 하는 등의 다양한 작업을 수행하더라도 항상 jupyter notebook 서비스가 자동으로 실행되어 구동중인 상태가 된다.

3. Dockerfile로 django 서버 구동해보기

docker로 nginx-uwsgi-django를 띄워보려고 한다.
그 전에 우선 Dockerfile로 django 서버를 구동해보자.

먼저 몇가지 유틸을 설치한 뒤, docker를 설치하고 현재 접속중인 사용자에게 권한을 주는 작업을 한다.

(curl : a command line tool to transfer data to or from a server)

$ sudo apt install ca-certificates	# 이 패키지에는 모든 사람에게 공통적인 ca 인증서의 업데이트된 버전이 들어 있다.
$ sudo apt install curl 		# docker를 다운 받기위한 curl 설치 
$ curl -fsSL https://get.docker.com/ | sudo sh
$ sudo usermod -aG docker $USER         # 현재 접속중인 사용자에게 권한 위임

그리고 docker로 만들 서버의 루트 폴더를 만들어 준다. (home에서 적당한 이름으로 폴더 생성하기)

$ mkdir docker-fearnot

해당 폴더에 들어가서 django project를 불러온다. (git clone을 통해 진행)

$ cd docker-fearnot
$ git clone https://github.com/nathan29849/FearNot.git

이 과정을 진행했다면 다음과 같은 구조가 된다.

└── docker-fearnot
    └── FEARNOT
         └── backend (django project 존재)
         └── frontend

이제 FEARNOT 안의 backend 폴더에 django 프로젝트가 생성되어 있으므로 backend 폴더에서 Dockerfile을 생성한다.

$ cd FEARNOT/backend
$ vi Dockerfile (또는 touch Dockerfile 이후 vi Dockerfile로 해도 된다.)

그리고 Dockerfile 안에 다음의 내용을 추가한다.

# /docker-fearnot/FEARNOT/backend/Dockerfile
FROM python:3.6.7		# 생성하는 docker의 python 버전 정해주기

ENV PYTHONUNBUFFERED 1

RUN apt-get -y update
RUN apt-get -y install vim	# docker 안에서 vi 설치를 안해도 된다.

RUN mkdir /srv/fearnot          # docker 안에 srv/fearnot 폴더 생성
ADD . /srv/fearnot  		# 현재 디렉토리를 srv/docker-server 폴더에 복사

WORKDIR /srv/fearnot		# 작업 디렉토리를 설정

RUN pip install --upgrade pip 				# pip 업그레이드
RUN pip install -r requirements.txt			# 필수 패키지 설치 (uwsgi 패키지 필수!)

EXPOSE 8000						 # 8000 포트로 연결 
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] # django 서버 구동 명령어

그 뒤 docker build 명령어를 통해 docker 이미지를 생성한다.
-t : docker 이미지에 이름을 붙여주는 옵션
. : (맨뒤에 붙은 점) 이미지로 만들 폴더 경로를 말한다. (현재 경로에 있다는 의미)

$ docker build -t backend/django .

이미지가 정상적으로 만들어졌는지 확인하기 위해서 docker images라고 입력하면 된다.
(아래 이미지는 최종적으로 만들어질 이미지들이다.)

그리고 -p 옵션을 통해 서버 자체의 포트(호스트 포트 번호)와 docker의 포트번호를 맞춰준다.
(왼쪽이 서버 자체 포트 : 오른쪽이 docker의 포트번호)
아래 명령어를 통해 docker 이미지가 실행되면서 바로 django 서버가 실행된다.

$ docker run -p 8000:8000 backend/django # docker image의 이름

실제 서버 url에 접속하면 아래와 같이 django 페이지가 뜨는 것을 확인할 수 있다.


4. Dockerfile로 nginx 웹서버 구동해보기


Reference

profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글