Docker 알아보기 - 도커 사용하기 (VSCode 사용하기)
2탄의 시작..?
필자는 Visual Studio Code 를 올리기 위해서 도커를 사용했다. (VSCode)
도커 쓰는방법을 설명하겠다. 도커 파일을 만드는 쪽은 아직 거의 쓸일이 없음.
커스텀으로 부족한 이미지가 있다면 추가/수정하는 일 말곤 없음.
기본적으로 도커는 docker run 이라는 명령어를 사용한다.
Code-server (Visutal Studio Code) 를 예시를 들어서 진행해보자. 줄여서 Cdr로 부르겠다.
Cdr의 경우에는 도커 이미지가 기본적으로 제공이 되어있는데, 보통 도커 이미지를 생성할때 쓰는 틀이
Dockerfile 인데, 확장자 없이 그냥 "Dockerfile"이다. 도커 파일에 대해서는 간단하게 설명하고 다음편에서 자세하게 설명.
Cdr 의 도커 파일은 오프소스이다.
https://github.com/cdr/code-server/blob/master/Dockerfile
FROM node:10.16.0
ARG codeServerVersion=docker
ARG vscodeVersion
ARG githubToken
# Install VS Code's deps. These are the only two it seems we need.
RUN apt-get update && apt-get install -y \
libxkbfile-dev \
libsecret-1-dev
# Ensure latest yarn.
RUN npm install -g yarn@1.13
WORKDIR /src
COPY . .
RUN yarn \
&& MINIFY=true GITHUB_TOKEN="${githubToken}" yarn build "${vscodeVersion}" "${codeServerVersion}" \
&& yarn binary "${vscodeVersion}" "${codeServerVersion}" \
&& mv "/src/binaries/code-server${codeServerVersion}-vsc${vscodeVersion}-linux-x86_64" /src/binaries/code-server \
&& rm -r /src/build \
&& rm -r /src/source
# We deploy with ubuntu so that devs have a familiar environment.
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
openssl \
net-tools \
git \
locales \
sudo \
dumb-init \
vim \
curl \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN locale-gen en_US.UTF-8
# We cannot use update-locale because docker will not use the env variables
# configured in /etc/default/locale so we need to set it manually.
ENV LC_ALL=en_US.UTF-8 \
SHELL=/bin/bash
RUN adduser --gecos '' --disabled-password coder && \
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
USER coder
# We create first instead of just using WORKDIR as when WORKDIR creates, the
# user is root.
RUN mkdir -p /home/coder/project
WORKDIR /home/coder/project
# This ensures we have a volume mounted even if the user forgot to do bind
# mount. So that they do not lose their data if they delete the container.
VOLUME [ "/home/coder/project" ]
COPY --from=0 /src/binaries/code-server /usr/local/bin/code-server
EXPOSE 8080
ENTRYPOINT ["dumb-init", "code-server", "--host", "0.0.0.0"]
구문은 매우 단순하다.
하나하나 보자면 FROM 은 다른 도커 이미지를 불러온다는 말이다.
저기서는 node:10.16.0 , 즉 node 도커 이미지 *버전 10.16 을 가져오는데
이 node 도커 이미지 마져도 node 에서 제공되는거임.
이게 좀 생태계가 얽혀있음. 계속 보자면 ARG는 그냥 argument 같은거다.
RUN 은 도커 이미지에 실행되는 명령, 예를 들어서 말 그래도 커맨드로 실행할 작업
설치면 apt를 쓰고 디렉터리 만들거나 지우거나 이런것들을 하는거다.
위에 도커 파일 소스를 보면 code-server 소스를 복사해서 컴파일 해서 생성하고
COPY --from=0 /src/binaries/code-server /usr/local/bin/code-server 실행결과를 옮기고,
EXPOSE 8080, 8080포트로 bind 하고 ENTRYPOINT ["dumb-init", "code-server", "--host", "0.0.0.0"]
대충 이런 명령줄로 실행한다. 이런 구성이다. 자세하게는 다음 편에서 설명.
중요한건 지금부터임.
도커에서 좀 신경써야 할 부분은 그 이미지가 뭐하는 이미지냐에 따라 내용이 많이 다른데,
Code-server(Cdr) 같은 경우는 일단 이런것들이 중요하다.
1. 작업할 디렉터리
2. 실행하는 결과 (이는 즉 서버) 를 보여줄 포트
1과 연계되어서 이 디렉터리를 실제 파일과 동기화 할지, 그런데 여기서 흔히하는 실수가
1에서 작업한 내용이 도커의 경우 다시 재부팅하는 순간, 파일이 날아간다.
그냥 PC방에 있는 개념이다. 그럼 밑에를 봐보자.
docker run -it -p 127.0.0.1:8080:8080 -v "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server" -v "$PWD:/home/coder/project" codercom/code-server:v2
구문이 길어서 보기 힘든데
docker run
-it \
-p 127.0.0.1:8080:8080 \
-v "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server" \
-v "$PWD:/home/coder/project" \
codercom/code-server:v2
이걸 보면 위에서는 run 명령어의 옵션으로 -v 는 공유할 디렉터리 지정이다.
실제 디렉터리 : 컨테이너 디렉터리 <- 이건 엄청 중요하다. 이런 식인데,
$PWD 로 되어있는건 환경변수로 받아내는거다.
이게 예전에는 환경변수로 안받고 그냥 명령줄에 쳤지만, 바뀐 이유가 보안상 문제 때문이다.
ps -ef 로 명령줄에 크디샌셜 내용이 포함되서 나타나기 때문에 환경변수로 옮겼다고 한다.
-p 는 포트, 당연히 앞이 실제 호스트고 뒤가 컨테이너이다.
마지막으로 오는게 codercom/code-server:v2 이건데 이게 도커 이미지가 된다.
실제로 한번 최초 실행때 도커 이미지는 자동으로 컴퓨터에 받아져서 docker images하면 나타나게 된다.
이런식으로 나타난다. 필자의 경우에는 codercom/code-server, cdr이 등록되어 있다.
자 일단 code-server 를 돌릴려면 중요한거 두가지를 알게 되었다.
그럼 이 네트워크를 어떻게 구성할것인가?
디렉터리 주소를 어떻게 할 것인가?
이 두가지를 고려해야한다.
필자의 조건
필자의 경우에는 Google Cloud 에서 호스팅을 받아서 사용중 : Ubuntu 16.04
웹으로 구성하기 떄문에 Reverse Proxy (역방향 프록시)를 사용중
code-server 로 REACT 를 공부할거기 때문에 3000포트를 열어야함.
여담이지만, 요즘 트렌드가 한가지 기술만으로 될게 아니라 풀스택이 되야하는게
뭐 하나 제대로 하려면 네트워크, 서버, 개발, 결국 이것저것 다 알아야함..;;
일단 필자가 생각한 구조는 이렇다.
vs code를 port = 1121 / location : /home/~/test
그런데 react를 열기 위해서는 3000포트가 필요함
3000 포트를 역방향 프록시로 구축해둔 상태 물론 vscode 도 역방향
그림을 그려보자.
이걸 보고 이해햐보자.
왜 coder-server 내에는 0.0.0.0이고 왜 Docker는 127.0.0.1 일까?
그냥 쉽게 생각해서 127.0.0.1는 Localhost, 즉 해당 호스트 내에서 로컬에서만 바인딩 되는 주소고
0.0.0.0 은 외부로 바인딩 되는 주소이다. (물론 로컬 포함)
Cdr이 바인딩 되는데 왜 0.0.0.0 일까? 답은 내가 봐야하는건 Cdr의 주소이기 때문이다.
암튼 역방향 프록시를 잡아야 하는데 도커 내부에서 돌아가는 포트를 어떻게 잡을까?
근데 도커가 내부에 있는 포트를 밖으로 매핑해주는 기능이 있다.
-p 옵션으로 말이다.
0.0.0.0:8080 -> 127.0.0.1:1121 필자의 경우 이렇게 해야한다.
Docker 내의 Code-server에서 8080으로 현재 돌아가는 중이라면 그 8080포트를 필자는 1121에 바인딩 시켜야한다.
필자가 docker 를 구성하기 위해서 조합을 해보았다.
docker run
-it \
-p 127.0.0.1:8080:1121 \
-v "${HOME}/code-server2.1688-vsc1.39.2-linux-x86_64/code-server:/home/~/code-server2.1688-vsc1.39.2-linux-x86_64/code-server" \
-v "$PWD:/home/~/test" \
codercom/code-server:v2
자 뭔가 이상하다.
먼저 일단 6번 라인의 codercom/code-server:v2는 cdr 에서 기본으로 제공되는 도커 이미지.
맨처음에 보여준 Dockerfile 의 결과물.
-it 는 -i랑 -t 옵션인데, -i 는 interactive, -t는 tty , 즉 말그대로 도커에서 bash 쉘을 실행할 수 있게 하는 작업이고
여기서 주로 쓰는 작업중 하나가 -d 옵션인데, d는 daemon 이다. 즉 background 로 돌린다.
shell 에서 & 와 같다.
그러나 일단 역방향 프록시 포트를 4자리로 하면 오류가 날수도 있으니 5자리로 설정해보겠다.
-p 127.0.0.1:11211:1121 \
-p 127.0.0.1:30000:3000 \
역방향 프록시 주소 : cdr 주소 (중요) / [내가 봐야할 역방향 프록시 주소]:[docker에서 쓰는 cdr이랑 react 포트]
단순히 ) 니실제서버주소:도커주소
그럼 다시 짜보자.
docker run -it \
-p 127.0.0.1:11211:1121 \
-p 127.0.0.1:30000:3000 \
-v "${HOME}/code-server2.1688-vsc1.39.2-linux-x86_64/code-server:/home/~/code-server2.1688-vsc1.39.2-linux-x86_64/code-server" \
-v "$PWD:/home/~/test" \
codercom/code-server:v2
디렉터리 부분에서 오류가 나고, 내가 열어야할 cdr의 포트는 1121 인데, 8080으로 열리게 된다.
-v "$PWD:/home/~/test" \
codercom/code-server:v2 \
--port 1121
포트 부분는 아까 ENTRYPOINT 처럼 위와 같이 넣어주면 포트부분은 해결이 된다.
디렉터리 문제는 Cdr에서 기본적으로 제공하는 디렉터리로 /home/coder/project을 설정해야한다.
조금씩 고쳐주면,
v "$PWD:/home/coder/project" \
codercom/code-server:v2 \
--port 1121
이렇게 고쳐줄수 있다.
그런데 $PWD의 환경변수는 어디갔지? 선언해줘야 한다. 예시를 한번 봐보자,
#!/bin/bash
DOCKER_IMAGE="code-server"
SERVER_PORT=****
PREVIEW_PORT=****
SHARED_DIR="/root/workspace/test"
PASSWORD="****"
# docker image update
docker build --tag $DOCKER_IMAGE .
# shared directory
mkdir -p $SHARED_DIR/project
mkdir -p $SHARED_DIR/extensions
mkdir -p $SHARED_DIR/user-data
chmod 777 $SHARED_DIR/project
chmod 777 $SHARED_DIR/extensions
chmod 777 $SHARED_DIR/user-data
# run
docker run -itd \
--rm \
-p 127.0.0.1:$PREVIEW_PORT:$PREVIEW_PORT \
-p 127.0.0.1:$SERVER_PORT:$SERVER_PORT \
-v "$SHARED_DIR/project:/home/coder/project" \
-v "$SHARED_DIR/extensions:/home/coder/extensions" \
-v "$SHARED_DIR/user-data:/home/coder/user-data" \
-e PASSWORD=$PASSWORD \
$DOCKER_IMAGE \
--allow-http \
--port=$SERVER_PORT \
--extensions-dir="/home/coder/extensions" \
--user-data-dir="/home/coder/user-data"
DOCKER_IMAGE="code-server"는 무시하고 봐보자.
22번줄에 --rm 은 도커를 종료했을때 내부 파일을 초기화 할것인지, 그러니까 PC방 처럼 그렇게 쓸것인가 아닌가 차이.
#!/bin/bash
# envioment
VS_SERVER_PORT=8080
VS_SERVER_PREVIEW_PORT=11211 #역방향 포트
REACT_PORT = 3000
REACT_PREVIEW_PORT = 30000 #역방향 포트
SHARED_DIR="/home/~/test"
PASSWORD="pental"
# shared directory
mkdir -p $SHARED_DIR/project
mkdir -p $SHARED_DIR/extensions
mkdir -p $SHARED_DIR/user-data
# set access mode
chmod 777 $SHARED_DIR/project
chmod 777 $SHARED_DIR/extensions
chmod 777 $SHARED_DIR/user-data
docker run -itd \
-p 127.0.0.1:$VS_SERVER_PREVIEW_PORT:$VS_SERVER_PORT \
-p 127.0.0.1:$REACT_PREVIEW_PORT:$REACT_PORT \
-v "$SHARED_DIR/project:/home/coder/project" \
-v "$SHARED_DIR/extensions:/home/coder/extensions" \
-v "$SHARED_DIR/user-data:/home/coder/user-data" \
-e PASSWORD=$PASSWORD \
codercom/code-server:v2 \
--allow-http \
--port = $VS_SERVER_PORT \
--extensions-dir="/home/coder/extensions" \
--user-data-dir="/home/coder/user-data"
필자도 새롭게 고쳐 보았다.
하지만 당연히 안된다. 30번째 줄 벡 스페이스 이후에 띄어쓰기가 하나 있다.
당연히 띄어쓰기가 있으면 안된다..
아 물론 저걸 작성하고, sh 파일로 저장해줘야 실행가능하다. 물론 복사 붙여넣기도 가능하고.
에러를 보니.. 28,29,30 부분에 29번째 공백 줄이 하나 있지 않은가? 당연히 이것도 인식이 안된다.
일단 Docker 를 정지해야 하므로 docker stop $(docker ps -a -q) 를 쳐준다.
새롭게 다시 스크립트를 짜준다.
#!/bin/bash
# envioment
VS_SERVER_PORT=8080
VS_SERVER_PREVIEW_PORT=11211
REACT_PORT=3000
REACT_PREVIEW_PORT=30000
SHARED_DIR="/home/~/test"
PASSWORD="pental"
# shared directory
sudo mkdir -p $SHARED_DIR/project
sudo mkdir -p $SHARED_DIR/extensions
sudo mkdir -p $SHARED_DIR/user-data
# set access mode
sudo chmod 777 $SHARED_DIR/project
sudo chmod 777 $SHARED_DIR/extensions
sudo chmod 777 $SHARED_DIR/user-data
sudo docker run -itd \
-p 127.0.0.1:$VS_SERVER_PREVIEW_PORT:$VS_SERVER_PORT \
-p 127.0.0.1:$REACT_PREVIEW_PORT:$REACT_PORT \
-v "$SHARED_DIR/project:/home/coder/project" \
-v "$SHARED_DIR/extensions:/home/coder/extensions" \
-v "$SHARED_DIR/user-data:/home/coder/user-data" \
-e PASSWORD=$PASSWORD \
codercom/code-server:v2 \
--allow-http \
--port=$VS_SERVER_PORT \
--extensions-dir="/home/coder/extensions" \
--user-data-dir="/home/coder/user-data"
완성 스크립트이다.
정상적으로 작동하는지 확인하기 위해서 cdr 서버를 들어가본다.
정상적으로 작동한다. 미리 선언한 비밀번호 pental 를 넣어준다.
정상적으로 실행이 되었다.
오탈자나 추가적인 문의는 pental@kakao.com 으로 보내주세요 :)
다음은 Dockerfile 만들기 입니다.
'그냥 개발 및 잡담 > Docker' 카테고리의 다른 글
Docker 알아보기 - 도커의 기본 개념 (2) | 2019.11.17 |
---|