데브코스 47일차 - Docker 실습 & CI/CD

Pori·2023년 12월 19일
0

데엔

목록 보기
40/47

Web service를 Docker로 실행해보기

HangMan web 실습

과정

hangman_web이라는 repo의 main에 코드가 머지될 때마다 다음을 수행

  1. 테스트 수행
  2. Docker Image 빌드
  3. Docker Image를 Docker Hub로 푸시

→ Github Actions로 구현한다.

Hangman 소개

  • flask를 사용한 웹 서비스 → flask 관련 모듈 설치 필요
  • 실행 : python3 -m flask run --host=0.0.0.0 --port=4000
  • requirements.txt
Flask==2.3.2
Flask-HTTPAuth==4.5.0
Flask-Login==0.6.2
Flask-SQLAlchemy==3.0.3
  • app.py
from flask import Flask,session

app= Flask(__name__)
...
app.secret_key = "Python Study"
if __name__=="__main__":
	app.run()

Docker Image로 구성하기

  • Docker 컨테이너 내부 프로세스와 호스트 프로세스간의 통신
    : Docker 컨테이너 내부에서만 포트를 열어도 호스트에서 포트가 닫혀있다면 서비스에 접속이 불가능하다. docker run -p 4000:4000 image_name → 포트 4000에 대한 액세스를 수행
    - 운영체제에서 접근이 가능한 포트를 포워드해야한다.
  • Dockerfile
    • Base image : FROM python:3.8-slim-buster
    • LABEL을 이용해서 찾기 쉽게 만듬 : LABEL Maintainer="my_name"
    • WORKDIR : 작업 디랙토리 설정 WORKDIR /app
    • COPY : 복사할 파일들을 위치와 함께 알려주기 COPY app.py ./ COPY requirements.txt ./
    • RUN : 실행할 pip 명령 작성 RUN pip3 install -r requirements.txt
    • EXPOSE : 포트번호를 넣어 맵핑시 참고하게 만들기 EXPOSE 4000
    • CMD : cmd 명령을 작성 CMD ["python3", "-m","flask","run","--host=0.0.0.0","--port=4000"]
# 전체 코드
FROM python:3.8-slim-buster
LABEL Maintainer="areacmzl@gmail.com"
WORKDIR /app
COPY app.py ./
COPY requirements.txt ./
RUN pip3 install -r requirements.txt
EXPOSE 4000
CMD ["python3", "-m","flask","run","--host=0.0.0.0","--port=4000"]

Hangman 서비스 Dockerization

  • 빌드하기 : docker build --platform=linux/amd64 -t poriz/hangman . (.유의!)
  • 푸시 : docker push poriz/hangman

CI/CD와 Github Actions

  • 소프트웨어 빌드 : 개발한 소프트웨어를 최종 출시를 위한 형태로 만드는 것. 충분한 테스트가 필요하다. 개발이 끝나기 전부터 빌드를 하면 소프트웨어의 안정성이 증대된다.
  • Continuous Integration
    • Software Engineering Practice의 하나
    • 기본원칙
      • 코드 Repo는 하나만 유지한다.
      • 코드 변경을 최대한 자주 반영
      • 테스트를 최대한 추가
      • 빌드를 계속적으로 수행 (자동화)
      • 성공한 빌드의 프로덕션 릴리스 (자동화)
  • CI/CD : 코드 커밋을하면 테스트 수행과 소프트웨어 배포를 하는 것을 말함.

Github Actions

  • CI/CD를 Github 위에서 구현하기 위한 서비스
  • Workflow라 부르며, 다음과 같은 컴포넌트들로 구성된다.
    • Events
    • Jobs
    • Actions
    • Runner
  • Workflow
    • 트리거 이벤트가 발생하면 시작되는 일련의 동작들을 지칭
    • Workflow를 위한 명령어들은 YAML 파일로 저장된다.
    • Workflow는 Job들로 나누어지며, 각 job은 일련의 스텝을 수행한다.
      • 각 스텝은 하나 혹은 그 이상의 명령어를 실행한다.
  • Actions 사용: github repo에 Actions 메뉴를 활용, yml 파일을 생성하거나 템플릿을 선택 후 수정하여 작성한다.

Action 사용 1. 테스트 추가하기

  • 사용할 CI Template: Python Application
    - 추가로 flake8을 사용하여 코딩 스타일 체크도 진행

  • 기본구성(unittest 사용)

    • unittest.TestCase를 부모로 받아 class를 새로 생성한다.
    • test로 시작하는 함수들을 생성하면 해당 클래스 내의 함수들을 부르게 된다.
  • python-app.yml

    • on : 트리거 이벤트 지정, push나 pull_request 시에 동작할 branch를 설정한다.
    • unittest사용을 위해 약간의 수정이 필요하다.
    jobs:
      build:
    
        runs-on: ubuntu-latest
    
        steps:
        - uses: actions/checkout@v3
        - name: Set up Python 3.10
          uses: actions/setup-python@v3
          with:
            python-version: "3.10"
        - name: Install dependencies
          run: |
            python -m pip install --upgrade pip
            pip install flake8
            if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
        - name: Lint with flake8 # pytest 삭제
          run: |
            # stop the build if there are Python syntax errors or undefined names
            flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
            # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
            flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
        - name: Test with unittest # unittest로 교체
    			# test로 시작하는 모든 파이썬 파일에 대해서 수행하기 위해 추가
          run: |
            python -m unittest discover -p 'test*.py' 
  • 수행

  • 테스트 확인

Action 사용 2. Dockerization 추가

  • Github Actions를 통해 main 브랜치에 push나 PR이 있는 경우 Docker Image를 만들고 Docker Hub으로 푸시

  • Docker image 템플릿 사용

  • Docker 관련 스텝

    • docker login : docker hub의 id, pw를 읽어와야한다. → github내에 저장
      • secrets.DOCKER_USER
      • secrets.DOCKER_PASSWORD
    - name: docker login
    	env:
    		DOCKER_USER: ${{secrets.DOCKER_USER}}
    		DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
    	run: |
    		docker login -u #DOCKER_USER -p $DOCKER_PASSWORD
  • docker build
    - name: Build the Docker image
    	run: docker build --tag ${{secrets.DOCKER_USER}}/hangman:latest .
  • docker push
    - name: docker push
    	run: docker push $DOCKER_USER/hangman:latest
  • Docker Hub 정보 설정 Actions secrets and variables > Actions
    - DOCKER_USER와 DOCKER_PASSWORD 저장
    - yml에서는 다음과 같이 접근 ${{secrets.DOCKER_USER}}


  • 결과


yml 파일 포맷

: JSON과 동일하며 변환도 가능하다.

  • Key-value pairs are separated by a colon and a space
- name: John Doe
- age: 30
  • Lists are denoted by a hyphen and a space
hobbies:
- reading
- hiking
  • Nested key-value pairs are indented with two spaces
contact:
email: john.doe@example.com
phone:
home: 555-1234
work: 555-5678

YAML ↔ JSON : https://www.json2yaml.com/

0개의 댓글