docker에서 많은 docker-entrypoint.sh 파일을 보면 아래와 같은 구조를 확인할 수 있다.
#!/bin/bash
set -e
... code ...
exec "$@"
FROM ubuntu:20.04
COPY ./docker-entrypoint.sh ./docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["ps", "-ef"]
기본적으로 위와같은 Dockerfile이 있을 때, CMD에 선언된 명령은 ENTRYPOINT에 인수로 전달되어 1개의 명령으로 실행됩니다.
예) # ./docker-entrypoint.sh ps -ef
하지만 exec "$@"을 이용하면 "이 .sh 스크립트에서 모든 작업을 수행한 다음 동일한 셸에서 사용자가 CMD에 전달한 명령을 실행" 할 수 있게된다.
<aside> 📌 set -e 실행 중인 명령이 0이 아닌 종료 코드로 종료되는 경우 즉시 스크립트를 종료하도록 쉘 옵션을 설정한다. 스크립트는 실패한 명령의 종료 코드와 함께 반환된다.
</aside>
아래와 같이 간단한 docker-entrypoint.sh와 Dockerfile을 생성한다.
#vi docker-entrypoint.sh
#!/bin/bash
set -e
ls
exec "$@"
#vi Dockerfile
FROM ubuntu:20.04
COPY ./docker-entrypoint.sh ./docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["ps", "-ef"]
# docker build -t testentry:1.0 .
# docker run -it testentry:1.0
bin docker-entrypoint.sh lib libx32 opt run sys var
boot etc lib32 media proc sbin tmp
dev home lib64 mnt root srv usr
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:57 pts/0 00:00:00 ps -ef
결과는 위와같이 entrypoint의 # ls와 CMD의 # ps -ef 모두 출력되는것을 확인할 수 있다.
exec "$@"이 없는 경우는 아래와 같다
#vi docker-entrypoint.sh
#!/bin/bash
set -e
ls
#vi Dockerfile
FROM ubuntu:20.04
COPY ./docker-entrypoint.sh ./docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["ps", "-ef"]
# docker build -t testentry:1.0 .
# docker run -it testentry:1.0
bin docker-entrypoint.sh lib libx32 opt run sys var
boot etc lib32 media proc sbin tmp
dev home lib64 mnt root srv usr
이전의 결과와는 다르게 CMD의 #ps -ef 명령은 수행되지 않은것을 확인할 수 있다.
이러한 설정으로 유저가 docker 이미지를 deploy하게 되는 상황에서, CMD의 작업을 보장함과 동시에 manual한 작업으로 인한 에러를 방지할 수 있을것이다.