
회사에서 내가 투입된 프로젝트에서 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의 ID는 test / VM의 IP는 192.168.0.160 이라 가정
ssh test@192.168.0.160
os-release 파일을 확인
cat /etc/os-release
결과를 통해 나오는 여러 항목이 있는데, 각 항목의 의미는 다음과 같음
NAME: 운영 체제의 이름VERSION: 운영 체제의 버전ID: 운영 체제의 IDID_LIKE: 운영 체제의 기반이 되는 시스템PRETTY_NAME: 사람이 읽기 쉬운 운영 체제 이름VERSION_ID: 운영 체제의 버전 IDHOME_URL: 운영 체제의 홈페이지 URLSUPPORT_URL: 지원 URLBUG_REPORT_URL: 버그 보고 URLPRIVACY_POLICY_URL: 개인정보 보호정책 URLVERSION_CODENAME: 버전 코드명UBUNTU_CODENAME: 우분투 코드명→ 나의 VM은 Ubuntu가 아닌 Debian이므로, Debian을 기반으로 한 Docker를 설치
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
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
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker
sudo docker run hello-world
위 명령어를 실행했을 때 "Hello from Docker!"라는 메시지가 출력되면 Docker가 성공적으로 설치된 것임
# 베이스 이미지로 Node.js 사용
FROM node:18
# 명령어를 실행할 작업 디렉토리 설정
WORKDIR /app
# 패키지 파일을 작업 디렉토리로 복사
COPY package*.json ./
# 의존성 설치
RUN npm install
# 애플리케이션 소스 코드를 작업 디렉토리로 복사
COPY . .
# Dockerfile의 빌드로 생성된 이미지에서 노출할 애플리케이션이 사용하는 포트 설정
EXPOSE 8083
# 애플리케이션 시작 명령어(run하고 동일)
CMD ["node", "app.js"]

→ 컨테이너 명령어 실행으로 들어오면 바로 app 경로로 들어간다는 것을 알 수 있다.
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 .
docker save -o <이미지이름>.tar <이미지ID 또는 이미지이름>
예시:
docker save -o my_image.tar my_image:latest
scp 명령어를 사용할 수 있음scp <이미지파일이름>.tar <사용자이름>@<VM주소>:<경로>
예시:
scp my_image.tar test@192.168.0.160:/home/test/
docker load -i <이미지파일이름>.tar
예시:
docker load -i my_image.tar
docker images
예시
docker run -d -p 8080:8080 --name my_image_container my_image
컨테이너 접속
docker exec -it 컨테이너명 /bin/bash
또는
docker exec -it 컨테이너명 /bin/sh
VM에 Nginx를 설치
sudo apt-get update
sudo apt-get install 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;
}
}
위 설정에서는:
localhost:3000에 있는 React 컨테이너로 리버스 프록시합니다.localhost:8080에 있는 Spring Boot 컨테이너로 리버스 프록시합니다.localhost:8082에 있는 다른 React 컨테이너로 리버스 프록시합니다.Nginx 설정 파일에 문제가 없는지 테스트
sudo nginx -t
설정 파일에 문제가 없다면 Nginx를 재시작
sudo systemctl restart nginx
docker start node-app
docker start react-app
docker start spring-boot-app
이제 브라우저에서 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를 공부하고 다룰 수 있는 경험을 얻을 수 있었고, 이렇게 내 기술 스택이 늘어났다는 것에 감사함을 느낀다. 이상 끝!