본문 바로가기
IT.인터넷/Docker

Docker컨테이너에서 host(Linux) 명령어 사용하는 방법(pipe)

by Mr-후 2023. 8. 4.
반응형

몇 일 동안 별별짓을 다했다. 왜? 모르니까. 

접근은 간단하게 될 줄 알고 시작을 했는데, 막상 간단하지는 않았다. 

Docker로 서버를 구성했다는 점을 간과한 것이 가장 뼈아픈 실수다. 

libreoffice라는 라이브러리를 이용하여 ms-office파일이 업로드 되면, 이걸 pdf로 변환하는 작업이 주요 골자다. 

같이 일하는 동료의 의견으로 받아 linux shell script로 변환하는 라이브러리를 호출하면서 인자로 변환할 파일을 전달 하는 것으로 시작, 

Java sprint boot에서 linex shell script를 실행할 수 있는 ProcessBuilder를 이용하기로 하고 

CHAT GPT에게 클래스 작성을 요청했다. 

깔끔한 자슥~~~ 

완변한 클래스가 하나 왔다. 헐 ~ 

각설하고, ProcessBuilder를 통해 script를 실행하였으나, 계속 명령어를 찾을 수 없다는 오류가 나왔다.

이걸 이틀에 걸쳐 별짓? 다해보면서 이유를 찾고자 했다. 사람은 역시, 하나만 파고 있으면 다른 생각이 안드나보다. 

어제 저녁, 약속 장소로 이동하는 전철에서, 그리고 linux 에 설치된 nodejs에서는 잘 되는걸 보고 아차!! 싶었다. 

Docker, docker,,,,  우리는 도커 컨테이너 안에서 명령어 실행되겠구나.. 싶어

출근해서 챗GPT에게 물어보니, Docker Host Binding이란 것이 있다고 한다.

그러면 컨테이너에서 host의 명령어를 실행할 수 있다는 ... 대박!! 

그리하여 시작된 일이 또 몇 시간이 흘렀다. 

결국 오후 2시가 넘어서 실마리가 풀렸고 역시 별짓을 다하고 테스트를 거쳐 정상적으로 변환이 되는 것을 확인했다. 

따라서, 오늘 내용은 

1. 리눅스에서 파이프 생성하는 내용

사실, 이 분의 블로그에 다 정리되어 있다. 
https://young-cow.tistory.com/79

 

[Docker] 도커 컨테이너에서 호스트에 있는 명령어를 실행하는 방법

도커 컨테이너에서 호스트에 있는 명령어를 실행하는 방법 출처의 내용을 한글로 번역하였습니다. 출처 : https://stackoverflow.com/questions/32163955/how-to-run-shell-script-on-host-from-docker-container 도커 컨테이

young-cow.tistory.com

이 분 역시 스택오버플로우에 있는 내용을 참고하였다고 한다. 

리눅스 파이프란, 프로세스간 통신을 할 때 사용하는 방법이라 하고, 난생 처음 사용해보게 되었다. 

블로그의 내용을 간단하게 코드로 정리해둔다. (나중에 꼭 쓰이기 마련이다.) 

//호스트(host) 에서 파이프 생성
mkfifo /경로/pdf_convert_pipe

ls -l //명령어를 통해 확인, Type이 p로 시작하는 파일이 만들어진다. 

//터미널을 두개 열고, 

#터미널 1에서 
tail -f /경로/pdf_convert_pipe

#터미널 2에서 
echo "hello world!" > /경로/pdf_convert_pipe

hello world!가 출력되는지 확인하면 된다.

 

그런데, 명령을 보내면 받아서 읽어서 처리를 해줘야 하는데 이 블로그에서 다음과 같이 설명하고 있다. 

#터미널 1
eval "$(cat /경로/경로/pdf_convert_pipe)"

#그리고 터미널 2에서 다음과 같이 호출 
echo "ls -l" > /경로/경로/pdf_convert_pipe 

#그러면 터미널1에 ls -l을 실행한 결과가 나오면 성공한 것이다.

 

호스트에서 파이프를 계속 읽는 방법에 대해서는 다음과 같이 되어 있는데 꼭 그런것 같지 않았다. (우분투 18.04버전) 

# 터미널 1
while true; do eval "$(cat /경로/경로/pdf_convert_pipe)"; done

빠져나오는 방법은 ctrl + c 

블로그에서 설명한, reboot시에도 스크립트가 실행되도록 하기라는 부분은 서버를 리부팅할 수 없는 상태라 해보지 않았지만, 

shell scrpt를 하나 더 만들고 그걸 실행하는 크론탭으로 등록하면 된다고 한다. 

#pipe_run.sh 내용 

#!/bin/bash
while true; do eval "$(cat /경로/경로/pdf_convert_pipe)"; done

그리고 크론탭에 등록할 때는 

crontab -e 로 열고 

insert모드로 변경하고 

아래 내용을 추가 

@reboot /경로/경로/pipe_run.sh

 

다음으로, 

 

3. docker 컨테이너 생성시 파이프를 볼륨으로 연결하는 것까지 정리

나의 경우, docker컨테이너 생성을 docker-compose.yml파일로 처리를 하고 있는데 기존에 올라간 컨테이너를 stop, rm을 통해 삭제하고 docker-compose.yml을 수정하였다. 그리고 docker-compose up -d 명령을 통해 컨테이너를 다시 생성하였다. 

version: "3"
services:
  my_api:
    container_name: my_api
    image: openjdk:8u212-jdk
    restart: always
    command: "java -jar -Dspring.profiles.active=api-dev /usr/src/api-0.0.1-SNAPSHOT.jar"
    network_mode: "host"
    ports:
      - 9004:9004
    volumes:
      - /home/user1/data/my_api:/usr/src
      - /home/user1/data/files:/res
      - /home/user1/data/my_api/logs:/logs
      - /home/user1/pdf_convert_pipe:/convert_pipe
    environment:
      - TZ=Asia/Seoul

 

이런 다음 my_api컨테이너에 접속한다. 

docker exec -it my_api bash 

그런 다음 ls -l을 해보면 마운트된  convert_pipe를 볼 수 있을 것이고 

다음과 같은 명령어를 실행해보면 파일이 생성되는지 알 수 있다. 

echo "touch makeTextFile.txt" > /convert_pipe 

*** 같은 기종의 운영체제에서 테스트해보시기 바란다. (linux host, linux docker container) 

오늘은 여기까지!! 

 

반응형