본문 바로가기

Back-End/Docker

Dockerfile을 활용해 이미지 직접 만들기

Dockerfile이란?

Docker 이미지는 Dockerhub을 통해 다운받아서 사용할 수 있다. 이 Docker 이미지들도 누군가 만들어서 Dockerhub에 올려놓은 것이다. 이 Docker 이미지는 어떻게 만들까

"바로 Dockerfile 이라는 것을 활용해서 Docker 이미지를 만들 수 있다"

Dockerhub에 올려놓은 이미지가 아닌 나만의 Docker 이미지를 만들 수 있다. 내가 만든 SpringBoot 프로젝트 자체를 Docker 이미지로 만들고 싶을 때는 Dockerfile을 활용하면 나만의 Docker 이미지를 만들 수 있게된다.


FROM : 베이스 이미지 생성

[의미]
FROM 
은 베이스 이미지를 생성하는 역할을 한다. Docker 컨테이너를 특정 초기 이미지를 기반으로 추가적인 세팅을 할 수 있다.
여기서 얘기한 특정 초기 이미지가 곧 베이스 이미지이다.

쉽게 얘기해서 우리가 윈도우 컴퓨터를 새로 사서 실행시켜보면 기본 프로그램들(인터넷, 그림판, 메모장 등)이 많이 깔려있다. 베이스 이미지도 이와 똑같다. 컨테이너를 새로 띄워서 미니 컴퓨터 환경을 구축할 때 기본 프로그램이 어떤게 깔려있으면 좋겠는 지 선택하는 옵션이라고 생각하면 된다. 누군가는 JDK가 깔려있는 컴퓨터 환경이 셋팅되기를 바랄 수도 있고, 누군가는 Node가 깔려있는 컴퓨터 환경이 셋팅되기를 바랄 수도 있다. 필요에 따라 베이스 이미지를 고르면 된다. 

[사용법]

# 문법
FROM [이미지명] 
FROM [이미지명]:[태그명]

1. 먼저 내 호스트 컴퓨터에 연습할 디렉토리를 만들자!

일단 desktop에 docker라는 폴더를 생성해줌.
데스크 탑에 만들어준 도커 폴더에 들어가서 docker-practice라는 디렉토리를 만들어준다.
데스크 탑에 만들어둔 도커 폴더 안에 docker-practice라는 폴더가 잘 생성된 것을 볼 수 있다.

2. 인텔리제이에서 docker-practice라는 폴더를 열어주고 Dockerfile 을 생성해줍니다.

잘 생성이 되었으니 인텔리제이 터미널에서 확인해보자

3. 잘 생성 되었는지 확인하기

잘 생성 되었다.
자바 17버전을 베이스 세팅해둘거야 하라는 뜻

4. Dockerfile로 이미지 생성하는 문법

# docker build -t [이미지명]:[태그명] [Dockerfile이 존재하는 디렉토리 경로(상대경로임)]

$docker build -t my-jdk-server .

5.이미지를 기반으로 컨테이너 띄우기

$ docker run -d my-jdk17-server

마지막 줄을 보면 내가 만든 이미지가 띄어져있다!

6. 이미지를 기반으로 컨테이너 띄우기

$ docker run -d my-jdk-17-server

7. 컨테이너 조회하기

$ docker ps # 실행되고 있는 컨테이너가 없다.
$ docker ps -a # 확인해보니 컨테이너가 종료되어 있다.

Docker의 컨테이너는 내부적으로 필요한 명령을 다 수행하면 컨테이너가 저절로 종료된다!

그럼 어떻게 컨테이너 내부를 볼까..?

[종료된 컨테이너에 들어가서 디버깅 하고 싶을 때]

우리가 위 코드를 작성하면 컨테이너가 종료되었다. 왜 그럴까? 내가 잘못 만들었나? 그게 아니고 도커 파일을 그냥 읽고 끝이나면 컨테이너를 종료시키기 때문에 그렇다! 그럼 어떻게 해야해?

# Dockerfile
FROM openjdk:17-jdk

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 500초 동안 시스템을 일시정지 시키는 명령어

위 명령어를 추가함으로써 컨테이너가 바로 종료되지 않고 500초 기다렸다가 종료가 된다. 500초 안에 우리는 docker exec -it를 활용해 컨테이너 내부에 직접 들어가서 디버깅을 하면 된다!


그럼 저 추가된 ENTRYPOINT 가 뭔데?

[ENTRYPOINT : 컨테이너가 시작할 때 실행되는 명령어]

ENTRYPOINT 는 컨테이너가 생성되고 최초로 실행할 때 수행되는 명령어를 뜻한다.

# 문법
ENTRYPOINT [명령문]

# 예시
ENTRYPOINT ["node", "dist/main.js"]