Dockerfile이란?
Dockerfile은 Docker 이미지를 생성하기 위해 사용되는 스크립트 파일이다. 이 파일에는 이미지 생성 과정에서 수행될 명령어들이 순차적으로 작성되어 있으며, 이를 사용해 Docker 이미지를 빌드할 수 있다.
그러면 지금부터 스프링 애플리케이션을 위한 간단한 Dockerfile을 만들어보자. 코드는 다음 위치에 있다.
* 이것은 예제를 위한 Dockerfile이고, 프로덕션을 위한 Dockefile은 더욱 복잡하게 만들어집니다.
Code: https://github.com/seyoungcho2/DockerExample/tree/feature/1.simplespringdocker
스프링 애플리케이션 Dockerfile을 만들기 위한 준비
스프링 애플리케이션을 실행하기 위해서는 기본적으로 스프링 애플리케이션을 실행하기 위한 jar 파일과 jar 파일을 실행하기 위한 JDK가 필요하다. 위의 코드를 받아 다음 코드를 터미널에서 실행해보자.
./gradlew bootJar
그러면 다음과 같이 BUILD SUCCESSFUL 메세지가 뜬다.
빌드가 성공했으므로 build/libs/SimpleApplication-0.0.1-SNAPSHOT.jar 파일이 생긴 것을 볼 수 있다.
이제 Dockerfile을 작성하기 위한 준비가 모두 마쳐졌다. 이제 Dockerfile을 작성해보자.
Dockerfile 작성하기
1. Docker Hub에서 실행 환경 확인하기
jar 파일을 실행하기 위해서는 알맞은 JDK가 필요하다. 이를 직접 구성해도 되지만, Docker Hub에서 가져올 수도 있다. 여기에서는
https://hub.docker.com/_/eclipse-temurin 을 사용한다.
이제 이 환경을 사용하는 Dockerfile을 작성해보자. 사용하도록 하는 방법은 간단하다. FROM을 쓰고 사용할 이미지의 이름을 입력하면 된다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
2. 기본 디렉토리 설정하기
이제 실행 환경을 설정했으니, 기본 디렉토리를 설정해보자. 기본 디렉토리는 WORKDIR 명령어로 설정 가능하다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
# 모든 명령이가 실행될 디렉토리 설정
WORKDIR /app
이곳에서는 app 디렉토리를 기본 디렉토리로 설정했다.
3. jar 파일 복사해 app 디렉토리에 넣기
이제 위에서 빌드한 jar 파일을 복사해 위의 디렉토리에 넣어보자. 기본 디렉토리가 설정되어 있으므로 별도 설정 없이 COPY [현재 jar 파일 경로] [복사할 경로] 를 실행하면 app 디렉토리에 넣어진다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
# 모든 명령이가 실행될 디렉토리 설정
WORKDIR /app
# 이미지 내부에 들어가야 할 경로 설정. 현재 경로의 모든 파일들이 도커 컨테이너의 app 디렉토리에 복사
COPY build/libs/SimpleApplication-0.0.1-SNAPSHOT.jar app.jar
즉 위의 코드는 app/app.jar에 SimpleApplication-0.0.1-SNAPSHOT.jar을 복사하는 명령어이다.
4. 외부에 오픈할 포트 문서화 하기
컨테이너가 실행되는 환경은 격리된 공간으로 실제 기기의 환경과 완전히 격리되어 있다. 스프링 애플리케이션은 기본적으로 8080번 포트에서 실행되므로 이 포트를 열어야 함을 명시해야 이후 이미지를 실행할 때 어떤 포트를 열어야 하는지 명확히 할 수 있다. 이를 위해 EXPOSE 8080을 적어 놓아 어떤 포트를 열어야 할지 명확히 한다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
# 모든 명령이가 실행될 디렉토리 설정
WORKDIR /app
# 이미지 내부에 들어가야 할 경로 설정. 현재 경로의 모든 파일들이 도커 컨테이너의 app 디렉토리에 복사
COPY build/libs/SimpleApplication-0.0.1-SNAPSHOT.jar app.jar
# 도커 컨테이너 내부의 8080번 포트를 외부로 노출해야 함을 문서화
EXPOSE 8080
5. jar 파일 실행하기
앞의 EXPOSE 코드까지는 이미지 파일이 만들어지면서 실행된다. 하지만, jar 파일을 실행하는 코드는 실제로 컨테이너가 실행될 때 실행돼야 한다. 이를 위해 Docker는 ENTRYPOINT라는 명령어를 제공한다.
ENTRYPOINT는 Dockerfile에서 도커 컨테이너가 시작될 때 실행할 명령어를 지정하는 데 사용된다. 이 명령어는 컨테이너가 시작될 때마다 항상 실행되며, 주로 애플리케이션을 실행하는 데 사용된다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
# 모든 명령이가 실행될 디렉토리 설정
WORKDIR /app
# 이미지 내부에 들어가야 할 경로 설정. 현재 경로의 모든 파일들이 도커 컨테이너의 app 디렉토리에 복사
COPY build/libs/SimpleApplication-0.0.1-SNAPSHOT.jar app.jar
# 도커 컨테이너 내부의 8080번 포트를 외부로 노출
EXPOSE 8080
# ENTRYPOINT를 사용해 컨테이너가 시작될 때 실행할 명령어를 지정
ENTRYPOINT ["java", "-jar", "app.jar"]
예를 들어, 이 Dockerfile에서 ENTRYPOINT ["java", "-jar", "app.jar"]는 컨테이너가 시작될 때 java -jar app.jar 명령어를 실행하여 Spring Boot 애플리케이션을 시작한다.
자 이제 첫 Dockerfile이 완성됐다. 완성된 코드는 다음과 같다.
이미지 만들기
이제 위 Dockerfile을 실행해 이미지를 만들어보자. 이미지를 만드는 방법은 간단하다. 단순히 다음 명령어를 입력하면 된다.
docker build .
이 명령어가 입력되면, 이 디렉토리 내부의 Dockerfile을 모두 찾아 이미지를 만들며 만들어진 이미지의 아이디는 빌드 마지막 줄의 : 이후의 값을 통해 확인할 수 있다.
이미지 사용해 컨테이너 실행하기
이제 만들어진 이미지를 사용해 컨테이너를 실행해보자. 컨테이너를 실행하기 위해서는 docker run 명령어를 실행하면 된다.
docker run -p [기기 포트]:[컨테이너 포트] [이미지 Id]
여기서 -p는 publish의 약자이며, 컨테이너의 환경은 실제 기기의 환경과 완전히 격리돼 있기 때문에 직접 연결해줘야 기기에서 접근할 수 있어 연결할 포트를 설정하기 위해 사용된다.
이제 컨테이너를 실행해보자. 다음 명령어를 통해 컨테이너를 실행한다. 이미지 Id는 위의 이미지 만들기 섹션에서 확인한 이미지 Id를 넣어주면 된다.
docker run -p 8080:8080 5124112d0a1e51d59858884e4970b1a6330b8bf72c8218039e92e0ca204ccca8
그러면 다음과 같이 스프링 애플리케이션이 잘 실행되는 것을 볼 수 있다.
만약 같은 이미지를 사용해 스프링 애플리케이션을 하나 더 실행하고 싶다면, 다음과 같이 기기의 포트만 바꿔서 실행해주면 된다.
docker run -p 8081:8080 5124112d0a1e51d59858884e4970b1a6330b8bf72c8218039e92e0ca204ccca8
실행된 애플리케이션 확인하기
이 애플리케이션은 내부에 이런 코드가 있어 /hello path로 접속하면 Hello Docker가 나온다.
@RestController
class SimpleController {
@GetMapping("/hello")
fun hello(): String {
return "Hello, Docker!"
}
}
localhost:8080/hello 로 접속하면 Hello, Docker! 가 잘 프린트 되는 것을 볼 수 있고
두 번째로 실행한 스프링 애플리케이션을 확인하기 위해 localhost:8081/hello 로 접속해도 Hello, Docker! 가 잘 프린트 되는 것을 확인할 수 있다.
'Docker' 카테고리의 다른 글
[Docker] 명령어로 컨테이너 목록 확인하고 중지하기 (0) | 2025.01.22 |
---|---|
Docker의 이미지와 컨테이너의 차이 알아보기 (0) | 2025.01.20 |
Docker란 무엇이고 왜 사용할까? Docker와 가상 머신의 차이점 완벽 정리 (0) | 2025.01.19 |