4.2.애플리케이션 빌드 실전 예제: 자바 소스 코드

  • 자바 스프링부트를 사용해 구현한 애플리케이션을 빌드하고 실행
  • 빌드하고 실행하기 위한 도구는 모두 도커 이미지를 통해 가져온다.
  • 이 절의 목적은 닷넷 코어(.NET Core), 얼랭(Erlang) 등 컴파일이 필요한 언어라면 어떤 언어라도 적용할 수 있는 패턴을 익히는 것

메이븐을 사용해 자바 애플리케이션을 빌드하는 Dockerfile 스크립트

001) FROM diamol/maven AS builder
002) 
003) WORKDIR /usr/src/iotd
004) COPY pom.xml .
005) RUN mvn -B dependency:go-offline
006) 
007) COPY . .
008) RUN mvn package
009) 
010) # app
011) FROM diamol/openjdk
012) 
013) WORKDIR /app
014) COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .
015) 
016) EXPOSE 80
017) ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
  1. 001~008: builder 단계에서는 먼저 이미지를 작업 디렉터리를 만든 다음 이 디렉터리에 pom.xml 파일을 복사하면서 시작된다. 이 파일에는 메이븐에서 수행할 빌드 정차가 정의돼 있다.
  2. 001: 기반 이미지로 메이븐과 OpenJDK를 포함하는 이미지를 사용
  3. 005: 메이븐이 실행돼 필요한 의존 모듈을 내려받는다.
  4. 007: 나머지 소스코드를 복사
  5. 008: 애플리케이션을 빌드하고 패키징
  6. 011: 자바 11 런타임을 포함하지만 메이븐을 포함하지 않는 이미지를 사용
  7. 013: 작업 디렉터리 생성
  8. 014: 앞서 builder 단계에서 만든 JAR 파일을 복사
  9. 016: 애플리케이션은 80포트를 주시하는 웹 서버 애플리케이션. 이 포트를 EXPOSE 인스트럭션을 통해 외부로 공개해야 한다.
  10. 017: ENTRYPOINT 인스트럭션은 CMD 인스트럭션과 같은 기능을 하는 인스트럭션. 해당 이미지로 컨테이너가 실행되면 도커가 이 인스트럭션에 정의된 명령을 실행. 이 이미지의 경우 java 명령으로 빌드된 JAR 파일을 실행

Dockerfile 스크립트 빌드

001)  docker build -t image-of-the-day .
002) [+] Building 34.1s (17/17) FINISHED                                                                                                                                                                      
003)  => [internal] load build definition from Dockerfile                                                                                                                                                0.0s
004)  => => transferring dockerfile: 341B                                                                                                                                                                0.0s
005)  => [internal] load .dockerignore                                                                                                                                                                   0.0s
006)  => => transferring context: 2B                                                                                                                                                                     0.0s
007)  => [internal] load metadata for docker.io/diamol/openjdk:latest                                                                                                                                    3.5s
008)  => [internal] load metadata for docker.io/diamol/maven:latest                                                                                                                                      3.8s
009)  => [auth] diamol/maven:pull token for registry-1.docker.io                                                                                                                                         0.0s
010)  => [auth] diamol/openjdk:pull token for registry-1.docker.io                                                                                                                                       0.0s
011)  => [internal] load build context                                                                                                                                                                   0.0s
012)  => => transferring context: 9.76kB                                                                                                                                                                 0.0s
013)  => [builder 1/6] FROM docker.io/diamol/maven@sha256:bc24b7b3beaae18550590fd986b09d7833c4daedb2632c76daddab21351b934f                                                                              14.1s
014)  => => resolve docker.io/diamol/maven@sha256:bc24b7b3beaae18550590fd986b09d7833c4daedb2632c76daddab21351b934f                                                                                       0.0s
015)  => => sha256:bc24b7b3beaae18550590fd986b09d7833c4daedb2632c76daddab21351b934f 1.41kB / 1.41kB                                                                                                      0.0s
016)  => => sha256:088997457a8974eaac75aeb011b9589606b22fba0c660ef63ee71ec3f4e6feee 2.42kB / 2.42kB                                                                                                      0.0s
017)  => => sha256:4c0955102f3f5a174781c0781a7ab326abd75b82fb5b73821afa349206630e7e 8.92kB / 8.92kB                                                                                                      0.0s
018)  => => sha256:c78c297fb0d010ee085f95ae439636ecb167b050c1acb4273bd576998cf94a83 49.18MB / 49.18MB                                                                                                    4.8s
019)  => => sha256:06af62193c25241eb123af8cf115c7a6298e834976fe148ac79ec11a7ca06ee5 7.69MB / 7.69MB                                                                                                      3.2s
020)  => => sha256:8b846e1b73901174c506ae5e6219ac2f356ef71eaa5896dfbc238dc67ca4bf73 9.98MB / 9.98MB                                                                                                      4.8s
021)  => => sha256:fb44d26a138a8d064a4ab8f9b472c64e7136c2482ec5af19bab8811b6d2c15b7 52.17MB / 52.17MB                                                                                                    7.6s
022)  => => extracting sha256:c78c297fb0d010ee085f95ae439636ecb167b050c1acb4273bd576998cf94a83                                                                                                           0.9s
023)  => => sha256:39642fd375ee8d38fc5c53324d4a02c9cf405fcac34ce88cc4d5913274246cb6 210B / 210B                                                                                                          5.1s
024)  => => sha256:0328821646cca37a6d16b29f865b06f587912b17e84f293bc7c08bbb3afeee93 5.28MB / 5.28MB                                                                                                      6.1s
025)  => => sha256:582c31bf5e2daffdf5c6e05aecaefab313a0b8e776f9ff1575ad3a05973085f4 200.40MB / 200.40MB                                                                                                 12.2s
026)  => => extracting sha256:06af62193c25241eb123af8cf115c7a6298e834976fe148ac79ec11a7ca06ee5                                                                                                           0.1s
027)  => => extracting sha256:8b846e1b73901174c506ae5e6219ac2f356ef71eaa5896dfbc238dc67ca4bf73                                                                                                           0.1s
028)  => => sha256:529d17dd69ab43de9e243244bf7156c70339386a8571afdf313d05fec3e75dc9 9.58MB / 9.58MB                                                                                                      7.6s
029)  => => extracting sha256:fb44d26a138a8d064a4ab8f9b472c64e7136c2482ec5af19bab8811b6d2c15b7                                                                                                           0.8s
030)  => => sha256:6b8169d349247080880be851b72f835bb8d922ed11366ec88ade11f879a2c6d7 853B / 853B                                                                                                          7.9s
031)  => => sha256:7997087f808e3e962fa04c72a22f693930bff7640f2ef74a6be97fd09eb14797 360B / 360B                                                                                                          7.9s
032)  => => extracting sha256:0328821646cca37a6d16b29f865b06f587912b17e84f293bc7c08bbb3afeee93                                                                                                           0.1s
033)  => => extracting sha256:39642fd375ee8d38fc5c53324d4a02c9cf405fcac34ce88cc4d5913274246cb6                                                                                                           0.0s
034)  => => extracting sha256:582c31bf5e2daffdf5c6e05aecaefab313a0b8e776f9ff1575ad3a05973085f4                                                                                                           1.5s
035)  => => extracting sha256:529d17dd69ab43de9e243244bf7156c70339386a8571afdf313d05fec3e75dc9                                                                                                           0.1s
036)  => => extracting sha256:6b8169d349247080880be851b72f835bb8d922ed11366ec88ade11f879a2c6d7                                                                                                           0.0s
037)  => => extracting sha256:7997087f808e3e962fa04c72a22f693930bff7640f2ef74a6be97fd09eb14797                                                                                                           0.0s
038)  => [stage-1 1/3] FROM docker.io/diamol/openjdk@sha256:bc11278602c48a60f71ea01031c54a73878d19db4803f7dd8705aa77bab89808                                                                             5.3s
039)  => => resolve docker.io/diamol/openjdk@sha256:bc11278602c48a60f71ea01031c54a73878d19db4803f7dd8705aa77bab89808                                                                                     0.0s
040)  => => sha256:bc11278602c48a60f71ea01031c54a73878d19db4803f7dd8705aa77bab89808 1.41kB / 1.41kB                                                                                                      0.0s
041)  => => sha256:0af0464095ea140f43a30b4cdee3b339a22635efcd930c680f17daee14afa7da 1.37kB / 1.37kB                                                                                                      0.0s
042)  => => sha256:17e883a5a4c7fa8e70d958b062d11575df249107a3053563f1e4de61a77c0039 5.67kB / 5.67kB                                                                                                      0.0s
043)  => => sha256:706ee5d0a6b53d9257cbea22d8409fb22c867ab3a001c65f6b8bfd37dace0e58 25.86MB / 25.86MB                                                                                                    1.7s
044)  => => sha256:303a8d33f3a602102b6a15a1f7974fc79449cdcff2c2fa6709b56cd1ac792384 3.12MB / 3.12MB                                                                                                      0.4s
045)  => => sha256:93b8b66a2613c2e81c20d5f33497aaa0c185225f7b1a0fc1478b628ad5bce829 211B / 211B                                                                                                          0.4s
046)  => => sha256:4b08a8fe7570eea8d3f52461e1667f5809826377f1ee2f99e5cc9690946de148 46.11MB / 46.11MB                                                                                                    4.3s
047)  => => sha256:5536d457e12456a73a534d7de853981653618af70af4b4d0bea264f332236f5e 1.99MB / 1.99MB                                                                                                      1.5s
048)  => => extracting sha256:706ee5d0a6b53d9257cbea22d8409fb22c867ab3a001c65f6b8bfd37dace0e58                                                                                                           0.5s
049)  => => extracting sha256:303a8d33f3a602102b6a15a1f7974fc79449cdcff2c2fa6709b56cd1ac792384                                                                                                           0.1s
050)  => => extracting sha256:93b8b66a2613c2e81c20d5f33497aaa0c185225f7b1a0fc1478b628ad5bce829                                                                                                           0.0s
051)  => => extracting sha256:4b08a8fe7570eea8d3f52461e1667f5809826377f1ee2f99e5cc9690946de148                                                                                                           0.7s
052)  => => extracting sha256:5536d457e12456a73a534d7de853981653618af70af4b4d0bea264f332236f5e                                                                                                           0.1s
053)  => [stage-1 2/3] WORKDIR /app                                                                                                                                                                      0.2s
054)  => [builder 2/6] WORKDIR /usr/src/iotd                                                                                                                                                             0.1s
055)  => [builder 3/6] COPY pom.xml .                                                                                                                                                                    0.0s
056)  => [builder 4/6] RUN mvn -B dependency:go-offline                                                                                                                                                 13.9s
057)  => [builder 5/6] COPY . .                                                                                                                                                                          0.0s
058)  => [builder 6/6] RUN mvn package                                                                                                                                                                   2.1s
059)  => [stage-1 3/3] COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .                                                                                                                 0.0s
060)  => exporting to image                                                                                                                                                                              0.0s
061)  => => exporting layers                                                                                                                                                                             0.0s
062)  => => writing image sha256:47e65cda0048acc09e42776c0a238acabf1966445c6a22b7d55fcbe3a614b798                                                                                                        0.0s
063)  => => naming to docker.io/library/image-of-the-day
  1. 058: 메이븐을 사용해 자바 애플리케이션을 JAR 파일로 패키징하는 부분이다.
  2. 059: 앞서 builder 단계에서 패키징된 JAR 파일을 빌드 마지막 단계에서 복사한다.

컨테이너 실행

  • 이 애플리케이션은 NASA의 오늘의 천문 사진 서비스Astronomy Picture of the Day에서 오늘 자 사진을 받아오는 REST API
  • 이 API는 이번 장에서 실행해 볼 전체 애플리케이션의 한 부분. 앞으로 여러 개의 컨테이너를 실행 돼 이들이 서로 통신 할 것
  • 컨테이너는 실행될 때 부여되는 가상 네트워크 내 가상 IP를 통해 서로 통신한다.
001)  docker network create nat
002) d5f34e061e8b4bd0c244b5056c609c6278428a589b471ac29d28c6cae6945b8f

앞서 빌드한 이미지로부터 컨테이너를 실행하되, 80번 포트를 호스트 컴퓨터를 통해 공개하고 nat 네트워크에 컨테이너를 접속

001)  docker container run --name iotd -dp 800:80 --network nat image-of-the-day
002) 0e4cd08c9f1a5ad8b16eaf6ea0dbae61e1192e85150448be61eb74d4ab8a5cd4

http://localhost:800/image 로 접근하면 NASA에서 제공하는 오늘의 사진에 대한 정보를 JSON 포맷으로 볼 수 있다.

{
  "url": "https://apod.nasa.gov/apod/image/2306/NorthSaturn_Cassini_960.jpg",
  "caption": "Saturn's Northern Hexagon",
  "copyright": "\nNASA,\nESA,\nJPL,\nSSI,\nCassini Imaging Team\n"
}

links

social