도커(Docker)로 SSL 인증된 API 운영하는 방법 (nginx proxy pass 활용)

1. Apps Script와 Python API


    구글 앱스 스크립트로 구글 워크 스페이스 내의 애플리케이션들을 자동화할 수 있지만, 한계도 존재합니다.

    두 가지 실제적인 예를 들어보겠습니다.

    1. JDBC로 DB에서 쿼리 결과를 받아와 2차원 배열로 변환하고 구글 시트에 입력하는 것을 앱스 스크립트에서 하면 속도가 느립니다. 받아오는 결과를 하나씩 배열로 변환하는 작업을 스크립트에서 진행하기 때문입니다.
    2. 구글 시트의 화면을 PDF로 저장하는 기능은 있지만, 이미지로 저장하는 기능은 없습니다. MMS 문자에 화면을 첨부해야 하는 경우 ConvertAPI같은 외부 API를 사용해서 PDF를 이미지로 변환한 뒤에, 문자에 첨부할 수 있습니다.

    이러한 한계를 극복할 수 있는 방법들 중 하나는 Python 프로그래밍을 통해 앱스 스크립트에서 하기 어려운 일들을 대신 해주는 API를 구축하는 것입니다. 꼭 Python으로 할 필요는 없지만, 라이브러리도 잘되어 있고, 많이 사용하는 언어이기 때문에 위의 문제들을 해결하는데 사용하였습니다.

    로컬 환경에서 Postman과 같은 툴로 Python 코드 테스트를 완료한 경우, 이제 앱스 스크립트가 호출할 수 있도록 서버에 배포할 방법이 필요합니다. 어떻게 할 수 있을까요?

    서버를 세팅하는 방법에 대해서는 이전 포스트에서 다루었는데, 가비아의 Micro 서버 정도로 진행할 수 있습니다. 그리고 서버를 세팅한 뒤에 SSL 인증서 발급도 포스트를 따라서 할 수 있습니다.

    구글 챗으로 LG U+ 센트릭스 전화 알림 받기 1/3

    Let’s Encrypt로 무료 SSL 인증서 발급하기 (우분투, nginx 활용)

    여기까지 진행하였다면, 자신의 도메인으로 접속했을 때에 nginx 의 성공화면이 표시될 것이고, https로 표시될 것입니다. 이제 서버에 Python으로 개발한 결과물을 올리고 nginx 의 Proxy Pass 기능으로 연결해주면, 앱스 스크립트에서 호출할 수 있게 됩니다.

    Python 코드를 그대로 올리는 것도 방법이지만, 개발 환경과 서버 환경이 일반적으로 다를 것이기 때문에 코드가 정상적으로 동작할 것이라고 보증할 수 없습니다. 파이썬 패키지의 버전도 환경에 따라 다를 수 있지요. 이런 문제를 해결하는 방법으로 도커(Docker)라는 기술이 있습니다.

    2. 도커(Docker) 소개


    Docker가 무엇인지는 Docker 홈페이지, 많은 블로그에서도 설명을 합니다.

    Docker: Accelerated Container Application Development

    Docker란? | IBM

    간단히 말해서, 도커는 로컬의 소스와 개발 환경을 그대로 묶어서 서버에서 실행할 수 있게 해주는 컨테이너 기술입니다. 도커를 사용하지 않으면, 로컬에서 개발한 소스를 서버에 복사하고 환경도 구성해주어야 할 것입니다. 필요한 패키지들을 설치해주는 과정도 필요하지요. 무엇보다 개발 환경과 서버의 환경이 100% 일치하지 않기 때문에 발생할 수 있는 문제를 없애주어, 내 컴퓨터에서는 잘 되는데 서버에서는 안되는 문제를 방지할 수 있습니다.

    도커를 사용하려면 개발 환경과 운영 환경 모두 도커가 설치되어 있어야 합니다. 개발 환경의 소스와 패키지를 도커 이미지(Image)로 만들어서 운영 환경에 업로드를 하고, 이미지를 로드한 뒤에 컨테이너를 실행하는 방식으로 진행되는데, 단계별로 해보면 그리 어려운 일은 아닙니다.

    3. 개발 환경에 도커(Docker) 설치하기


    먼저 Python API 개발을 완료한 개발 환경에 도커를 설치합니다. 여기서는 개인 로컬 PC가 되겠습니다.

    도커 홈페이지에 접속해서 Docker Desktop 을 다운로드하고 설치합니다. 운영체제에 맞추어 설치하면 됩니다. 권장사항들은 체크하도록 합시다. (아래 스크린샷은 윈도우에서 설치할 때 기준입니다.)

    설치 후에 도커를 실행해서 제대로 실행되는지 체크합니다.


    4. Dockerfile 만들기


    도커가 설치된 환경에서 도커 이미지를 만들기 위해서는 이미지를 위한 청사진이라고 할 수 있는 Dockerfile을 만들어야 합니다. 소스 폴더의 루트에 Dockerfile을 생성합시다.

    Dockerfile의 내용은 개발 환경마다 다를 수 있습니다.

    스크린샷의 내용은 PDF를 이미지로 변환하기 위한 코드를 포함할 때에 필요한 패키지를 설치하고, 소스 파일을 복사하는 과정을 담고 있습니다.

    • 도커에서 제공하는 python 3.9 기반의 슬림 이미지를 사용하여 환경을 구성합니다.
    • 필요한 패키지와 의존성 패키지를 설치합니다. requirements.txt에는 의존성 패키지가 구성되어 있어야 합니다.
    • 다음으로 소스를 모두 복사하고, 컨테이너가 8000 포트를 노출하도록 설정하였습니다.


    5. 이미지 빌드하기


    이제 정상적으로 동작하는 소스코드가 있고, Dockerfile도 설정했으니 이를 기반으로 도커 이미지를 빌드할 수 있습니다. 그런데 개발 환경은 윈도우이고, 서버 환경은 리눅스 기반이기 때문에 빌드할 때에 도커의 buildx를 사용해서 크로스플랫폼 빌드를 할 필요가 있습니다. 그대로 빌드한다면 윈도우 환경으로 빌드를 하기 때문에 리눅스 환경에서는 사용할 수 없습니다.

    먼저 buildx를 통해서 크로스플랫폼 빌더를 만듭니다. 빌더의 이름은 linuxbuilder 이고, 드라이버는 docker-container를 사용하고, 플랫폼은 리눅스입니다.


    그리고 이 빌더를 사용해서 이미지를 빌드합니다. -t 는 이름을 지정하는 파라미터이고, 맨 마지막에 점(.)을 잊지마세요. 이미지의 이름은 영어 소문자여야 합니다. —load를 통해서 빌드한 이미지를 도커 데스크탑에 로드합니다.



    빌드한 이미지를 서버 환경으로 전송하기 위해서 tar 파일로 만들어줍니다.


    ⚠️ 만약 이 과정에서 “open .docker_temp_339743083: The system cannot find the file specified.” 와 같은 오류가 발생한다면, Windows 보안에서 차단된 것일 수 있습니다. 디바이스에서 허용으로 처리해주면 저장이 됩니다.


    6. 서버 환경에 이미지 전송하기


    이미지가 tar 파일로 만들어졌으니 이를 터미널의 scp 명령어 또는 파일질라 같은 FTP 도구를 사용해 서버로 전송합니다.

    scp를 사용한다면, 저장할 폴더는 미리 생성되어 있어야 합니다.


    7. 서버 환경에 도커 설치하기


    이제 서버에 도커 환경을 구축하고, 이미지로 컨테이너를 만들어 실행할 차례입니다.

    서버에 접속해서 도커를 설치합니다. 그리고 도커 서비스를 시작하고, 부팅 시 자동으로 시작되도록 설정합니다. 코드를 한 행씩 실행하면 됩니다.


    docker 명령어를 실행할 때에 sudo를 입력하지 않으려면 사용자 권한 설정도 추가해줍니다.


    8. 도커 이미지 로드 및 컨테이너 실행하기


    방금 tar 파일을 저장한 폴더로 가서 도커 이미지를 로드합니다.

    또는 어느 폴더에서든 폴더 경로까지 포함해서 파일명을 지정함으로 로드할 수도 있습니다.


    다음과 같이 이미지가 로드됩니다.

    이제 이미지를 기반으로 컨테이너를 실행합니다. -d는 백그라운드에서 실행을 의미하고 -p는 포트 매핑입니다. 외부에서 8000 포트로 접근하면, 컨테이너의 포트 8000으로 매핑을 해줍니다. 컨테이너 이름은 단순하게 pdf라고 지정했습니다.



    컨테이너가 정상적으로 실행되었는지 명령어를 통해 확인해봅시다.

    현재 2개의 컨테이너가 실행되고 있는데, 방금 실행한 pdf 컨테이너가 첫 줄에 보입니다.

    pdf 컨테이너가 잘 실행되고 있는지 로그를 통해서 확인해볼 수도 있습니다. 오류가 나지 않았다면 docker ps 를 실행했을 때에 계속 표시될 것입니다.



    9. nginx에서 프록시 패스(Proxy Pass) 설정하기


    여기까지의 상황을 요약하면 다음과 같습니다.

    1. 도메인으로 접속하면 SSL 인증서가 적용된 https로 리다이렉트 됨
    2. 도커는 외부에서 8000 포트로 접속할 수 있음

    이제 목표는 앱스 스크립트에서 도메인/api 를 호출했을 때에 도커의 8000 포트로 접근해서 서버의 응답을 받는 것입니다.

    이 목표를 달성하기 위해서 nginx에서 프록시 패스를 설정해주어야 합니다.

    프록시 패스는 다음과 같습니다. 웹브라우저에서 도메인/api로 접속했을 때에, 어디로 리다이렉트할지를 정해줍니다. 여기서 유의할 점은, 도커가 실행되고 있는 IP주소입니다. 여기서는 172.17.0.3 입니다.

    이 IP주소는 실행되고 있는 도커 컨테이너로 접속해서 알아낼 수 있습니다.


    그럼 이제 프록시 패스는 어디에 넣어주어야 할까요?

    nginx 의 설정 파일에 넣어주면 되는데, 일반적으로 /etc/nginx/sites-available/ 에 위치해있습니다. 해당 폴더로 이동해보면 default 라는 파일이 보입니다. nano 에디터로 수정모드로 진입합니다.


    내용을 보면 server {} 로 구성된 파트가 여러개 보입니다. 이 중에서 listen 443 ssl; 이 들어있는 파트에 추가해줍니다.


    nginx의 설정을 수정했기 때문에 nginx를 재시작합니다.


    이제 https://도메인/api 로 접근해서 API를 활용할 수 있게 됩니다. 앱스 스크립트에서 호출할 때에도 SSL 문제 없이 안전하게 API를 호출할 수 있게 됩니다.

    Similar Posts