사내에 구형 배포 시스템인 Webistrano를 해당 서버가 위치한 상면과 유지보수 등의 이슈로 인해 EOL되면서 철거 일자를 잡아놓았는데, 한 서비스팀에서 아직 신규 배포 시스템 준비가 안되어서 급하게 철거 대상과 별도로 Webistrano 띄워 달라는 요청이 왔다.

Webistrano 바라보던 데이터베이스는 철거 대상이 아니어서 신규 Webistrano 해당 데이터베이스를 접근하고 구성만 해주면 해당 팀에서 유지보수를 하며 사용하겠다는 입장이었다.

Webistrano 설치는 의존성을 많이 타서 번거롭기 때문에 말려있던 Docker 이미지를 찾던 중 사용하기 적합한 이미지(https://hub.docker.com/r/bestna39/webistrano)를 발견하였다.

해당 이미지의 Webistrano 설정을 상당부분 수정하고, 사내에서 사용하기 위한 커버로스를 비롯한 각종 패키지를 이미지에 덧붙여서 새로운 이미지를 만들어야 했다. 이 과정에서 기존에 옵션이나 사용을 정리하지 않고 매번 구글링을 통해서 사용했던 Docker 명령어와 애매하게 알고 있던 것을 정리하고자 이 글을 쓰게 되었다.

Docker 컨테이너와 이미지 삭제하기

docker kill $(docker ps -q) # 모든 컨테이너 멈춤
docker rm $(docker ps -a -q) # 모든 컨테이너 삭제
docker rmi $(docker images -q) # 모든 이미지 삭제

docker container prune # stop 상태의 컨테이너 모두 삭제
docker system prune # 사용하지 않는 리소스 모두 삭제

ENTRYPOINT와 CMD의 차이

ENTRYPOINT 경우 지정된 명령어만 수행 가능하지만 CMD의 경우 명령어를 덮어씌워 사용할 수 있다.
ENTRYPOINT 사용 시 --entrypoint를 이용해서 덮어씌우는 것은 가능하다.

애플리케이션 실행과 같이 실행할 명령의 목적이 분명하다면 ENTRYPOINT를 이용하여 Dockerfile을 정의하는 것이 확실해 보인다.

두 가지를 모두 사용해서 유지해야 하는 것은 ENTRYPOINT 변형이 필요한 것은 CMD를 적절하게 이용 해야겠다.

ENTRYPOINT [“echo”, “Hello”]
CMD [“World”]


참고
– ENTRYPOINT & CMD 사용법: https://bluese05.tistory.com/77
– ENTRYPOINT & CMD 차이: https://phoenixnap.com/kb/docker-cmd-vs-entrypoint

CMD 리스트 포맷과 셸 포맷 차이

CMD ["tail", "-f", "/dev/null"]
CMD tail -f /dev/null


위의 두 차이는 sh -c를 통해서 실행이 되느냐 차이다.

Docker 공식 문서에서는 리스트 포맷을 권장하고 있다.

기존 이미지의 ENTRYPOINT를 덮어씌우는 방법

기존 이미지에 ENTRYPOINT가 있다면 반드시 ENTRYPOINT를 지정해서 덮어씌워줘야 한다.
저렇게 하면 환경 변수를 앞에 두고 tail을 실행하는 건데, 이것은 /usr/bin/tail이 아닌 환경 변수에서 tail의 위치를 찾아 실행해주는 방식이다.

ENTRYPOINT ["/usr/bin/env"]
CMD ["tail", "-f", "/dev/null"]


참고
– ENTRYPOINT 덮어씌우는 방법: https://stackoverflow.com/questions/41207522/docker-override-or-remove-entrypoint-from-a-base-image
– 환경변수 사용 이유: https://blog.gaerae.com/2015/10/what-is-the-preferred-bash-shebang.html

ADD와 COPY 차이

ADD가 COPY보다 먼저 개발 되었으며, ADD는 파일 복사 뿐만 아니라 특정 주소에서 파일을 받아오는 기능까지 가지고 있다.

명확하게 사용하기 위해서 파일 복사를 위한 COPY가 나타났고, 파일 다운로드도 RUN curl 등으로 가능하기 때문에 현재 ADD는 하위 호환을 위해 사용된다고 알아두면 좋을 것 같다.

참고
– ADD & COPY 차이: https://m.blog.naver.com/PostView.nhn?blogId=kbh3983&logNo=221130490612&proxyReferer=https:%2F%2Fwww.google.com%2F

ENTRYPOINT가 Bash인 컨테이너 실행

docker run -itd --name=ubuntu ubuntu
단순히 -it 옵션만 사용할 경우에는 해당 컨테이너를 빠져나가게 되는 순간 컨테이너가 stop 상태가 된다. 따라서 -d 옵션을 이용한다. 이후에 bash로 떠있기 때문에 exec말고 attch를 통해서 해당 컨테이너에 붙을 수도 있다.

execattach의 차이는 exec의 경우 별도의 process를 띄운다는 것이다.

Docker build 후 push

로컬에서는 이미지에 단순히 알아먹을 수 있는 태그를 붙여서 생성한다. docker build -t test .
원격에 푸쉬하기 위해서는 해당 이미지에 추가 태그를 달아야 한다. docker tag test <repository>/<user>/test
새로 만든 태그를 푸쉬한다. docker push <repository>/<user>/test