[PyCharm] Mac에서 PyCharm Docker를 원격 연결하기 Develop Tip

그동안 PyCharm을 돌리면서 실제 도는 작업은 패러렐즈에 있는 우분투 16.04를 별도로 돌려 원격 인터프리터로 연결하여
사용하고 있었습니다. (PyCharm을 이용한 원격 디버거 이용 참조)

그런데 이제는 해당 Python 코드의 결과가 Docker로 deploy 되는데 python:2.7-alpine 이미지를 가져와서 
만든 컨테이너 이미지를 실행시킵니다.

그래서 패러렐즈에 다시 alpine 리눅스를 설치해서 돌려볼까... 하다가 문득,
아... 왜 VM으로 개발을 하고 갔다가 다시 그 결과를 Docker Container 로 다시오지?
처음부터 개발을 docker 에서 하면 될 것을... 이라는 생각이 들어 정신을 차리게 되었습니다.

그러데 Mac 에서 돌리는 지라... 역시 Mac용 Docker가 잘 돌고 있습니다.


그리고,


다커 서버 버전도 따끈 따끈한 1.13 입니다.

이제 터미널을 하나 열어,

정상적으로 Docker 데몬이 돌고 있고 2375 포트로 SDK API 가 노출되어 있다면,

$ docker -H tcp://127.0.0.1:2375 images

라고 하였을 때, 

REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
pycharm_helpers         PY-163.9735.8       4a45065e2725        47 minutes ago      22.9 MB
backend_audit_test      1.0                 3019a59994e2        40 hours ago        180 MB

와 같은 결과가 잘 나와야 하는데,

실제 Mac 에서는

$ docker -H tcp://127.0.0.1:2375 images
Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?

와 같이 오류가 발생합니다.

구글링을 한 결과 로컬 소켓으로 열고 돌기 때문에 TCP Unix domain 소켓으로 노출이 안되어서 발생하는 문제였습니다.

이를 해결하기 위하여,

$ brew install socat
이라고 하여

위와 같이 설치를 마치고,

$ socat TCP-LISTEN:2375,reuseaddr,fork,bind=localhost UNIX-CONNECT:/var/run/docker.sock

라는 명령을 내리고 다시 

$ docker -H tcp://127.0.0.1:2375 images

해 보면 결과가 잘 나옵니다.

참고로,

$ nc -z localhost 2375
Connection to localhost port 2375 [tcp/*] succeeded!
와 같이 테스트 해도 됩니다.

아하, socat 명령은 특정 네트워크,IPC 등의 스트림을 다른 스트림으로 연결을 해 주는 유틸리티구나... 를 알 수 있습니다.

이제 위의 명령이 Mac을 재기동해서 계속 돌게 하기 위해서,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>docker.sock</string>

    <!-- This file should be ~/Library/LaunchAgents/docker.sock.plist -->
    <!-- Start with: launchctl load ~/Library/LaunchAgents/docker.sock.plist -->
    <!-- Configure jetbrains with tcp://localhost:2375 -->

    <key>OnDemand</key>
    <false/>

    <key>moonchangchae</key>
    <!-- Change the string below to your username -->
    <string>aReasonableUserName</string>

    <key>GroupName</key>
    <!-- Change the string below to any arbitrary group name such as "Docker" -->
    <string>staff</string>

    <key>ProgramArguments</key>
    <array>
            <string>/usr/local/bin/socat</string>
            <!-- Change the port - 2375 - if necessary. Otherwise just keep it as is -->
            <string>TCP-LISTEN:2375,reuseaddr,fork,bind=localhost</string>
            <string>UNIX-CONNECT:/var/run/docker.sock</string>
    </array>
    <key>RunAtLoad</key>
            <true/></dict>
</plist>

라는 내용을 

$ sudo vi /Library/LaunchAgents/docker.sock.plist

라고 하여 넣어주고 (사용자 및 그룹 계정을 자신의 것으로 수정 요)

$ sudo chown root:wheel /Library/LaunchAgents/docker.sock.plist

라고 한 다음, load를 시키면
이후 시스템이 다시 기동해도 계속 socat은 동작을 합니다.

reboot을 해 보았는데,

$ ps -ef | grep socat
  501   464     1   0  2:58PM ??         0:00.01 /usr/local/bin/socat TCP-LISTEN:2375,reuseaddr,fork,bind=localhost UNIX-CONNECT:/var/run/docker.sock

와 같이 잘 동작합니다.

미리 준비할 것이 하나 있는데,
맥의 Docker Preferences를 띄워,

PyCharm 프로젝트가 위치한 폴더 혹은 그 상단의 폴더를 공유하겠다고 위와 같이 설정하고
restart 합니다.


이제는 PyChame을 띄웁니다.

Community 버전에도 지원되면 좋겠으나 현재로서는 2016.3 (이전 버전에도 동작했던 것 같습니다) Professional 버전에서 동작합니다.

위와 같이 설정을 열고 Project Interpreter를 설정하고 

Add Remot를 선택하여

상단에 Docker를 선택하고 New... 를 누른다음,

API URL에는 : http://localhost:2375
Certificates folder에는 ​: /Users/moonchangchae/.docker/machine/certs 를 지정합니다.
(해당 폴더 내에 cert.pem, key.pem, ca-key.pem, ca.pem 등의 인증서가 있는지 확인합니다)

이제 위와 같이 잘 나오고 Image name: 에는 python:2.7-alpine 이미지를 선택합니다.

혹시 이것이 없다면, 미리 이전에 터미널에서,

$ docker pull python:2.7-alpine 
라고 당겨 놓습니다.

(알파인 버전을 사용하는 이유: 데비안이나 우분투 등은 그 자체로 많은 이미지를 이미 포함하고 있어
 100M 이상인 반면 alpine 리눅스만 가져오면 3.5M - 와우! 놀랍습니다. 리눅스가 3.5M로 컨테이너로 돌다니요.
 이 알파인 리눅스 위에 python 2.7을 얹어 놓은 거인데 80M가 안됩니다. 나중에 사용하지 않은 파이썬 다이어트도 필요합니다)


이제 메뉴에서 View > Tool Windows > Docker 를 선택해 보면,

와 같이 보입니다.자동으로 /pycharm_helpers_... 를 설치하고 가져왔네요.
SSH 연결인 경우에는 원격 디버깅을 하기 위하여 원격 사용자 홈디렉터리에 ./pytcharm_helper 를 만들어
파일을 보내고 원격 디버깅을 했는데 그런 일련의 작업 조차도 컨테이너로 만들어 놓은 듯...

이제 프로젝트 디폴트 인터프리터가 설정되어 있으므로 간단한 소스를 만들어
디버깅을 해 보면,


프로그래머의 대당의 Hello World 되시겠습니다.

어라... /stoic_heyrovsky 라는 임의의 컨테이너가 생겼고, 볼륨을 보니
자동으로 /opt/project 가 본 시스템의 프로젝트 Root folder 로 연결되어 있고,

이 때 터미널에서 

해당 컨테이너가 동작하고 있는 지 확인하여,

해당 컨테이너로 들어갔더니 오~~
자동으로 실행된 하위폴더의 위치로 들어가있고,
/opt/project 가 PYTHONPATH로 지정되어 있어 
소스 사항의 동작을 하는데 문제가 없군요.

대신 만약 Third-Party 모듈을 가져와서 동작을 한다면,
해당 모듈을 설치한 이미지로부터 출발하면 될 것 같습니다.


docker 대신 docker-compose 구성도 가능한 것으로 보아,
더 많은 작업을 가상머신 여러 개 띄워 하지 않다도
가능하게 되어 있습니다.

이제 돈 주고 Professional 버전을 사야할 확실한 이유가 하나 더 생겼습니다.


어느 분께는 도움이 되셨기를...


덧글

  • 민대디 2017/02/08 23:51 # 삭제 답글

    올려주신 내용 잘 읽었습니다.
    저도 한번 테스트 해보려고, 따라 하는데 "...$socat TCP-LISTEN:2375,reuseaddr,fork,bind=localhost UNIX-CONNECT:/var/run/docker.sock" 이 명령어를 실행시켜도 아무런 진행을 하지 않고 있는데요.

    ctrl+C로 강제로 종료를 시켰습니다. 혹시, 더 오래 기다려야될까요?
  • 지훈현서아빠 2017/02/09 01:28 #

    아하~ 그 명령은 & 를 붙이지 않으면 그냥 실행되고 있는 상태입니다. 하나의 터미널에서 실행시키고, 다른 터미널에서 확인을 해 보셔요.
    그리고 매번 위의 명령을 안 줘도 그 아래 plist 를 넣으면 자동으로 리눅스에 데몬 돌듯이 돌게 됩니다.
    도움이 되셨기를 바랍니다.
댓글 입력 영역

구글애드텍스트