ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 부트 도커에 올리기(Dockerizing Spring Boot App)
    웹 어플리케이션 2019. 2. 25. 13:36

    이전 포스트 도커(Docker) 설치하기에서 도커가 무엇인지 간략하게 알아보고 도커를 설치했다. 이번 포스트에서는 실제 프로젝트를 이용해 도커 이미지를 만들고 도커 위에 컨테이너를 실행시켜 보도록 한다. 도커 이미지를 만들 프로젝트는 스프링부트 웹 어플리케이션 프로젝트이다.

    목차

    • Dockerfile
    • Docker build
    • Docker run

    Dockerfile

    첫번째로 도커가 이해 할 수 있는 Dockerfile이라는 것을 만들어 줘야 한다. 이 파일에 필요한 디펜던시 예를들어 우리와 같은 경우 어떤 자바를 사용 할 것인지, 어떤 어플리케이션(.jar)를 사용 할 것인지, 어떤 명령어로 이 도커 컨테이너를 실행시켜야 되는지에 대해 명시해야 한다.

    일단 프로젝트 root 디렉토리에 Dockerfile을 만들자.


    Dockerfile의 내부는 다음과 같다. 

    # Start with a base image containing Java runtime
    FROM java:8

    # Add Author info
    LABEL maintainer="f.softwareengineer@gmail.com"

    # Add a volume to /tmp
    VOLUME /tmp

    # Make port 8080 available to the world outside this container
    EXPOSE 8080

    # The application's jar file
    ARG JAR_FILE=build/libs/MySpringApp-0.0.1-SNAPSHOT.jar

    # Add the application's jar to the container
    ADD ${JAR_FILE} to-do-springboot.jar

    # Run the jar file
    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/to-do-springboot.jar"]

    Dockerfile은 명령어들로 구성되어있다. 예를들어서, 아래는 이 스프링 부트 앱이 java 8위에서 실행된다는 뜻이다.

    FROM java:8

    Label은 말 그대로 라벨이다. maintainer를 추가해 이 이미지를 관리하는 사람이 누구인지 명시했다.

    LABEL maintainer="f.softwareengineer@gmail.com"

    이제 VOLUMN이라는 디렉토리를 지정 해 준다. 이 디렉토리 /tmp아래에 이 컨테이너가 필요한 여러가지 데이터를 저장하는 곳이다. 

    VOLUME /tmp

    이 웹 어플리케이션은 도커 컨테이너 내부에서는 8080의 포트를 가지고 돌 것이다. 따라서 이 포트를 외부로 노출시킨다.

    EXPOSE 8080

    ARG JAR_FILE을 이용해 어떤 어플리케이션을 실행시켜야 하는지, 즉 어플리케이션의 실행파일을 연결 해 주어야한다. 우리가 gradle build를 하면 .jar파일이 생성된다. 내 환경에서는 build/libs/아래에 생성되었다. 프로젝트의 환경에 따라 tartget아래에 생성되기도 하도 build아래에 생성되기도 한다. 어쨌든 프로젝트를 빌드 후 .jar파일을 찾아 그 경로를 확인하는게 중요하다. 경로를 확인했으면 경로를 적어주자. 주의 할 점은 상대경로를 적어주어야 한다는 것이다. 안그러면 다른 팀원의 개발환경에서는 실행되지 않을 수 있다.

    ARG JAR_FILE=build/libs/MySpringApp-0.0.1-SNAPSHOT.jar

    이제 이 JAR_FILE에 이름을 붙여준다. 이름은 to-do-springboot.jar이다.

    ADD ${JAR_FILE} to-do-springboot.jar

    여기까지 완료되었다면 어플리케이션을 실행시키기 위한 초석을 마련한 것이다. 이제 어플리케이션을 실행시키기 위한 명령어를 쓰자.

    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/to-do-springboot.jar"]

    ENTRYPOINT가 바로 자바를 실행시키는 것이다. 이 부분에 들어가는 명령어들은 실제 명령어를 스페이스로 나눠놓은 것과 같다. 즉, 우리가 직접 실행 시킬 때는 아래처럼 실행 시킬 것을 그냥 따로따로 리스트로 하나씩 주는 것이다.

    ➜ java -Djava.security.edg=file:/dev/./urandom -jar /to-do-springboot.jar

    Docker build

    이제 작성한 도커파일로 도커 이미지를 만들어야 한다. 도커 이미지를 만드는 명령어는 간단하다. Dockerfile이 존재하는 디렉토리 아래에서 실행시켜야 한다는 것을 명심하라.

    <Dockerfile이 있는 프로젝트의 ROOT 디렉토리>

    ➜ docker build -t to-do-springboot .
    Sending build context to Docker daemon 47.33MB
    Step 1/7 : FROM java:8
    8: Pulling from library/java
    5040bd298390: Downloading 13.59MB/51.36MB
    fce5728aad85: Downloading 4.865MB/18.54MB
    76610ec20bf5: Downloading 5.549MB/42.5MB
    60170fec2151: Waiting
    e98f73de8f0d: Waiting ... Successfully built 9e5f29ac40ed Successfully tagged to-do-springboot:latest

    위와같은 메시지로 Successfully tagged...로 끝나면 완료 된 것이다.

    Docker run

    이제 도커 이미지가 제대로 만들어 졌는지 확인 해 보자. docker images로 현재 이미지를 확인 해 보면 to-do-springboot와 스프링 부트가 사용할 java이미지가 생긴 것을 확인 할 수 있다.

    ➜ docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    to-do-springboot latest 9e5f29ac40ed 2 minutes ago 672MB
    java 8 d23bdf5b1b1b 2 years ago 643MB

    이제 도커이미지를 이용해 도커 컨테이너를 실행 해 보자.

    ➜ docker run -p 5000:8080 to-do-springboot

    이렇게 하면 gradle bootRun을 실행시켰던 것과 같은 로그화면이 뜨기 시작 할 것이다. 여기서 5000:8080에 대해 잠깐 보자. 아까 우리는 도커파일에서 8080을 노출시켰다. 만약에 내가 to-do-springboot말고 다른 웹 앱을 실행시키고 싶다면 그 앱도 로컬환경에서 8080을 사용 할 수 있다. 이 때 같은 포트를 사용하는 앱을 한 서버에서 실행시키면 port가 중복되어 에러가 난다. 그렇다면 내 환경에서는 8080에 실행시키고, 도커에서는 다른 포트에서 실행 시킬 수 있을까? 그럴 때 사용하는게 바로 5000:8080 Porter이다. 이 뜻은 내부적으로는 이 어플리케이션이 8080을 사용하고 있으니 5000으로 날아오는 포트는 전부 이 어플리케이션의 8080포트에 맵핑시켜라 라는 뜻이다. 이렇게 하면 개발 당시에는 8080을 사용하고, 개발 후 도커에 올리고 나서는 5000포트를 이용 할 수 있다는 장점이 있다. 

    브라우저를 켜서 http://localhost:5000/todo/ (이거는 사용한 프로젝트마다 다를 것이므로 프로젝트가 제공하는 API로 테스팅을 해보면 된다.)에 들어간다. 네트워크탭(F12)를 열어 보면 웹 앱이 제대로 실행 된 것을 확인 할 수 있다.

    이번 포스트를 통해 스프링 부트를 도커에 올리는 법을 알아보았다. 계획은 스프링 부트랑 몽고디비를 함께 올리는 것이므로 이후의 포스트에서는 몽고디비를 도커에 올리고 스프링부트를 연결하는 방법에 대해서 포스팅 해 보겠다.

    댓글

f.software engineer @ All Right Reserved