[Docker] Dockerfile + docker-compose 를 사용하여 SpringBoot 프로젝트 실행시키기

반응형
728x90
반응형

Dockerfile

애플리케이션을 패키징하기 위한 간단한 스크립트다. Dockerfile은 일련의 인스트럭션으로 구성되어있는데, 익스트럭션을 실행한 결과로 도커 이미지가 만들어진다. 어떠한 애플리케이션이라도 패키징할 수 있다. 

Dockerfile
FROM diamol/node

ENV TARGET="blog.sixeyed.com"
ENV METHOD="HEAD"
ENV INTERVAL="3000"

WORKDIR /web-ping
COPY app.js .

CMD ["node", "/web-ping/app.js"]
인스트럭션 설명 예제에서 사용 방법
FROM 모든 이미지는 다른 이미지로부터 출발한다.
FROM 뒤에 지정된 이미지를 시작점으로 지정한다.
https://hub.docker.com/r/diamol/node
diamol/node 이미지를 시작점으로 지정했다.
diamol/node 이미지에는 web-ping 애플리케이션을 실행하는데 필요한 런타임인 Node.js가 설치되어있다.
ENV 환경변수 값을 지정하기 위한 인스트럭션이다.
값을 지정하기위해 [key]="[value]" 형식을 따른다.
ENV 인스트럭션이 3번 사용되어, 3개의 환경변수를 설정했다.
WORKDIR 컨테이너 이미지 파일 시스템에 디렉터리를 만들고, 해당 디렉터리를 작업 디렉터리로 지정하는 인스트럭션이다.
구분자는 /를 사용한다.
리눅스 컨테이너에서는 /web-ping 디렉터리를 만들고, 윈도 컨테이너에서는 C:\web-ping 디렉터리를 만든다.
COPY 로컬 파일 시스템의 파일 혹은 디렉터리를 컨테이너 이미지로 복사하는 인스트럭션이다. 
[원본경로][복사경로] 형식으로 지정하면 된다. 
app.js 파일을 이미지의 작업 디렉터리로 복사했다.
CMD 도커가 이미지로부터 컨테이너를 실행했을때 실행할 명령을 지정하는 인스트럭션이다. Node.js 런타임이 애플리케이션을 시작하도록 app.js를 지정했다. 

 

 

docker-compose.yml

위에서 알아본 Dockerfile은 단순히 애플리케이션을 패키징하기 위한 스크립트다. 만약, 프론트엔드, 백엔드 API, 데이터베이스를 갖춘 애플리케이션을 패키징하려면 각 컴포넌트에 하나씩 3개의 Dockerfile 스크립트가 필요한데, 이 컨테이너는 누가 실행해야할까?

직접 순서대로 각각의 컨테이너를 도커 명령행을 통해 일일이 옵션을 지정해가며 실행할 수도 있겠지만, 이런 수동 프로세스는 온갖 실수와 오류의 원천이 되기쉽다. 

 

위 문제를 해결하기위해, docker-compose 파일에 애플리케이션의 구조를 정의한다.

도커 컴포즈 파일은 애플리케이션의 '원하는 상태', 모든 컴포넌트가 실행 중일때 어떤 상태여야 하는지를 기술하는 파일이다. 명령어를 사용하여 컨테이너를 실행할때 지정하는 모든 옵션을 모아놓은 단순한 형식의 파일이다. docker-compose 파일을 작성하고나면 도커 컴포즈 도구를 사용하여 애플리케이션을 실행한다. 그러면 도커 컴포즈가 컨테이너, 네트워크, 볼륨 등 필요한 모든 도커 객체를 만들도록 도커 API에 명령을 내린다.

 

docker-compose.yml
version: '3.7'

services:
  
  todo-web:
    image: diamol/ch06-todo-list
    ports:
      - "8020:80"
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat

위 스크립트의 내용은 도커 네트워크에 도커 컨테이너 하나가 연결된 간단한 애플리케이션을 기술한 것이다.

최상위문(statement) 설명
version 이 파일에 사용된 도커 컴포즈 파일 형식의 버전을 가리킨다.
services 애플리케이션을 구성하는 모든 컴포넌트를 열거하는 부분이다.
실제 컨테이너 대신 서비스(service) 개념을 단위로 삼는다.
하나의 서비스를 같은 이미지로 여러 컨테이너에서 실행할 수 있기 때문이다.
컨테이너의 이름이자 도커 네트워크 상에서 다른 컨테이너들이 해당 컨테이너를 식별하기 위한 DNS 네임으로도 쓰인다.
networks 서비스 컨테이너가 연결된 모든 도커 네트워크를 열거하는 부분이다.
ports 공개할 포트에 대한 정보

 

도커 컴포즈를 사용해 이 애플리케이션을 실행하면, 컨테이너 하나가 실행돼 스크립트에 정의된 구성을 갖춘다. 

스크립트 분석 설명
todo-web: 서비스 이름
image: diamol/ch06-todo-list diamol/ch06-todo-list 이미지로부터 단일 컨테이너로 실행된다.
ports:
      - "8020:80"
호스트 컴퓨터(로컬)의 80번 포트로 자신의 8002번 포트를 공개한다.
networks:
      - app-net
컨테이너가 접속할 도커 네트워크를 정의하는 필드다.
서비스가 구성될 네트워크 이름은 app-net이다. 
networks:
  app-net:
    external:
      name: nat
위 app-net 네트워크는 nat이라는 이름이 외부 네트워크로 연결된다. external 필드의 의미는 nat 네트워크가 이미 존재하므로 새로 생성하지 말라는 뜻이다.

 

위 도커 컴포즈 파일은 아래의 명령어를 실행한 것과 같다.

docker container run -p 8020:80 --name todo-web --network nat diamol/ch06-todo-list

 

여기까지 기본 개념을 '도커 교과서' 교재를 참고하였다.

 

 

SpringBoot 프로젝트 띄어보기

프로젝트 하위에 Dockerfile 파일을 추가하였다.

Dockerfile
FROM gradle:jdk11

WORKDIR /app
COPY build/libs/studyolle-0.0.1-SNAPSHOT.jar /app/app.jar

EXPOSE 8081
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

 

분석
인스트럭션  
FROM 도커 생성시의 기반 이미지를 선언한다.
WORKDIR 컨테이너 이미지 파일 시스템에 디렉터리를 만들고, 작업 디렉토리를 설정한다.
COPY build/libs/xxx.jar 파일을 /app/app.jar 라는 이미지 파일로 복사한다.
EXPOSE 도커 컨테이너 내부에서 8081의 포트를 가지고 수행된다.
8081 포트를 외부로 노출시킨다.
(하지만 이 포트가 반드시 호스트의 포트와 바인딩되는 것은 아니다. 단지 8081를 사용한다는 선언일 뿐이다.)
ENTRYPOINT 애플리케이션을 실행시키기 위한 명령어(스크립트)를 작성한다.

 

 

jar 파일 경로

gradle > build 가 정상 수행되면, 아래와 같이 build/libs 경로에 xxx.jar 파일이 생성된다.

 

 

docker/docker-compose.yml

 

docker-compose.yml
version: "3.9"

services:
  db:
    image: postgres:latest
    container_name: studyolle-postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DATABASE: studyolle
      POSTGRES_USER: studyollejpa
      POSTGRES_ROOT_PASSWORD: 1234
      POSTGRES_HOST_AUTH_METHOD: "trust"
    networks:
      - internal-network
  studyolle:
    container_name: studyolle-kotlin
    build: ../
    ports:
      - "8081:8080"
    networks:
      - internal-network
networks:
  internal-network:
    driver: bridge

1) service명 : db

db:
  image: postgres:latest
  container_name: studyolle-postgres
  restart: always
  ports:
    - "5432:5432"
  environment:
    POSTGRES_DATABASE: studyolle
    POSTGRES_USER: studyollejpa
    POSTGRES_ROOT_PASSWORD: 1234
    POSTGRES_HOST_AUTH_METHOD: "trust"
  networks:
    - internal-network

 

2) service명 : studyolle

studyolle:
  container_name: studyolle-kotlin
  build: ../
  ports:
    - "8081:8080"
  networks:
    - internal-network

 

 

도커 컴포즈 명령어 

docker-compose.yml 파일이 있는 디렉터리로 이동하고, 아래 명령어로 애플리케이션을 시작할 수 있다.

docker compose -f docker-compose.yml up -d --build

1) 아래와 같이 오류가 발생할 경우

▶ gradle > build > bootJar 클릭한다.

 

2) 성공한 경우

 

3) docker dashboard > image 확인

 

4) docker dashboard > containers 확인

 

 

 

반응형

Designed by JB FACTORY