Published on

Docker와 Nginx를 사용해보며 개인적인 정리

Authors
  • avatar
    Name
    김민석
    Twitter

Introduction

image.png

Docker 사용해보기

  • 사이트에서 설치한다.
image.png
  • 설치 프로그램을 실행하고, 안내에 따라 설치를 완료한다.

  • 설치가 끝나면 Docker Desktop을 실행하고, Docker가 제대로 작동하는지 확인한다.

    • 명령 프롬프트(cmd) 창에서 밑에 명령어를 작성하여 확인하기.
    docker --version
    

build 태스크를 통한 jar 파일을 생성해야 된다.

  • 왼쪽 사진을 따라 진행하면 오른쪽 사진처럼의 jar 파일이 생성된다.
image.png
image.png
  • 다음으로 SpringBoot 프로젝트를 Docker로 컨테이너화하기 위해 Dockerfile을 만들어야 한다. Dockerfile은 Docker 이미지 생성을 위한 명령어가 포함된 파일이다.
image.png
  • 인텔리제이에서 프로젝트의 루트 디렉토리 즉, src 디렉토리가 있는 폴더에 Dockerfile이라는 파일을 생성해준다.
  • Dockerfile 파일에 다음과 같은 내용을 추가한다.
    • (프로젝트의 JAR 파일을 컨테이너에 복사) → 항목은 각자의 프로젝트에서의 build를 통해 생성된 jar파일 이름을 작성하는 것이다.
# OpenJDK 17을 기반으로 한 Docker 이미지 사용
FROM openjdk:17-jdk-slim

# 작업 디렉토리 설정
WORKDIR /app

# 프로젝트의 JAR 파일을 컨테이너에 복사
COPY build/libs/resume-feedback-0.0.1-SNAPSHOT.jar /app/app.jar

# 컨테이너가 실행될 때 실행할 명령어
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
  • 프로젝트 빌드 및 Docker 이미지 생성하기

    • 이제 Docker 이미지를 생성하는 과정이다. 4번 과정을 한번 더 빌드해서 JAR 파일을 만든 후, Docker 이미지로 변환하는 작업이다.
    • 빌드를 완료 하였다면 밑에 명령어를 인텔리제이 터미널 or cmd에서 실행시킨다.
      • 실행 시킬때는 해당 프로젝트 파일에서의 Dockerfile이 있는 위치까지 가서 실행 시킨다.
    docker build -t springboot-app .
    

6번 확인 과정을 보면 이렇다.

image.png
image.png
  • Docker 컨테이너 실행하기

    • 이제 생성된 이미지를 컨테이너로 실행해볼 수 있다.
    • 다음 명령어로 Docker 컨테이너를 실행한다.
    docker run -p 8080:8080 springboot-app
    

    이 명령어는 호스트의 포트 8080을 Docker 컨테이너의 포트 8080에 매핑해서 Spring Boot 애플리케이션을 실행하는 과정인 것이다.

    이제 브라우저에서 http://localhost:8080을 입력하면 애플리케이션이 실행되는 것을 확인할 수 있다.

image.png

Nginx 사용해보기

먼저 Nginx를 Docker 컨테이너로 실행하는 것이다. Docker를 통해 설치하면 컨테이너로 Nginx를 실행할 수 있다.

  • PowerShell을 열고 밑에 명령어를 입력한다.
docker pull nginx

이 명령어는 Docker Hub에서 Nginx의 최신 이미지를 다운로드 한다.

image.png
  • Nginx Docker 컨테이너 실행하기
    • Docker 명령어로 Nginx 실행한다
docker run --name my-nginx -p 80:80 -d nginx
  • -name my-nginx: Nginx 컨테이너의 이름을 "my-nginx"로 설정.
  • p 80:80: 호스트의 80번 포트를 Nginx 컨테이너의 80번 포트로 연결.
  • d nginx: 백그라운드에서 Nginx를 실행.

실행 과정.

image.png

브라우저에서 http://localhost로 접속하면 기본 Nginx 화면이 나타난다.

이렇게 Nginx가 성공적으로 실행된 것을 확인할 수 있다.

image.png
  • Nginx 설정 파일 만들기.
    • Nginx 설정 파일 (nginx.conf) 생성하기

이제 Nginx가 클라이언트로부터 HTTPS(SSL) 요청을 받고, 내부적으로 Spring Boot 애플리케이션에 요청을 전달하도록 설정 파일을 작성하는 것이다.

생성 위치는 이런식으로 하면 되는 것이다.

my-project/
├── src/
├── Dockerfile
├── nginx.conf
└── docker-compose.yml

이 파일에는 다음 내용을 추가한다.

events {
    # 기본 이벤트 설정 (필수)
}

http {
    server {
        listen 443 ssl;
        server_name localhost;

        # SSL 인증서 설정
        ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;

        # Spring Boot 애플리케이션으로 요청 전달
        location / {
            proxy_pass http://application:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    server {
        listen 80;
        server_name localhost;

        # HTTP로 들어오는 요청을 HTTPS로 리다이렉트
        return 301 https://$host$request_uri;
    }
}

image.png

환경 변수 설정을 해줘야 한다.

image.png
image.png

환경 변수를 설정한 후에는 PowerShell을 다시 열고 openssl 명령어를 실행해본다.

openssl version
image.png

PowerShell과 프로젝트 폴더 내에 ssl 폴더를 먼저 만든다.

프로젝트

my-project/
├── src/
├── Dockerfile
├── nginx.conf
└── ssl/
    ├── nginx-selfsigned.key
    └── nginx-selfsigned.crt

PowerShell

mkdir ssl

SSL 인증서를 로컬 파일 시스템에 저장하고, Docker 컨테이너 내부에서 사용할 수 있도록 Nginx 설정 파일과 연결하는 과정이다.

image.png

SSL을 적용하기 위해 인증서와 비밀 키 파일을 만들어야 한다. 여기서는 테스트용으로 셀프 서명된 인증서를 만드는 것이다.

  • SSL 인증서 생성 (셀프 서명):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx-selfsigned.key -out nginx-selfsigned.crt

이 명령어는 nginx-selfsigned.keynginx-selfsigned.crt라는 비밀 키와 인증서를 1년 동안 사용할 수 있게 생성해준다. (비밀 키와 인증서)

  • 생성된 이 두 파일은 나중에 Nginx 컨테이너에서 사용하게 된다.
image.png
  • Country Name (2 letter code): 나라 코드를 입력 (예: KR).
  • State or Province Name (full name): 지역 이름 입력.
  • Locality Name (eg, city): 도시 이름 입력.
  • Organization Name (eg, company): 회사 또는 단체 이름 입력.
  • Organizational Unit Name (eg, section): 부서 이름 입력 (선택 사항).
  • Common Name (e.g. server FQDN or YOUR name): 도메인 이름 또는 서버 이름 입력 (개발 환경이면 localhost로 입력 가능).
  • Email Address: 이메일 주소 입력 (선택 사항).

생성된걸 알 수 있다.

image.png
  • Docker Compose 설정 작성
    • Docker Compose를 사용하면, 로컬에 있는 인증서 파일을 컨테이너 내로 마운트할 수 있다.
      • 이 과정을 통해 Nginx가 SSL 인증서와 비밀 키 파일을 사용할 수 있게 되는 것이다.
    • Nginx와 Spring Boot 애플리케이션을 함께 실행할 수 있도록 Docker Compose 파일을 작성한다.
    • Docker Compose는 여러 컨테이너를 동시에 관리하고 실행할 수 있게 도와주는 것이다..
version: '3'
services:
  application:
    image: springboot-app  # 이미 빌드된 Spring Boot 이미지
    ports:
      - "8080:8080"  # 애플리케이션은 내부적으로 8080에서 실행

  nginx:
    image: nginx:latest  # 공식 nginx 이미지
    ports:
      - "80:80"   # HTTP 포트
      - "443:443" # HTTPS 포트
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf # Nginx 설정 파일 마운트
      - ./ssl:/etc/nginx/ssl  # IntelliJ 프로젝트 내의 ssl 폴더와 매핑
    depends_on:
      - application # NginxSpring Boot 애플리케이션이 실행된 후에 실행

설명

  • application: Spring Boot 애플리케이션 컨테이너. 8080 포트에서 실행되고, Nginx가 리버스 프록시로 이를 받아 클라이언트에게 전달한다.

  • nginx: Nginx 컨테이너. 80번 포트에서 HTTP 요청을 받고 443번 포트에서 HTTPS 요청을 받음.

    • volumes: 로컬 파일 시스템의 nginx.conf와 SSL 인증서를 Nginx 컨테이너 내부로 마운트.
    • depends_on: Spring Boot 애플리케이션이 먼저 실행되어야 Nginx가 실행됨.
  • Docker Compose 실행

    • Docker Compose로 Nginx와 Spring Boot 애플리케이션을 실행한다.
    • 인텔리제이에서 명령어를 입력한다.
      • 주의사항은 프로젝트의 src, dockerfile, docker-compose 폴더가 있는 위치에서 명령어를 입력해야 된다는 것이다.
    docker-compose up --build
    
  • 이 명령어는 Docker Compose로 두 개의 컨테이너(Nginx와 Spring Boot)를 빌드하고 실행해준다.

  • SSL 적용 확인

    • 이제 브라우저에서 https://localhost로 접속하면, SSL이 적용된 Nginx를 통해 Spring Boot 애플리케이션에 접근할 수 있다.
image.png
image.png

브라우저에서 확인해본다.

  • 브라우저에서 https://localhost로 접속해보면, SSL이 적용된 Nginx가 Spring Boot 애플리케이션으로 요청을 전달하는 것을 확인할 수 있다.
  • 만약 HTTP로 접속하면, HTTPS로 자동으로 리다이렉트 된다.
image.png

마지막 정리.

  • https://localhost로 입력했을 때 이전에 localhost:8080에서 보이던 Spring Boot 애플리케이션 화면이 정상적으로 출력 되었다.
    • Nginx가 SSL 설정과 함께 리버스 프록시 역할을 제대로 수행하고 있는 것이다.
  • 즉, Nginx가 HTTPS 포트(443)에서 들어오는 요청을 받아서 Spring Boot 애플리케이션(8080)으로 전달하고, 그 결과를 브라우저에 출력하는 과정이 모두 정상적으로 동작하고 있는 상태인 것이다.
    • 성공적으로 NginxSpring Boot 애플리케이션이 Docker 환경에서 SSL을 통해 연결된 것을 알 수 있었다.

실행 시키고 싶을때.

  1. 코드 수정.
  2. Tasks → build 실행시켜 jar 파일 생성 시키기
  3. Docker 이미지 재빌드
  • docker-compose down # 기존 컨테이너를 종료
  • docker-compose up --build # Docker 이미지를 재빌드하고 컨테이너를 실행
  1. 브라우저 확인 → https://localhost에 접속하여 Spring Boot 애플리케이션 페이지가 정상적으로 출력되는지 확인 한다.