상세 컨텐츠

본문 제목

[4.5차/15기 김제성] Docker 실습

본문

도커 환경변수

: 각 컨테이너는 독립적이기 때문에 도커를 구동하는 호스트에서 환경변수를 통해 외부 정보를 알려주도록 함 (도커파일에서 환경변수 정의)

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=complusblog&logNo=220975099502

 

—rm 옵션

: 컨테이너를 일회성으로 실행할 때 주로 쓰이는데요. 컨테이너가 종료될 때 컨테이너와 관련된 리소스(파일 시스템, 볼륨)까지 깨끗이 제거해줍니다.

 

-it옵션

: -i 옵션과 -t 옵션은 같이 쓰이는 경우가 매우 많은데요. 이 두 옵션은 컨테이너를 종료하지 않은체로, 터미널의 입력을 계속해서 컨테이너로 전달하기 위해서 사용합니다. 따라서, -it  옵션은 특히 컨테이너의 쉘(shell)이나 CLI 도구를 사용할 때 매우 유용하게 사용됩니다.

https://www.daleseo.com/docker-run/

 

도커 볼륨 설정하는 이유

: 도커에서 컨테이너를 업데이트 하게 되면 기존 컨테이너를 삭제하고 새로운 버전을 pull하게 된다. 이때 이전 버전 컨테이너에서 생성된 파일이 다 사라지는 것을 막게 하기 위해서 데이터를 컨테이너 내부가 아닌 외부 스토리지에 저장하게 하는 것

https://wnsgml972.github.io/setting/2020/07/20/docker/

 

 

 


도커 빌드

https://www.youtube.com/watch?v=59P19DFB0sc&list=PLnIaYcDMsSczk-byS2iCDmQCfVU_KHWDk&index=13

 

# test_server.py
import socket

with socket.socket() as s:
  s.bind(("0.0.0.0", 12345))
  s.listen()
  print("server is started")
  conn, addr = s.accept()
  # conn 클라이언트와 통신할 소켓
  # addr 클라이언트의 정보가 들어있음
  with conn:
    print("Connected by", addr)
    while True:
      data = conn.recv(1024)
      if not data: break
      conn.sendall(data)

클라이언트로 부터 어떤 string을 입력받으면 그걸 그대로 돌려주는 간단한 서버 (echo)

12345 포트로 통신하는 것으로 설정

 

jay@LAPTOP-HAHI675A:~$ sudo nano test_server.py

nc 127.0.0.1 12345

nano 편집기를 활용하여 py파일을 만들어주고

TCP서버, TCP 클라이언트 요청이 가능한 nc (netcat) 옵션을 활용하여 서버가 잘 작동하는 것을 확인한다

 

(별도 dir 추가 생성함)

이미지를 생성하기 위해 필요한 일종의 template인 dockerfile도 nano 편집기로 작성을 해주고

 

jay@LAPTOP-HAHI675A:~/my_first_project$ sudo nano dockerfile
FROM python:3.7

RUN mkdir /echo
COPY test_server.py /echo

CMD ["python", "/echo/test_server.py"]

빌드 옵션을 적용해주면

jay@LAPTOP-HAHI675A:~/my_first_project$ ls
dockerfile  test_server.py
jay@LAPTOP-HAHI675A:~/my_first_project$ sudo docker build -t echo_test .

(. 은 현재 디렉토리 의미)

 

새로운 echo_test 이미지가 생성된 것을 확인할 수 있다

 

 

컨테이너를 생성해 run 실행시켜보면

jay@LAPTOP-HAHI675A:~/my_first_project$ sudo docker run -t -p 12345:12345 --name et --rm echo_test
server is started
Connected by ('172.17.0.1', 34868)  # 별도의 콘솔창에서 nc 127.0.0.1 12345 로 접속하면 뜸

echo_test 서비스가 잘 작동하는 것으로 볼 수 있다

 

 


Docker voting application

Udemy Docker for the Absolute Beginner - Hands On - DevOps

 

python vote : 통해 두가지 옵션을 선택하게 front end web app을 구축한다

redis : 각 투표를 모은다

.NET : 투표 결과를 db에 반영시

Postgred db : docker volume에 의해 운영되는 db

Node.js : 실시간으로 투표 결과를 보여

 

 

해당 프로젝트가 올라와 있는 깃허브 레포를 다운받아주고,

jay@LAPTOP-HAHI675A:~$ cd example-voting-app/vote

python으로 구성된 vote파일에서 Dockerfile을 확인해본다

jay@LAPTOP-HAHI675A:~/example-voting-app/vote$ cat Dockerfile

# Using official python runtime base image
FROM python:3.9-slim

# add curl for healthcheck
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Set the application directory
WORKDIR /app

# Install our requirements.txt
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

# Copy our code from the current folder to /app inside the container
COPY . .

# Make port 80 available for links and/or publish
EXPOSE 80

# Define our command to be run when launching the container
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"]

작성된 도커파일로 이미지를 만들기 위해 build를 해주고

jay@LAPTOP-HAHI675A:~/example-voting-app/vote$ sudo docker build . -t voting-app

컨테이너를 만들어서 run 실행시켜주면

 

jay@LAPTOP-HAHI675A:~/example-voting-app/vote$ sudo docker run -p 5000:80 voting-app
[2023-04-09 10:02:36 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2023-04-09 10:02:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2023-04-09 10:02:36 +0000] [1] [INFO] Using worker: sync
[2023-04-09 10:02:36 +0000] [7] [INFO] Booting worker with pid: 7
[2023-04-09 10:02:36 +0000] [8] [INFO] Booting worker with pid: 8
[2023-04-09 10:02:36 +0000] [9] [INFO] Booting worker with pid: 9
[2023-04-09 10:02:36 +0000] [10] [INFO] Booting worker with pid: 10

vote 웹페이지가 생성된 것을 볼 수 있다

실제로 클릭을 해보면 에러가 뜨는 것을 확인할 수 있는데

app.py를 보면 클릭했을때(post) redis에 어떤 조건을 실행하도록 되어있고 아직 redis 컨테이너는 실행시키지 못했기 때문이다.

app.py 일부

따라서 redis 컨테이너를 생성, 실행시켜준뒤 (run)

—link 옵션을 통해 voting app 컨테이너에 redis를 연결 시켜주면

 

jay@LAPTOP-HAHI675A:~$ sudo docker run -d --name=redis redis
jay@LAPTOP-HAHI675A:~$ sudo docker run -p 5000:80 --link redis:redis voting-app

app.py에 나와있는 response 결과물처럼 클릭한 동물에 체크표시가 뜬다

 

worker를 실행시키기 위해서 우선 먼저 postgres db 컨테이너를 만들어줘야 한다

jay@LAPTOP-HAHI675A:~/example-voting-app/worker$ sudo docker run -d --name=db -e POSTGRES_PASSWORD=postgres postgres:9.4

worker 파일에서 해당 이미지 빌드해주고

jay@LAPTOP-HAHI675A:~/example-voting-app/worker$ sudo docker build . -t worker.app
jay@LAPTOP-HAHI675A:~/example-voting-app/worker$ sudo docker run --link redis:redis --link db:db worker.app

컨테이너 만들어줄 때 worker에게는 두 개의 링크 (redis / db )를 연결시켜주어야 한다

 

 

투표 결과물을 보여주는 node js 파일이 담긴 /result 로 넘어가서

result.app을 빌드해주고 db에 링크를 걸어주어 컨테이너를 생성한다

jay@LAPTOP-HAHI675A:~/example-voting-app/result$ cat Dockerfile
FROM node:18-slim

# add curl for healthcheck
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    curl \
    tini \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# have nodemon available for local dev use (file watching)
RUN npm install -g nodemon

COPY package*.json ./

RUN npm ci \
 && npm cache clean --force \
 && mv /app/node_modules /node_modules

COPY . .

ENV PORT 80
EXPOSE 80

ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["node", "server.js"]
jay@LAPTOP-HAHI675A:~/example-voting-app/result$ sudo docker build . -t result-app
jay@LAPTOP-HAHI675A:~/example-voting-app/result$ sudo docker run -p 5001:80 --link db:db result.app

5000번 포트에는 python으로 만든 서버를 걸어두었기에 result 결과 웹페이지는 겹치지 않게 5001 포트로 연결하였다

 

이렇게 매번 이미지 빌드해오고 컨테이너 만들고 하는 번거로운 작업을

.yml 파일에 각 application의 필요 요건들을 적어두어

그 .yml 파일만을 돌려서 최종 작업을 손쉽게 작업해줄 수 있게 하는 명령어가 compose 이다

jay@LAPTOP-HAHI675A:~$ cat > docker-compose.yml
redis:

db:

vote:

worker:

result:^C

.yml 파일 뼈대를 만들고 vi 에디터를 활용해서 각 컨테이너들의 필요 사항들을 기재해준다

 

redis:
  image: redis

db:
  image: postgres:9.4
  environment:
     POSTGRES_USER: postgres
     POSTGRES_PASSWORD: postgres

vote:
  image: voting-app
  ports:
    - 5000:80
  links:
    - redis

worker:
  image: worker-app
  links:
    - db
    - redis

result:
  image: result-app
  ports:
    - 5001:80
  links:
    - db
jay@LAPTOP-HAHI675A:~$ sudo docker-compose up

위에서 진행한 것처럼 동일한 vote 결과물을 얻을 수 있다

 

 

+) 상황에 따라 요즘엔 docker-compose version 3를 활용한다고 한다

관련글 더보기

댓글 영역