Dockerfile 개요
- 도커는 Dockerfile을 사용하여 이미지를 제작할 수 있다
- Dockerfile은 코드 형태의 텍스트 문서이며, 여러 가지 지시어를 사용하여 이미지를 제작할 수 있다.
- 일반적으로 이미지를 생성할 때 commit 이나 import 보다는 Dockerfile을 사용한다.
- 컨테이너가 실행하는 CMD 또는 ENTRYPOINT 는 commit 이나 import 로는 지정하기 어렵기 때문
- 코드 형태로 되어 있어 버전 관리에 용이함
- 이미지의 기능을 파악하기도 쉬움
Dockerfile 지시어
지시어 | 설명 |
---|---|
FROM | 베이스 이미지 지정 |
RUN | 이미지를 생성하면서 실행할 명령 지정 |
ENTRYPOINT | 컨테이너의 애플리케이션 지정 |
EXPOSE | 컨테이너의 포트 지정 |
ADD | 이미지 생성시 파일 추가 |
VOLUME | 컨테이너의 볼륨 지정 |
WORKDIR | 컨테이너 작업 디렉토리 지정 |
MAINTAINER | 이미지 작성자 명시 |
CMD | 컨테이너의 애플리케이션 지정 |
LABEL | 이미지의 라벨 지정 |
ENV | 컨테이너의 환경 변수 지정 |
COPY | 이미지 생성시 파일 복사 |
USER | 컨테이너의 사용자 지정 |
- RUN, CMD, ENTRYPOINT 지시어들은 exec 과 shell 형식으로 사용할 수 있음
- exec 형식은 명령을 쉘을 통해 실행하지 않으며, shell 형식은 /bin/sh 과 같은 쉘을 통해 지정된명령을 실행한다.
형식 | 표현방법 |
---|---|
exec | ["yum", "-y", "install", "httpd"] |
shell | yum -y install httpd |
RUN, CMD, ENTRYPOINT
RUN
- 보통 패키지 설치 등에 사용
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
curl \
nginx
CMD
- CMD 명령의 주용도는 컨테이너를 실행할 때 사용하는 default를 설정
- 명령이나 인자값이 변경될 수 있고 컨테이너에서 명령 설정하지 않을 시 CMD에 기재된 명령을 기본값으로 실행
FROM centos:7
CMD echo "This is a CentOS 7"
- docker run 실행 시 아무런 커맨드를 주지 않으면 CMD 명령 실행
$ docker run -it --rm <image-name>
This is a CentOS 7
$
- echo " " 라고 실행할 커맨드를 주게 되면 CMD 는 무시되고 커맨드가 실행
$ docker run -it --rm <image-name> echo "This is a Ubuntu 18.04"
This is a Ubuntu 18.04
$
ENTRYPOINT
- docker run 실행 시 실행되는 명령
- CMD에서 설정한 default 파라미터가 ENTRYPOINT 에서 사용
- 인자로 명령이 수정 불가능하여 사용자에 의해 변경되지 않고 고정적으로 실행될 명령을 사용할 때 많이 씀
- 같은 명령에 다른 옵션은 수정가능
FROM ubuntu
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
- docker run 명령 실행 시 파라미터 주면 CMD 는 사용되지 않지만 ENTRYPOINT 는 사용됌.
- 이것이 가장 큰 차이점
$ docker run -it --rm <image-name>
Hello world
$ docker run -it --rm <image-name> bye
Hello bye
$
- shell form 으로 실행 시 변수 등을 그대로 가능.
FROM centos
ENTRYPOINT ["echo","$HOME"]
$ docker run -it --rm <image-name>
$HOME
$
- exec form 은 변수가 변환됌.
FROM centos
ENTRYPOINT echo $HOME
$ docker run -it --rm <image-name>
/root
$
- CMD는 명령과 인자값이 변경될 수 있고, 컨테이너에서 명령 설정하지 않을 시 CMD에 기재된 명령을 기본값으로 실행.
- ENTRYPOINT는 명령 수정이 불가능하여 사용자에 의해 변경되지 않고 고정적으로 실행될 명령은 ENTRYPOINT를 사용하는것이 좋음.
centos 기반에서 apache 서비스를 실행하는 이미지를 제작하는 예시 Dockerfile
[root@docker ~]# cat > /root/Dockerfile
FROM centos:latest
RUN yum -y install httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] ENV WEBPORT 80
EXPOSE ${WEBPORT}
EXPOSE 443
VOLUME /var/www/html
COPY index.html /var/www/html/index.html
dockerfile 이미지 제작
[root@docker ~]# docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
- docker build 명령으로 Dockerfile을 지정하여 이미지를 제작할 수 있음.
- 필수 옵션은 아니지만 -t 옵션으로 이미지 이름을 지정하는 것이 좋음. 그렇지 않으면 이미지를 사용할 때 ID 값으로 사용해야 함.
- PATH에는 Dockerfile 이라는 이름의 파일을 가지고 있는 디렉토리 경로를 지정해야 하며, 만약 파일이름이 Dockerfile이 아닌 경우 다른 옵션을 추가로 사용해야 함.
- Dockerfile을 작성할 때 작업용 디렉토리를 생성하고 접근하여 사용하는 것을 권장
- 이미지를 제작하면서 필요한 파일을 COPY하거나 ADD할 때 같은 위치에 있으면 상대경로로 적을 수 있어 편리하기 때문
//작업용 디렉토리 생성
[root@docker ~]# mkdir centos_web && cd centos_web
//Dockerfile 작성
[root@docker centos_web]# cat > Dockerfile
FROM centos:latest
RUN yum -y install httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] ENV WEBPORT 80
EXPOSE ${WEBPORT}
EXPOSE 443
VOLUME /var/www/html
COPY index.html /var/www/html/index.html
[root@docker centos_web]# echo "CentOS apache" > index.html
[root@docker centos_web]# docker build -t JadenPark/docker:centosweb .
Successfully built f919b51ad04d
Successfully tagged JadenPark/docker:centosweb
[root@docker centos_web]# docker images JadenPark/docker:centosweb
REPOSITORY TAG IMAGE ID CREATED SIZE
JadenPark/docker centosweb f919b51ad04d 28 seconds ago 252MB
//지정했던 설정 확인
[root@docker centos_web]# docker inspect JadenPark/docker:centosweb
"ExposedPorts": {
"443/tcp": {}
},
...
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/usr/sbin/httpd",
"-D",
"FOREGROUND"
],
...
"Volumes": {
"/var/www/html": {}
},
...
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:2653d992f4ef2bfd27f94db643815aa567240c37732cae1405ad1c1309ee9859",
"sha256:28571101685b4f9ef9a9eaa99ee3b99a2588d5bb9b9a9e1ebad451386530ee63",
"sha256:33845f856dab3eeef1a69a5f3f5b673a1c7d2dc8c4fd865fd39425c69b7cd432"
]
commit 과 Dockerfile 을 이용해서 hello.py 파일을 이용해 "hello-world" 출력 이미지 제작 및 컨테이너 실행
commit
[root@docker ~]# cat > test.py
print("hello-world")
[root@docker ~]# docker run -itd --name os1 centos:7
[root@docker ~]# docker exec os1 yum -y install python
[root@docker ~]# docker exec os1 mkdir /app
[root@docker ~]# docker cp test.py os1:/app
//둘 다 같은 결과임.
// 1
[root@docker ~]# docker commit --change 'CMD ["/app/test.py"]' --change 'ENTRYPOINT ["/usr/bin/python"]' --change 'VOLUME /app' --change 'WORKDIR /app' osp1 python_test1:v1
[root@docker ~]# docker run --name pythontest1_1 python_test1:v1
hello-world
//2
[root@docker ~]# docker commit --change "VOLUME /app" --change "WORKDIR /app" --change 'CMD ["python","test.py"]' osp1 python_test1:v2
[root@docker ~]# docker run --name pythontest1_2 python_test1:v2
hello-world
Dockerfile
[root@docker ~]# mkdir pytest && cd pytest
[root@docker pytest]# cat > test.py
print("hello-world")
//둘 다 같은 결과임.
//1
[root@docker pytest]# cat > Dockerfile
FROM centos:7
RUN yum -y install python
RUN mkdir /app
COPY test.py /app/test.py
CMD ["/app/test.py"]
ENTRYPOINT ["/usr/bin/python"]
VOLUME /app
WORKDIR /app
//2
[root@docker pytest]# cat > Dockerfile
FROM centos:7
RUN yum -y install python
CMD ["mkdir","app"]
COPY test.py /app/test.py
WORKDIR /app
VOLUME /app
CMD ["python","/app/test.py"]
[root@docker pytest]# docker build -t pthon_test2:v1 .
[root@docker pytest]# docker run --name pythontest2
hello-world
Dockerfile 로 go 언어로 만든 hello world 이미지 제작 및 컨테이너 실행
[root@docker ~]# yum -y install epel-release.noarch
[root@docker ~]# yum -y install golang-bin
[root@docker ~]# cat > /root/hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello This is golang")
}
[root@docker ~]# go build hello.go
[root@docker ~]# cat > Dockerfile
FROM scratch
COPY hello .
CMD ["/hello"]
[root@docker ~]# docker build -t golang_test:v1 .
[root@docker ~]# docker images golang_test:v1
REPOSITORY TAG IMAGE ID CREATED SIZE
golang_test v1 0000e96bc235 10 minutes ago 2.03MB
[root@docker ~]# docker run --name golangtest2 golang_test:v1
'도커 > 개념 및 실습' 카테고리의 다른 글
도커를 이용한 워드프레스 웹 서비스 구축 (1) | 2021.06.20 |
---|---|
07장, 프라이빗 이미지 저장소 (0) | 2021.06.04 |
06장-1, 이미지 제작 및 업로드 (0) | 2021.06.03 |
05장-2, 컨테이너의 통신 (0) | 2021.06.02 |
05장-1, 도커 네트워크 유형 (0) | 2021.06.02 |