Docker의 볼륨
Docker의 컨테이너 내부에서 생성되는 데이터는 기본적으로 해당 컨테이너의 파일 시스템에 저장된다. 하지만, 이는 컨테이너가 삭제되면 데이터도 함께 삭제되는 한계가 있다. 이런 문제를 해결하기 위해 Docker는 볼륨(Volume)이라는 메커니즘을 제공한다.
이 글에서는 이러한 Volume 중 익명 볼륨(Anonymous Volume)에 대해 알아볼 것이다.
익명 볼륨이란?
익명 볼륨은 이름이 없는 볼륨으로, Docker가 자동으로 생성하고 관리한다. 이름이 지정되지 않았기 때문에 컨테이너 외부에서 직접 참조하거나 관리하기가 어렵지만, 컨테이너와 데이터의 분리를 통해 데이터 유실을 방지할 수 있는 장점이 있다.
익명 볼륨은 주로 아래와 같은 상황에서 사용될 수 있다.
- 특정 컨테이너 실행 중에만 데이터가 필요하고, 이후 관리가 필요하지 않은 경우.
- 테스트 컨테이너를 실행하면서 파일 시스템의 데이터를 격리하고자 할 때.
- mounted volume의 영향을 받지 않는 하위 폴더를 구성해야 하는 경우
익명 볼륨 생성하기
컨테이너를 실행할 때 VOLUME 명령어나 docker run 명령어를 통해 익명 볼륨을 생성할 수 있다.
예를 들어 /posts 경로에 대한 익명 볼륨을 생성하고 싶다면 다음과 같은 명령을 Dockerfile에 추가하면 된다.
# 익명 볼륨 만들기
VOLUME /posts
혹은 다음과 같이 -v 옵션으로 익명 볼륨을 만들 경로를 지정하면 된다.
docker run -p 8080:8080 -v /posts volume:1.0.0
익명 볼륨 사용해 파일 저장 확인해보기
GitHub 코드: https://github.com/seyoungcho2/DockerExample/tree/feature/2.volume-anonymous
익명 볼륨 사용을 위한 준비
익명 볼륨을 사용해보기 위해 다음과 같은 스프링 컨트롤러를 만든다.
data class PostRequest(
val title: String,
val content: String
)
@RestController
class PostController {
@PostMapping("/post")
fun createPost(
@RequestBody postRequest: PostRequest
): String {
val postsDir = File("posts")
if (!postsDir.exists()) {
postsDir.mkdirs()
}
val id = randomUUID().toString()
val file = File(postsDir, "$id.json")
val postJson =
"""
{
"id": "$id",
"title": "${postRequest.title}",
"content": "${postRequest.content}"
}
""".trimIndent()
file.writeText(postJson)
return postJson
}
@GetMapping("/post")
fun getPostById(
@RequestParam id: String
): String {
val file = File("posts/$id.json")
return file.readText()
}
}
이 컨트롤러는 Post를 저장하고 조회하기 위한 컨트롤러로 포스트를 생성하고, 가져올 수 있는 기능을 제공한다.
이렇게 만든 후 ./gradlew bootJar를 실행해 jar 파일을 만들고 다음과 같은 Dockerfile을 만든다.
# JDK 17 이미지 사용하기
FROM eclipse-temurin:17
# 모든 명령이가 실행될 디렉토리 설정
WORKDIR /app
# 익명 볼륨 만들기
VOLUME /app/posts
# 이미지 내부에 들어가야 할 경로 설정. 현재 경로의 모든 파일들이 도커 컨테이너의 app 디렉토리에 복사
COPY build/libs/SimpleApplication-0.0.1-SNAPSHOT.jar app.jar
# 도커 컨테이너 내부의 8080번 포트를 외부로 노출
EXPOSE 8080
# ENTRYPOINT를 사용해 컨테이너가 시작될 때 실행할 명령어를 지정
ENTRYPOINT ["java", "-jar", "app.jar"]
이제 모든 준비가 완료됐으면 다음 명령어를 통해 이미지를 빌드한다.
docker build -t volume:1.0.0 .
이제 이미지가 만들어졌으니 이 이미지를 사용해 컨테이너를 실행해보자. 실행 명령어는 다음과 같다.
docker run -p 8080:8080 volume:1.0.0
그러면 다음과 같은 실행 화면을 볼 수 있다.
포스트 만들기
포스트를 만들기 위해 .http 파일에 다음과 같이 작성해 요청을 실행한다.
POST http://localhost:8080/post
Content-Type: application/json
{
"title": "My First Post",
"content": "This is my first post"
}
그러면 다음과 같이 200응답과 함께 만들어진 포스트의 id가 온다.
이제 이 포스트가 잘 만들었는지 다음 요청을 실행해 확인해보자.
### Get Post by ID
GET http://localhost:8080/post?id=b5377945-9eb0-46fb-99a8-a52f6f2aa1d5
그러면 다음과 같이 포스트가 잘 만들어진 것을 확인할 수 있다.
이 포스트 파일은 익명 볼륨 /app/post에 저장된다.
익명 볼륨에 저장된 파일 확인하기
익명 볼륨에 저장된 파일을 확인하기 위해서는 다음 명령어를 실행해 콘솔을 켠 후
docker exec -it [컨테이너 Id] /bin/sh
app/posts 폴더에 해당 아이디에 해당하는 .json 파일이 있는지 확인하면 된다.
아래는 현재 컴퓨터에서 실행한 결과이고 b5377로 시작하는 파일이 잘 저장된 것을 볼 수 있다.
익명 볼륨 확인하기
익명 볼륨을 확인하기 위해서는 docker inspect 명령어를 사용하면 된다.
docker inspect [컨테이너 Id]
그러면 내부의 Mounts 섹션에 볼륨이 생성돼 있는 것을 볼 수 있다.
일반적으로 익명 볼륨은 /var/lib/docker/volumes/ 경로에 생성된다.
Docker Desktop에서 익명 볼륨 확인하기
익명 볼륨은 Docker Desktop의 Volumes 섹션에서도 확인할 수 있다.
이름을 더블 클릭해서 들어가면 다음과 같이 볼륨 내부도 확인할 수 있다.
익명 볼륨 사용 시 주의할 점
익명 볼륨은 컨테이너가 제거될 때 함께 제거되지 않는다
익명 볼륨은 기본적으로 컨테이너가 제거될 때 함께 제거되지 않는다. 예를 들어 위에서 다룬 컨테이너를 stop 해도, 제거 해도 volume은 그대로 남아있다. 이는 아래에서 확인할 수 있다. docker volume ls가 볼륨 목록을 확인하는 명령어이다.
이런 경우 사용하지 않는 익명 볼륨들이 시스템에 쌓일 수 있는데, docker volume prune 명령어를 통해 제거해주면 된다.
--rm 옵션과 함께 실행된 컨테이너가 제거될 때 익명 볼륨은 함께 제거된다.
--rm 옵션을 넣으면 컨테이너가 중지될 때 컨테이너가 삭제되고, 컨테이너에서 사용되는 리소스가 함께 정리된다. 이때 익명 볼륨도 함께 제거된다.
다음 콘솔에서는 --rm 옵션과 함께 이미지를 사용해 컨테이너를 생성 후 실행하고 docker을 중지한 다음(docker stop) 도커의 볼륨을 확인(docker volume ls)했다.
익명 볼륨이 자동으로 제거된 것을 확인할 수 있다.
익명 볼륨을 터미널에서 만들기
익명 볼륨을 Dockerfile에 지정하지 않더라도, 터미널에서 -v 명령어를 통해 지정할 수 있다.
docker run -p 8080:8080 -d --name postapp --rm -v /app/posts volume:1.0.1
'Docker' 카테고리의 다른 글
[Docker] Bind Mount 통해 호스트 머신의 경로를 컨테이너 경로와 연결하기 (0) | 2025.01.28 |
---|---|
[Docker] Named Volume 이란 무엇인가? 사용 방법과 특징 정리 (0) | 2025.01.27 |
Docker Hub에 이미지 업로드 하기 (0) | 2025.01.25 |
[Docker] 이미지 목록 확인하고 제거하는 방법 한 번에 정리하기 (0) | 2025.01.24 |
[Docker] 도커 이미지 정보 확인하기: docker image inspect (0) | 2025.01.23 |