docker에서 nodejs + python-shell 사용할때 배운 docker 기본기와 개발 기본기

다음과 같이 dockerfile이 작성되었고

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

RUN pip install --upgrade pip
RUN pip install matplotlib
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:16.18

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

 

 

이렇게 구성된 dockerfile에서 다음과 같은 python-shell을 수행할려고 한다

 

app.post("/api/personal", upload, (req, res) => {
  console.log(req.file);

  var options = {
    mode: "text",
    pythonPath: "",
    pythonOptions: ["-u"],
    scriptPath: "",
    args: [`./images/${req.file.filename}`],
  };

  PythonShell.run("./personalcolor.py", options, function (err, results) {
    if (err) {
      throw err;
    }
    console.log(results);

    res.send(results[0]);
  });
});

 

무작정 실행해보니.. numpy가 없다고 한다

 

 

 

그래서 numpy를 설치하는 코드를 추가하고 다시 빌드해본다

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

RUN pip install --upgrade pip
RUN pip install numpy
RUN pip install matplotlib
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:16.18

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

 

그런데 분명히 설치했는데도... numpy가 없다고 나옴

 

 

어찌저찌 몇시간을 찾아보니까...

 

node.js - error importing installed python packages in nodejs pyshell - Stack Overflow

 

error importing installed python packages in nodejs pyshell

I have installed a package using pip on my Ubuntu 18.04 server. When I go into the terminal and type the following, everything works fine : $ python >>> import <package-name> I am...

stackoverflow.com

 

설치된 패키지가 어디 경로에 설치되어있는지에 따라 문제가 될 수 있다는 걸 알게 되었다

 

/home/ubuntu/.local/lib/python2.7/site-packages/ -> pip install
/home/ubuntu/.local/lib/python3.6/site-packages/ -> pip install
/usr/lib/python2.7/dist-packages/ -> apt-get install

 

python-shell은 /usr/lib에서 설치된 패키지를 찾아오나봐

 

아무튼 패키지가 설치되어있는 경로에 문제가 있다는 것을 알게되었는데...

 

그래서 pip install로도 설치해보고 apt-get install로도 설치해보고... 여러 시행착오 겪다가

 

python이 패키지를 찾아오는 경로가 따로 있다는 것을 알게되었다

 

sys.path, PYTHONPATH: 파이썬 파일 탐색 경로 | 방성범 블로그 (bangseongbeom.com)

 

sys.path, PYTHONPATH: 파이썬 파일 탐색 경로

import 문을 통해 다른 파이썬 파일을 불러올 때, 파이썬은 내부적으로 파일을 찾기 위해 sys.path와 PYTHONPATH에 있는 경로를 탐색합니다. 이 두 변수를 적절히 수정해 임의의 디렉터리에 있는 파이썬

www.bangseongbeom.com

 

numpy double installation (pip vs apt-get) - Stack Overflow

 

numpy double installation (pip vs apt-get)

I am using python 2.7 on Ubuntu 14.04 LTS. I have tensorflow, scipy, numpy installed, but when I try installing sklearn or opencv using apt-get, another numpy is installed whose version is 1.8 and...

stackoverflow.com

 

python이 없어서 그런가 python도 설치해보고... 근데 도커이미지인데 호스트에 python 설치하는게 무슨 의미겠냐고..

 

아무튼 여러 방법 다 해보긴 했는데 잘 안되었지만 핵심은

 

import 패키지를 할때 파이썬이 설치된 패키지를 탐색하는 경로가 있다는 점

 

PYTHONPATH로 환경변수 설정을 통해 설치된 패키지 위치를 알려주면 파이썬이 해당 위치를 탐색해서 불러온다는 점

 

dockerfile에 PATH 설정이 안되어서 설치된 패키지가 어딘지 모르는건 아닐까

 

PYTHONPATH같은 걸로 dockerfile에 입력했던 예시들 많이 봤었는데 이런 이유였을까

 

그래서 PATH를 설정해줄려고 했더니.. 도대체 내가 설치한 패키지가 어디있는건데..?

 

/usr/lib,.... /usr/local/lib,.... 뭐라뭐라 나오던데.. docker image에도 여기에 있는건가..?

 

그러다보니 docker image안에 파일들이 어떻게 존재하고 있는지가 궁금했다

 

https://www.leafcats.com/163

 

docker cp - 호스트 컨테이너 사이 파일 복사

docker image를 실행시킨 컨테이너는 HOST와 다른 PC인 것이나 마찬가지이다.docker는 HOST와 PC간의 파일 이동을 위해 복사 명령어인 cp를 지원한다. docker cp 명령어는 호스트에서 컨테이너로, 컨테이너

www.leafcats.com

 

 

docker cp 명령어를 이용하면 가능하다

 

내부 파일을 가져오길 원하는 이미지를 먼저 컨테이너로 실행시킨다

 

$ docker run -d -p 3001:3001 --name server -u root back_server

 

back_server라는 이름을 가진 이미지를 server라는 이름으로 컨테이너 실행시켰다

 

파일을 무작정 가지고오면.. 지저분해질것 같아서 폴더를 일단 만들고

 

$ mkdir temp

 

temp로 이동해서 해당 temp에.. server container 파일을 모두 가져온다

 

$ docker cp server:. .

 

server라는 이름을 가진 container내에 모든 파일(.)을 현재 경로(.)에 옮기겠다는 뜻이다

 

그러면 이렇게 copy하고 있다고 나오고..

 

 

 

전부 copy해오면 대충 이렇게 나오더라고

 

 

 

그러면 이제 보니까 usr, lib, bin같은 어디서 자주보던 이름이 보이더라

 

이런 경로를 탐색해봐서 실제로 파이썬 패키지가 어디에 설치되어있을까.. 이런걸 확인해보자

 

stackoverflow나 여러 인터넷 찾다보면 usr/local/lib/python/site-packages 대충 이렇게 생긴곳에 있던것 같더라

 

실제로 ~/usr/local/lib/python3.8/site-packages 들어가보면...

 

 

 

설치했던 torch나.. tensorflow나.. 이런게 있더라고..?

 

그래서 dockerfile에 PYTHONPATH를 설정해서 패키지가 여기에 설치되어있다고 알려주었다

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

RUN pip install --upgrade pip
RUN pip install numpy
RUN pip install matplotlib
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:16.18

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

ENV PYTHONPATH "${PYTHONPATH}:/SubPjt2/backend/usr/local/lib/python3.8/site-packages/"

EXPOSE 3001

CMD ["npm", "start"]

 

 

내 dockerfile에서 핵심은 아래 부분이라서.. 거기에 환경변수 설정을 해주었지

 

 

오 이번엔 뭔가 좀 다르게 나왔음..

 

numpy를 설치했는데 numpy.core_multiarray_umath가 없다고 나옴

 

이 부분은 찾아보니까 pip install --upgrade numpy 이런식으로 numpy를 업그레이드 해야한다던데

 

아무 의미 없었음

 

그렇게 헤매다가 오류를 좀 자세히 보니까

 

 

나는 python3.8을 설치했는데 python3.7이라고 나오더라고..

 

버전이 안맞는거 아닐까? 이런 생각을 하게됨

 

그래서 도커 이미지 뜯어놓은 파일 경로 찾아가 usr/bin/python3 부분 보니까

 

 

 

내가 다운받은 적이 없던 python3.7이 있더라고..

 

이유가 뭔지는 넘기더라도.. 버전이 안맞는것 같아서

 

python-shell의 옵션을 자세히 살펴보니

 

 

pythonPath부분에서 python이 설치된 위치를 지정해줘야하나봐

 

내가 설치한 python은 python3.8이니까..

 

그리고 usr bin 이런곳에 대충 있겠지

 

 

usr/local/bin 쪽에 설치했던 python3.8이 있는것 같더라고

 

그래서 그 부분 경로를 지정해주고..

 

app.post("/api/personal", upload, (req, res) => {
  console.log(req.file);

  var options = {
    mode: "text",
    pythonPath: "/SubPjt2/backend/usr/local/bin/python3",
    pythonOptions: ["-u"],
    scriptPath: "",
    args: [`./images/${req.file.filename}`],
  };

  PythonShell.run("./personalcolor.py", options, function (err, results) {
    if (err) {
      throw err;
    }
    console.log(results);

    res.send(results[0]);
  });
});

 

-------------------------------------------------------------------------------------------------------------------------------------------------

 

원래 여기서 안되어가지고 묘수로 그냥 디폴트인 python3.7을 설치하고 pythonPath를 지정하지 않았었는데...

 

이번에 재현하면서 다시 해보니까 잘 되네..

 

이번에 경로 설정을 잘 해서 그런가..?

 

python3말고 python3.8해도 되고..

 

사실 오류에 보면 usr/bin/python3였잖아.. 그래서 나도 SubPjt2/backend/usr/bin/python3 해봤었는데..

 

 

 

 

근데 저번에 했을때는 python이 있어도 아예 못찾던데 이번에는 python이 있는걸 찾긴하네..

 

저기에 python3.8이 있었다면 되는거였는데.. 보니까 python3.9밖에 없어가지고 안되는것 같기는 한데

 

아무튼 귀신이 곡할 노릇이네

 

-----------------------------------------------------------------------------------------------------------------------------------------------

 

그랬더니 뭔가 다른 에러가 나오긴함..

 

 

GLIBC_2.29가 없다는데.. 이게 뭔 리눅스 라이브러리 그런거라던데

 

현재 환경에서 ldd --version을 치면 GLIBC에 대한 정보를 볼 수 있다고 한다

 

 

그러면 2.31인데.. 2.29로 다운그레이드를 해야하나..?? 인터넷 찾아보면 glibc 다운그레이드하는건 상당한 위험을 동반한다던데

 

그런데 생각해보니까 내 호스트 환경에 GLIBC를 알아봤자 의미없잔항

 

나는 도커 이미지를 실행시키는건데 도커 이미지 내에 GLIBC가 어떤 버전인지를 알아야지

 

애초에 설치가 되어있는건지도 모르겠더라고

 

인터넷 찾다보니 도커 이미지 내에 glibc에 대해 알 수 있는 방법이 있더라

 

도커 이미지를 exec로 접속해서 ldd --version을 치면 이미지 내에 설치된 glibc에 대해 알 수 있다고함

 

먼저 해당 도커 이미지를 실행시키고...

 

 

 

docker ps를 입력해보면 왼쪽에 나온 id가 container id이다..

 

docker exec는 대충 실행된 컨테이너 안에 접속하는 명령이라고 생각하면 된다

 

다음을 실행해보면..

 

$ sudo docker exec -it (my-docker-container-id) bash

$ ldd --version

 

대충 다음과 같이 glibc 버전이 나오더라

 

 

어찌저찌 찾아보니까 nodejs 이미지 안에 glibc가 설치되어있긴 한가보더라고

 

현재 설치한 nodejs가 16.18이라서 nodejs 버전을 올리면 glibc 버전도 올라가나.. 그런 생각을 하게 됨

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

RUN pip install --upgrade pip
RUN pip install numpy
RUN pip install matplotlib
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:18.14

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

ENV PYTHONPATH "${PYTHONPATH}:/SubPjt2/backend/usr/local/lib/python3.8/site-packages/"

EXPOSE 3001

CMD ["npm", "start"]

 

그래서 이렇게 도커 파일을 만들고 빌드해서 실행해보면... 정상적으로 파이썬 파일이 실행된다

 

ldd --version을 확인해보면

 

 

2.31이더라.. 요구하는 버전보다 높으면 상관없나봐

TAGS.

Comments