본문 바로가기

docker

set -e 와 exec "$@"

docker에서 많은 docker-entrypoint.sh 파일을 보면 아래와 같은 구조를 확인할 수 있다

#!/bin/bash
set -e

... code ...

exec "$@"

set -m 과 exec "$@"은 무엇인가?

FROM ubuntu:20.04
COPY ./docker-entrypoint.sh ./docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["ps", "-ef"]

기본적으로 위와같은 Dockerfile이 있을 때, CMD에 선언된 명령은 ENTRYPOINT에 인수로 전달되어 1개의 명령으로 실행됩니다.

ex) # ./docker-entrypoint.sh ps -ef
하지만 exec "$@"을 이용하면 "이 .sh 스크립트에서 모든 작업을 수행한 다음 동일한 셸에서 사용자가 CMD에 전달한 명령을 실행"할 수 있게된다.

 

set -e : 실행 중인 명령이 0이 아닌 종료 코드로 종료되는 경우 즉시 스크립트를 종료하도록 쉘 옵션을 설정한다. 스크립트는 실패한 명령의 종료 코드와 함께 반환된다.

 

 

간단하게 확인해보기 !

아래와 같이 simple한 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 image를 deploy하게 되는 상황에서, CMD의 작업을 보장함과 동시에 manual한 작업으로 인한 에러를 방지할 수 있을것이다.

 

 

 

참고 : https://stackoverflow.com/questions/39082768/what-does-set-e-and-exec-do-for-docker-entrypoint-scripts

반응형