Docker 이미지는 Dockerhub을 통해 다운받아서 사용할 수 있는데 올려져 있는 이미지들도 누군가 만들어서 Dockerhub에 올려놓은 것이다.
Dockerfile이라는 걸 활용해서 Docker 이미지를 만들 수 있다.
Dockerhub에 올려놓은 Docker 이미지가 아닌 나만의 Docker 이미지를 만들고 싶을 수 있다.
예로 Spring Boot 프로젝트가 있을 때 프로젝트 자체를 Docker 이미지로 만들고 싶다면 이럴때 Dockerfile을 활용하면 나만의 Docker 이미지를 만들고 사용할 수 있다.
FROM 은 베이스 이미지를 생성하는 역할을 한다. Docker 컨테이너 특정 초기 이미지를 기반으로 추가적인 셋팅을 할 수 있다. 여기서 말한 특정 초기 이미지가 곧 베이스 이미지다.
FROM [이미지명]
FROM [이미지명]:[태그명]
태그명을 적지 않으면 해당 이미지의 최신(latest)버전을 사용한다.
# Docker file
FROM openjdk:17-jdk
-------------------------------------------------------------------------
# Docker로 이미지 생성하는 문법
$ docker build -t my-jdk17-serever
# 이미지를 기반으로 컨테이너 뛰우기
$ docker run -d my-jdk17-server
COPY는 호스트 컴퓨터에 있는 파일을 복사해서 컨테이너로 전달한다.
COPY [호스트 컴퓨터에 있는 복사할 파일의 경로] [컨테이너에서 파일이 위치할 경로]
# 예시 (파일)
COPY app.txt /app.txt
# 예시 (폴더)
COPY my-app /my-app/
# 예시 (와일드 카드)
COPY *.txt /text-files/
특정 파일 또는 폴더만 COPY를 하고 싶지 않을 수 있다. 그럴때 .dockerignore를 활용한다.
.dockeignore
readme.txt
dockerfile을 만들고 이미지 생성 및 컨테이너를 실행하면
readme.txt 을 제외하고 COPY된 결과를 볼 수 있다.
ENTRYPOINT컨테이너가 생성되고 최초로 실핼할 때 수행되는 명령어를 뜻한다. 쉽게 설명하자면 컴퓨터의 전원을 키고나서 실행시키고 싶은 명령어를 적으면 된다.
ENTRYPOINT [명령문...]
ENTRYPOINT ["/bin/bash","-c","echo hello"]
@RestController
public class AppController {
@GetMapping("/")
public String home() {
return "Hello World";
}
}
FROM openjdk:17-jdk
COPY build/libs/*SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
$ ./gradlew clean build
$ docker build -t hello-server .
$ docker run -d -p 8080:8080 hello-server
RUN 은 이미지를 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.
RUN [명령문]
RUN npm install
RUN, ENTRYPOINT를 사용하다보면 헷갈리는 경우가 있다. 둘 다 같이 명령어를 실행시키기 때문이다.
하지만 둘의 사용 용도는 다르다. RUN은 이미지 생성 과정에서 필요한 명렬어를 실행시킬 때 사용하고 ENTRYPOINT는 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용한다.
FROM ubuntu
RUN apt update && apt install -y git
ENTRYPOINT ["/bin/bash","-c","sleep 500"]
WORKDIR 으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령문은 해당 디렉터리를 기준으로 실행된다. 작업 디렉터리를 굳이 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이다.
WORKDIR [작업 디렉토리로 사용할 절대 경로]
WORKDIR /usr/src/app
EXPOSE는 컨테이너 내부에서 어떤포트에 프로그램이 실행되는 지를 문서화하는 역할을 한다.
-p의 옵션과 같은 역할은 아니다. 쉽게 표현하자면 EXPOSE 명령어를 쓰나 안 쓰나 작동하는 방식의 영향을 미치지 않는다.
권장사항 일 뿐 실제 뜨는 포트랑 달라도 전형 상관없다.
EXPOSE [포트 번호]
EXPOSE 8080