여러 프로젝트를 Docker로 배포한 후, Nginx를 통해 Reverse Proxy 해서 각 프로젝트로 연결시켜주기

IRISH·2024년 8월 8일

Review

목록 보기
8/8
post-thumbnail

회사에서 내가 투입된 프로젝트에서 Docker와 Nginx를 활용하기는 했지만, 내가 구축한 것이 아니었기 때문에 그냥 실행법만 다루었다.

하지만, 내가 직접 공부한 후 실무까지 적용해보고 싶은 생각이 들었다. 그래서, 프로그래밍 자체보다는 Docker랑 Nginx 위주로 공부해서 어떻게 Docker를 통해 프로젝트를 배포할지, Nginx를 통해 어떻게 하면 Reverse Proxy를 할지 학습했고 실제 적용했다.

내 프로젝트는 전자정부프레임워크에서 제공한 SpringBoot와 React로 구성되어 있고, 회사에서는 다루지 않지만 그냥 공부겸 하나 만든 Node 프로젝트가 있다.

참고로, 개발 OS는 Linux Ubuntu 22.04 LTS 이며, 가상 머신(VM)의 OS는 Linux Debian이다.

이것을 기반으로 Dokcer 이미지 생성 + 컨테이너 + 배포 / Nginx의 Reverse Proxy를 다루어본다.

VM 접속

→ VM의 ID는 test / VM의 IP는 192.168.0.160 이라 가정

ssh test@192.168.0.160

VM의 OS 확인

os-release 파일을 확인

cat /etc/os-release

결과를 통해 나오는 여러 항목이 있는데, 각 항목의 의미는 다음과 같음

  • NAME: 운영 체제의 이름
  • VERSION: 운영 체제의 버전
  • ID: 운영 체제의 ID
  • ID_LIKE: 운영 체제의 기반이 되는 시스템
  • PRETTY_NAME: 사람이 읽기 쉬운 운영 체제 이름
  • VERSION_ID: 운영 체제의 버전 ID
  • HOME_URL: 운영 체제의 홈페이지 URL
  • SUPPORT_URL: 지원 URL
  • BUG_REPORT_URL: 버그 보고 URL
  • PRIVACY_POLICY_URL: 개인정보 보호정책 URL
  • VERSION_CODENAME: 버전 코드명
  • UBUNTU_CODENAME: 우분투 코드명

VM의 OS에 맞는 Docker 설치

→ 나의 VM은 Ubuntu가 아닌 Debian이므로, Debian을 기반으로 한 Docker를 설치

1. 시스템 업데이트

  • 먼저 패키지 목록을 업데이트하고 시스템을 업그레이드 진행
sudo apt-get update
sudo apt-get upgrade

2. Docker 설치를 위한 필수 패키지 설치

  • Docker 설치에 필요한 패키지를 설치
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

3. Docker의 공식 GPG 키 추가

  • Docker의 GPG 키를 추가
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

4. Docker 저장소 설정

  • Docker 패키지를 설치할 수 있도록 APT 소스를 설정
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

5. Docker 엔진 설치

  • Docker 엔진을 설치
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

6. Docker 서비스 시작 및 활성화

  • Docker 서비스를 시작하고 부팅 시 자동으로 시작되도록 설정
sudo systemctl start docker
sudo systemctl enable docker

7. Docker 설치 확인

  • Docker가 정상적으로 설치되었는지 확인
sudo docker run hello-world

위 명령어를 실행했을 때 "Hello from Docker!"라는 메시지가 출력되면 Docker가 성공적으로 설치된 것임

로컬 Dockerfile 작성

  • 각 Skill 별로 Dockerfile을 작성해야 하지만, 예시이므로 Node랑 Spring-boot의 Dockerfile 작성
  • 참고 : https://seosh817.tistory.com/381
  • Node 프로젝트 관련한 Dockerfile 작성
# 베이스 이미지로 Node.js 사용
FROM node:18

# 명령어를 실행할 작업 디렉토리 설정
WORKDIR /app

# 패키지 파일을 작업 디렉토리로 복사
COPY package*.json ./

# 의존성 설치
RUN npm install

# 애플리케이션 소스 코드를 작업 디렉토리로 복사
COPY . .

# Dockerfile의 빌드로 생성된 이미지에서 노출할 애플리케이션이 사용하는 포트 설정
EXPOSE 8083

# 애플리케이션 시작 명령어(run하고 동일)
CMD ["node", "app.js"]

→ 컨테이너 명령어 실행으로 들어오면 바로 app 경로로 들어간다는 것을 알 수 있다.

  • SpringBoot 프로젝트 관련한 Dockerfile 작성
FROM openjdk:18-jdk-alpine
WORKDIR /app
COPY target/my-spring-boot-app.jar my-spring-boot-app.jar

# ENTRYPOINT : 도커 컨테이너가 실행할 때 고정적으로 실행되는 스크립트 혹은 명령어
# 생략이 가능하며, 생략할 경우 커맨드(CMD)에 지정된 명령어로 수행.
# ["a", "b", "c"] >>> a, b, c 순으로 실행
ENTRYPOINT ["java","-jar","my-spring-boot-app.jar"]
EXPOSE 8080

로컬 이미지 빌드

docker build -t update-my-node-app .

로컬의 도커 이미지를 tar 파일로 압축 후 scp 활용해 VM으로 보내기

1. Docker 이미지 저장

  • 먼저 로컬에서 Docker 이미지를 tar 파일로 저장
docker save -o <이미지이름>.tar <이미지ID 또는 이미지이름>

예시:

docker save -o my_image.tar my_image:latest

2. 이미지 파일 전송

  • 저장된 tar 파일을 VM으로 전송합니다. 이를 위해 scp 명령어를 사용할 수 있음
scp <이미지파일이름>.tar <사용자이름>@<VM주소>:<경로>

예시:

scp my_image.tar test@192.168.0.160:/home/test/

로컬에서 전달받은 tar 파일을 VM에서 Docker 이미지 로드하기

1. Docker 이미지 로드

  • VM에 접속한 후, 전송된 tar 파일을 Docker 이미지로 로드
docker load -i <이미지파일이름>.tar

예시:

docker load -i my_image.tar

2. 이미지 확인

  • 이미지가 정상적으로 로드되었는지 확인
docker images

VM Docker 컨테이너 실행

예시

docker run -d -p 8080:8080 --name my_image_container my_image

컨테이너 접속

docker exec -it 컨테이너명 /bin/bash

또는

docker exec -it 컨테이너명 /bin/sh

VM Nginx 설치

1. Nginx 설치

VM에 Nginx를 설치

sudo apt-get update
sudo apt-get install nginx

2. Nginx 설정 파일 수정

Nginx 설정 파일을 수정하여 각 Docker 컨테이너로 트래픽을 리버스 프록시 진행

  • /etc/nginx/sites-available/default 파일을 편집함
sudo nano /etc/nginx/sites-available/default

예시 설정 파일:

server {
    listen 1000;
    server_name 192.168.0.160;

    location / {
        proxy_pass http://localhost:3000;
    }
}

server {
    listen 1001;
    server_name 192.168.0.160;

    location / {
        proxy_pass http://localhost:8080;
    }
}

server {
    listen 1002;
    server_name 192.168.0.160;

    location / {
        proxy_pass http://localhost:8082;
    }
}

위 설정에서는:

  • 포트 1000으로 들어오는 트래픽을 localhost:3000에 있는 React 컨테이너로 리버스 프록시합니다.
  • 포트 1001로 들어오는 트래픽을 localhost:8080에 있는 Spring Boot 컨테이너로 리버스 프록시합니다.
  • 포트 1002로 들어오는 트래픽을 localhost:8082에 있는 다른 React 컨테이너로 리버스 프록시합니다.

3. Nginx 설정 테스트 및 재시작

Nginx 설정 파일에 문제가 없는지 테스트

sudo nginx -t

설정 파일에 문제가 없다면 Nginx를 재시작

sudo systemctl restart nginx

4. Docker 컨테이너 실행 확인

  • Nginx가 Docker 컨테이너와 통신할 수 있도록 Docker 컨테이너가 실행 중인지 확인
  • 만약 컨테이너가 실행 중이지 않다면 아래 명령어를 사용하여 컨테이너를 실행
docker start node-app
docker start react-app
docker start spring-boot-app

5. VM의 IP로 접속 테스트

이제 브라우저에서 VM의 IP를 통해 각각의 애플리케이션에 접속

  • http://192.168.0.160:1000/
  • http://192.168.0.160:1001/
  • http://192.168.0.160:1002/

위의 경로로 접속하여 각 애플리케이션이 정상적으로 동작하는지 확인

결과 화면

  • http://192.168.0.160:1000/
  • http://192.168.0.160:1001/

  • http://192.168.0.160:1002/

마치며

요즘 IT Trend 중 하나인 Docker와 Nginx를 활용해 내 프로젝트를 띄워 보았다. 특히, Docker와 Nginx는 우리 회사에서도 사용하는 기술 Stack이다. 내가 회사에서 투입된 프로젝트에서도 사용이 되고는 있지만 내가 처음부터 만든 것이 아니다. 그래서, 활용법 정도만 익혔었다.

하지만, Docker와 Nginx를 직접 사용해보고 싶다는 생각이 들었고, 공부해서 실습까지 했다.

아쉬웠던 부분 중에 하나라면, 내 프로젝트에서 사용하는 DB까지 Docker image로 pull을 받아 내 DB와 연결하는 정보를 mapping한 후, 프로젝트와 함께 테스트를 해보면 어땠을까라는 아쉬움은 든다.

또한, 해당 부분을 아키텍처로도 그리면 좋을 것 같다라는 생각이 추가적으로 든다.

어찌됐든 직접적으로 Docker와 Nginx를 공부하고 다룰 수 있는 경험을 얻을 수 있었고, 이렇게 내 기술 스택이 늘어났다는 것에 감사함을 느낀다. 이상 끝!

profile
#Software Engineer #IRISH

0개의 댓글