ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 43일차 - 도커와 웹 사이트 배포하기
    AI 솔루션 개발자과정(Java, Python) 2022. 12. 7. 18:14

    웹 사이트 배포하기

    웹 사이트를 사람들에게 공개하기 위해서는 먼저 서버에 올려야 한다.

    지금까지 각자 작업한 컴퓨터와 서버는 운영체제를 비롯한 여러 가지 환경이 다를 수 밖에 없다.

     

    윈도우에서 작업한 내용을 리눅스 서버로 옮기다 보면 그 과정에서 문제가 생길 수 있는데, 이때 도커를 이용하면 이 문제를 안정적으로 처리할 수 있다.

     

     

    도커란 다른 하드웨어와 운영체제에서 작업하더라도 동일한 환경을 갖출 수 있도록 도와주는 기술이다.

    기본적으로 앞에서 이용했던 가상환경(venv)와 비슷하다. 다반 가상환경은 개발환경을 구축하기에는 충분하지만 구현한 서비스를 서버에 옮겨서 서비스를 제공하는 배포 과정에서는 부족한 부분이 있다.

     

    배포를 하기 위해서는 소스 코드를 복제해서 적절한 위치에 저장하고, 웹 페이지를 보여주는 웹 서버, 웹 서버에서 받은 요청을 장고에게 넘겨주기 위한 인터페이스, 장고에서 사용할 데이터베이스 등의 추가적인 작업이 필요하다.

     

    가상환경으로는 이러한 작업을 수행하는 데 한계가 있으므로 도커를 사용해 모든 환경을 전부 서버로 옮기는 것이다.

     

     

     

    도커의 작동 원리는 먼저 도커 설정 파일에 운영체제, 파이썬 버전, 라이브러리, 소스 코드, 이미지 파일 등 웹 사이트 배포에 필요한 환경설정 정보를 모두 지정한다.

    그리고 도커를 실행하면 도커 설정 파일에서 지정한 대로 서버 전체를 온전히 복제한 컨테이너 이미지가 생성된다.

    마지막으로 이미지를 작동시키면 컨테이너가 실행되면서 기존과 동일한 상태로 웹 사이트 서버를 실행한다.

     

    컨테이너 이미지를 처음 생성할 때는 서버를 실행하기 위해 필요한 모든 파일을 내려받아야 하기 때문에 시간이 많이 걸린다.

    하지만 두 번째 작업부터는 이미 받아놓은 이미지에서 변경된 부분만 갱신하면 되기 때문에 이미지를 생성하는 시간이 대폭 단축된다.

     

    또한 컨테이너 이미지에는 서버 전체가 온전히 담기기 때문에 다른 컴퓨터에서 도커를 설치하고 이 이미지를 복제해서 작동하기만 하면 기존과 동일한 상태로 웹 사이트 서버를 실행할 수 있다.

     

     

     

    도커를 설치하기 위해서 먼저 윈도우 사용자라면 자신의 컴퓨터가 가상화 기능을 지원하는지 확인해야 한다.

    작업관리자 창을 연 후 [성능] 탭에서 '가상화'가 '사용'으로 되어 있는지 확인한다.

    대부분은 사용으로 되어있을 것이다.

     

    그렇다면 도커 설치 파일을 내려받기 위해 도커 웹 사이트(https://www.docker.com/)로 접속한다.

    운영체제에 맞는 설치 파일을 내려받은 후 설치하고 시스템을 재시작한다.

     

    재시작 후 터미널을 열고 docker -v 라고 입력했을 때 다음과 같이 나오면 설치가 성공한 것이다.

     

    이 값은 어떠한 경로에서든 동일한 결과값이 나와야 한다.

     

     

     

    도커 파일 만들기

    지금까지 웹 사이트를 만들면서 여러 라이브러리를 활용했고, 이는 가상환경에 설치가 되어 있다.

    이제 여기 설치된 라이브러리를 도커 컨테이너로 옮겨야 한다.

     

    터미널에서 pip freeze > requirements.txt 명령어를 입력해 지금까지 가상환경에 설치한 라이브러리들을 리스트로 만들어 저장한다.

    새로 생성된 텍스트 파일을 열어보면 지금까지 웹 사이트를 만드는 데 사용한 모듈이 나열되어 있다.

     

     

     

    이제 도커 설정 파일을 만들어야 한다.

    도커 설정 파일에는 지금까지 프로젝트를 진행한 로컬환경과 동일한 컨테이너 이미지를 만들기 위해 지정할 내용을 작성한다.

     

     

    프로젝트 폴더에 확장자 없이 Dockerfile이라는 이름으로 파일을 만들고 다음과 같이 내용을 작성한다.

    2줄 : 도커는 파이썬이 설치되어 있는 이미지를 기본으로 제공한다. 이 이미지를 불러온다.

    5줄 : 프로젝트의 작업 폴더를 /usr/src/app으로 지정한다.

    8줄 : 파이썬은 종종 소스 코드를 컴파일해서 확장자가 .pyc인 파일을 생성한다. 도커를 이용할 때는 .pyc                를 생성하지 않도록 한다.

    9줄 : 파이썬 로그가 버퍼링 없이 즉각적으로 출력하게 만든다.

    11줄 : 로컬 컴퓨터의 현재 위치에 있는 파일을 모두 작업 폴더로 복사한다. 그래야 도커 이미지에 담긴다.

    13, 14줄 : requirements.txt에 나열된 라이브러리를 설치한다.

     

     

    docker-compose 파일을 사용하면 컨테이너 여러 개를 한 번에 실행시킬 수 있고, 컨테이너를 실행시킬 때 옵션도 줄 수 있다.

     

    프로젝트 폴더에 docker-compost.yml파일을 만들고 다음과 같이 작성한다.

    1줄 : 도커 컴포즈 파일 포맷을 최신 버전으로 사용하겠다는 의미이다.

    4줄 : 여기서는 web이라는 이름의 서비스 하나만 실행한다.

    5줄 : 현재 폴더를 build라고 한다. 앞에서 만든 Dockerfile이 현재 폴더에 있으므로 이 파일을 이용해 컨테이           너 이미지를 만든다.

    6줄 : command로 터미널에서 직접 입력했던 서버 실행 명령을 대신 입력한다.

    7줄 : volumes로 로컬 컴퓨터의 폴더와 도커의 폴더를 연결한다. 여기서는 /usr/src/app/폴더와 연결한다.

    9줄 : posts로 이번과 똑같이 8000번 포트를 사용한다.

    11줄 : 이제 오류 페이지가 다른 사람에게 보이지 않도록 SETTINGS.PY에서 관리되던 요소 일부를 개발환경            과 배포환경(.env.prod)으로 나누어 관리한다. 아직은 개발중이므로 .env.dev만 지정한다. 

     

     

    프로젝트에서 개발환경 파일을 활용할 수 있도록 settings.py를 다음과 같이 수정한다.

     

    시크릿 키는 장고에서 제공하는 기본값이기 때문에 랜덤한 값을 넣어 사용해야 한다.

    https://miniwebtool.com/django-secret-key-generator/ 시크릿 키를 생성해주는 사이트를 참고한다.

     

     

    27줄은 디버깅 모드를 계속 유지하겠다는 의미이다.

    29줄은 HOST로 허용하는 주소를 적어두는 곳이다. 서비스로 공개할 때는 보안을 위해 서버가 될 URL만 남겨놓는 것이 맞다. 반면에 개발할 때는 127.0.0.1이나 localhost로 장고에 접근할 수 있어야 한다.

    이런 목적으로 env파일에서 DJANGO_ALLOWED_HOST를 읽어올 수 있다면 그 값을 사용하고, 없다면 이전과 동일하게 되도록 설정한다.

     

     

     

     

    개발할 때의 환경설정을 위한 .env.dev 파일을 만들고 다음과 같이 입력한다.

     

     

    이제 터미널에서 docker-compose build 명령어로 이미지를 만들고, docker-compose up으로 컨테이너를 실행한다.

     

     

     

     

     

     

    다시 컨테이너를 실행하면 페이지가 작동하지 않습니다 라는 문구가 나온다.

    이는 psycopg2가 없기 때문이다.

     

    pip install psycopg2-binary 설치 후 pip freeze > requirements.txt 로 psycopg2가 설치된 결과를 반영.

    웹 브라우저에 programmingError 메시지가 나오면 성공이다.

    docker-compose exec web python manage.py migrate로 마이그레이션을 진행한다.

     

     

    docker-compose exec web python manage.py createsuperuser로 관리자 계정을 생성한다.

     

     

     

    이전에는 장고에서 제공하는 runserver를 통해 서버를 실행했지만, 웹 서버 소프트웨어를 사용하면 방문자의 요청에 더 빠르게 응답할 수 있고, 많은 사용자가 동시에 접속했을 때 여러 대의 서버로 요청을 분산하는 로드 밸런싱 같은 기능도 제공할 수 있다.

     

    먼저 Gunicorn을 사용하기 위해 도커 이미지를 수정한다. docker-compose.yml파일을 다음과 같이 수정한다.

     

    pip install gunicorn으로 모듈을 설치하고, freeze 와 build를 진행한다.

     

    이때 static 파일을 찾을 수 없다는 메시지가 발생한다.

    gunicorn을 사용하면서 static폴더에 직접 파일을 연결하지 않았기 때문이다.

    settings.py를 열고 다음과 같이 지정한다.

     

    위의 url이 urls.py에서 처리가 되도록 다음과 같이 한 줄 추가한다.

     

     

    이제 터미널에서 python manage.py collectstatic 을 입력해 static파일을 복사한다.

    다시 build하고 도커를 실행해 확인해본다.

     

     

     

     

    배포용 도커 파일 만들기

    실제로 웹 사이트를 공개할 때는 보안을 위해 몇 가지 설정이 달라져야 한다.

    방문자가 웹 사이트를 돌아다니다가 오류를 발생했을 때 방문자에게 어디서 오류가 발생했는지 알려준다면 웹 사이트의 소스 코드 일부 및 취약점이 공개되어 버린다.

    그러면 개발 단계에서 개발자에게는 큰 도움이 될 수도 있지만, 나쁜 의도를 가진 사람들에게는 웹 사이트를 공격하는 데 필요한 도움을 주는 셈이 되기도 한다.

    따라서 개발용 환경과 실제 환경을 달리 해야 한다.

     

     

     

    개발용 docker-compose파일을 복사하여 파일명을 docker-compose.dev.yml로 변경한다.

    기존에 있던 docker-compose파일은 배포용으로 사용한다.

     

    개발용인 docker-compose.dev.yml 파일로 도커 컨테이너를 실행시키려면 다음과 같이 터미널에 명령어를 입력하면 된다.

     

    웹 브라우저를 실행하여 제대로 작동하는지 확인하고, 컨테이너를 중단한다.

    이제 서비스 배포용인 docker-compose.yml파일을 수정한다.

     

     

     

    .env.dev 파일을 복사하여 .env.prod파일로 파일명을 변경 후 다음처럼 수정한다.

    문제가 발생했을 때 브라우저에서 오류 메시지를 더 이상 나타내지 않도록 DEBUG는 0으로 변경한다.

    SECRET_CEY는 새 시크릿 키를 만들어 넣는다.

     

    .env.prod.db 파일을 새로 만들고 docker-compose.yml에서 삭제한 내용을 붙여 넣는다.

     

     

     

    위의 두 파일은 다른사람에게 공개되면 안되기 때문에 git으로 관리하면 안된다.

    .gitignore 파일에 위의 두 파일을 추가한다.

     

     

    이제 도커에 변화된 내용을 반영해야 한다.

    반영하기에 앞서 실행되었던 컨테이너를 내리고, 이들 컨테이너와 연결되어 있던 볼륨도 다 삭제하기 위해 -v 옵션을 추가한다.

     

     

    이제 디버그를 False로 설정했기 때문에 더 이상 오류 내용이 무엇인지 알려주지 않는다.

     

     

    왜 이런 문제가 발생했는지 로그를 확인하려면 터미널에 docker-compose logs를 입력하면 된다.

    이번 문제는 마이그레이션이 되지 않아 발생한 문제이다.

    docker-compose exec web python manage.py migrate로 마이그레이션을 진행하고 새로운 최고관리자 계정을 생성한다.

     

     

     

    현재 상태에서 웹 사이트를 열어보면 아직 정적 파일(이미지파일과 css파일)이 제대로 적용되지 않는다.

    Nginx를 이용해 이 문제를 해결한다.

    Nginx를 적용하기 위한 새로운 컨테이너를 준비하기 위해 docker-compose.yml을 다음과 같이 수정한다.

     

    nginx폴더를 만들고 그 안에 Dockerfile을 새로 만든다.

    Nginx역시 도커에서 제공하고 있다.

     

     

    아직 Nginx 설정 정보를 담을 nginx.conf 파일을 만들지 않은 상태이다.

    방금 만든 nginx폴더에 nginx.conf 파일을 생성하고 다음과 같이 작성한다.

    장고 쪽에서  proxy_pass를 통해 nginx로 오는 내용은 8000번 포트로 받고, 서버 외부에서 오는 요청은 80으로 받도록 설정한다.

    또 /static/이나 /media/ 경로로 접근하는 경우에 파일을 제공할 수 있도록 static 파일과 media 파일이 저장되어 있는 위치를 적어둔다.

     

    터미널에서 컨테이너를 종료하고, docker-compose up으로 다시 실행한 다음 collectstatic으로 static파일을 정리한다.

     

    이제 웹 브라우저에 접속할 때 더이상 포트번호를 쓰지 않고, 127.0.0.1만 입력한다.

     

     

     

    아마존 웹 서비스로 프로젝트 옮기기

    가끔 컴퓨터 작업을 하다 보면 개인 컴퓨터로는 해결하기 어려운 문제들을 만나게 된다.

    며칠 동안 고사양의 컴퓨터로 대용량의 데이터를 처리해야 하는 경우와, 웹 사이트를 운영하기 위해 365일 24시간 컴퓨터를 켜두어야 하는 경우 등이 있다.

     

    이럴 때 클라우드 컴퓨팅 서비스를 이용한다. 클라우드에서 원하는 사양의 컴퓨터를 기간을 정해 대여할 수 있는 서비스이다.

    아마존, 구글, 마이크로스프트 뿐만 아니라 네이버 cafe24등 다양한 회사에서 이 서비스를 제공하고 있다.

     

    이 중 가장 유명한 서비스가 아마존에서 운영하는 AWS(Amazon web service)이다.

     

    여기서는 AWS가 제공하는 여러 서비스 중 Lightsail을 사용한다.

    Lightsail은 거대한 서버에서 작은 방을 빌려 내 개인 서버로 이용하는 것이다.

    부동산에서 임대차 계약을 할 때처럼 가상 서버를 빌릴 때에도 같은 과정을 거친다.

     

     

     

     

    리눅스계열의 Ubuntu 운영체제를 선택하고 인스턴스 이름을 정한 후 인스턴스를 생성한다.

    인스턴스 생성이 완료되면 터미널 모양의 아이콘을 클릭하여 웹 브라우저 상에서 방금 만든 가상 서버의 터미널에 접속할 수 있다.

     

     

    터미널을 통해 서버에 접속되면 mkdir 명령어를 이용하여 제작한 웹 사이트를 담을 폴더를 생성하고, git clone을 진행한다.

     

     

    깃 클론을 통해 소스 코드는 옮겼지만, AWS Lightsail 인스턴스에는 아직 도커가 설치되어 있지 않으므로, sudo apt-get update 명령어로 unbuntu에서 소프트웨어를 설치할 때 주로 사용하는 apt-get을 업데이트 해야 한다.

     

    그리고 혹시 남아 있으지도 모르는 도커 관련 내용을 모두 삭제하기 위해서

    sudo apt-get remove docker docker-engine docker.io를 입력한다.

     

    sudo apt install docker.io로 도커를 설치하면 되고,

    sudo systemctl start docker와 sudo systemctl enable docker로 운분투 서버가 시작될 때,

    도커도 자동으로 실행되도록 설정을 추가한다.

     

    AWS 서버에는 아직 docker-compose가 설치되어 있지 않기 때문에 sudo apt install docker-compose명령어로 설치한다.

     

     

     

    이제 웹 사이트를 운영하기 전에 서버의 IP를 알아야 한다.

     

    인스턴스의 네트워킹 텝에서 고정 IP 생성 버튼을 클릭한다.

     

     

    다음은 배포용 환경설정 파일을 만들어야 한다.

    앞에서 만든 .env.prod 파일과 .env.prod.db 파일은 .gitignore로 제외했기 때문에 AWS 서버에 전달되지 않았다.

    새로운 파일 2개를 생성하기 위해 서버폴더로 이동하고, touch .env.prod .env.prod.db 를 입력한다.

    운분투에서 touch는 파일을 생성하는 명령어이다.

     

    파일을 작성하기 위해서는 nano라는 에디터를 사용한다.

    nano .env.prod를 입력하여 기존 파일처럼 작성하고, 로컬호스트 주소 뒤에 서버의 고정IP주소를 추가한다.

     

     

    두 파일 모두 작성했다면 sudo docker-compose up -d --build 명령어를 통해 빌드를 진행하고, 새로 데이터베이스를 만들었기 때문에 마이그레이션을 진행한다.

     

    마이그레이션은 sudo docker-compose exec web python manage.py makemigrations
    sudo docker-compose exec web python manage.py migrate 로 진행한다.

     

    이제 웹 브라우저에 서버 고정IP를 입력하여 접속하면 웹 사이트 배포 완료이다.

Designed by Tistory.