티스토리 뷰
이번 글은 기본이 부족해 삽질한 경험이 바탕이 되는 글입니다. 🥲
docker-compose에서 multiple commands를 사용하는 법에 대해 알아보겠습니다 😸
docker-compose 에서 multiple commands 가 왜 필요해 ?
아래와 같은 docker-compose 파일을 작성해 개발 중이었습니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
위 docker-compose 파일에 대해 설명드리자면, docker registry에 등록된 이미지가 아닌 현재 directory의 Dockerfile을 빌드하고 특정 volume을 마운트해 구동됩니다. 해당 Dockerfile은 corretto jdk 이미지를 기본 이미지로 구성하고 있습니다.
그리고 저는 해당 docker-compose를 통한 docker 구동이 완료가 되면 특정 script를 시작해야만 했습니다. 즉 , start up script가 존재해 container가 구동될 때, 시작해야만 했습니다. 이 start up script는 volume으로 mount 한 디렉토리 중에 존재하는 상황이었습니다. 그리고 start up script를 시작한 후에 container가 종료되지 않고, bash script로 바로 동작하게 끔 구현하고 싶었습니다.
수행해야 할 프로세스가 따로 존재하지 않는 container image인 경우, container 구동을 완료하면 바로 종료되게 됩니다. 이를 멈추기 위해서 보통 '/bin/bash'를 구동시켜 bash를 동작하게 만듭니다. 그러면 bash가 종료되기 이전까지 container가 종료되지 않습니다. 즉, docker가 종료되지 않게 하려면 '/bin/bash'를 시작시켜야만 하고 결국엔 현재 상황에선 2개의 command (명령)을 수행해야하는 것입니다.
- 1. start up script 수행
- 2. /bin/bash 수행
보통 Container가 구동하고 바로 command를 실행하기 위해 아래와 같이 사용하고 있습니다.
- Dockerfile에서는 'CMD', 'ENTRYPOINT'를 활용합니다.
- docker-compose에서는 'command:', 'entrypoint:'에 명시해주면 됩니다.
근데 일반적으로 하나의 command 구문만 사용할 수 있습니다.
예를 들어 아래처럼 작성하면 오류가 납니다. 이 부분의 더 자세한 내용은 여기 공식문서를 참조해주세요.
당연히도 docker-compose인 경우에도 정상적으로 동작하지 않습니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command: sh some_script1.sh
command: sh some_script2.sh
그렇기에 저와 같이 2개 이상의 command를 실행해야 하는 경우, 위와 같은 방법으로는 구동시킬 수 없습니다.
그러면 어떻게 해야하는 걸까요~?
docker-compose multiple commands !
일단, 저는 docker-compose를 활용해 개발 중이었으므로 이 글에서는 docker-compose에서 multiple commands를 사용하는 법만 다루겠습니다. 하지만 docker-compose에서 하는 방법과 Dockerfile에서 하는 방법은 비슷하니 참고하시면 도움 될 것 같네요.
방법은 간단하면서 다양한 방법을 통해 구현할 수 있습니다. 하지만 핵심은 '&&'를 통해 명령어를 묶으면 됩니다.
너무 간단하지 않나요?😂 사실 CLI에서 command를 여러개 묶어 한 줄에서 수행할 때 '&&'를 사용하곤 하는데, 저는 docker file이라는 것에 시선과 생각이 묶여 이런 생각을 안하고 .... 계속 다른 방법이 있겠지 찾아 다녔습니다.
아무튼 아래와 같은 것이 '&&'를 통해 command를 한 번에 실행한 예라고 보면 될 것 같습니다.
이러한 방법을 사용해서 docker-compose에서 multiple commands를 사용하면 다음과 같이 작성하면 됩니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command: sh -c "/some_script1.sh && /some_script2.sh"
단순하죠 ?
단순하게 생각하면 아래처럼 작성하면 될 것 같은데..... 라는 생각이 안드시나요? ㅎㅎㅎㅎ 아래처럼은 작성하시면 안됩니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command: sh -c /some_script1.sh && /some_script2.sh
- 'sh -c'를 통해 실행되면서 뒤에 있는 것들은 모두 args(arguments) 취급 받게 됩니다. sh는 첫 번째 파일만 실행시키기 때문에 뒤에는 실행되지 않아 원하는 대로 동작하지 않습니다.
더 다양한 방법 !
앞서 말씀드린 것처럼 더 다양한 방법으로 작성할 수 있습니다.
아래 예들은 위 방법에서 줄 바꿈을 통해 다 간결하게 command를 볼 수 있도록 수정한 예 입니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command: >
sh -c "
/some_script1.sh &&
/some_script2.sh
"
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command: sh -c "
/some_script1.sh &&
/some_script2.sh"
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
command:
- sh
- -c
- |
/some_script1.sh
/some_script2.sh
아래 예제는 entrypoint를 사용한 예입니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
entrypoint: ["sh", "-c"]
command:
- |
/some_script1.sh
/some_script2.sh
참고로 entrypoint(ENTRYPOINT)와 command(CMD)의 차이를 잘 모르시는 분들은 아래 블로그 글을 참조하시면 도움 될 것 같습니다 :)
저는 맨 아래의 방법인 entrypoint와 command를 나눠 작성하는 것을 선호하는 편입니다.
그래서 맨 앞에서 언급한 제 문제를 해결하도록 docker-compose를 작성해보면 다음과 같습니다.
version: "3"
services:
some_service:
container_name: some_service
build: .
volumes:
- ~/some-data:/some-data
- ~/some-info:/some-info
- ~/some-script:/some-script
entrypoint: ["/bin/bash","-c"]
command:
- |
/some_start_up_script.sh
/bin/bash
사람마다 차이가 있으니 여러 방법 중 제일 맘에 드는 방법을 사용해서 여러 문제들을 해결하셨으면 좋겠네요.
'Development > ETC' 카테고리의 다른 글
IntelliJ의 Hint - inlay hint 사용하기 (0) | 2022.08.06 |
---|---|
[Javadoc] error: bad use of '>' 오류에 관하여 - @code 사용법 (0) | 2021.07.29 |
[NS3] CSMA example (0) | 2021.01.23 |
[TCP] BIC-TCP (0) | 2021.01.23 |
Github 원하지 않는 개발언어로 등록된 경우 (0) | 2021.01.22 |
- Total
- Today
- Yesterday
- Algorithm
- 하루
- 쿠버네티스
- k8s
- container
- 클린 아키텍처
- MySQL
- 비동기
- 백준
- Clean Architecture
- hexagonal architecture
- c++
- Istio
- docker
- java
- Intellij
- 로그
- 알고리즘
- Spring
- tag
- Kubernetes
- Spring boot
- Log
- 일상
- boj
- jasync
- HTTP
- gradle
- python
- WebFlux
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |