웹 서비스를 Docker로 실행해 보기
학습 목표
웹 서비스를 Docker로 구동해 보는 전체 과정 익히기
- hangman_web이라는 repo의 main에 코드가 머지될 때마다 다음을 수행
- Github repo의 Github Actions로 구현
- 테스트 수행
- Docker Image 빌드
- Docker Image를 Docker Hub로 푸시
Hangman 서비스
Hangman 소개
- hangman_web github repo (미완성)
- hangman 프로그램을 flask를 사용하여 웹으로 노출
- 포트번호는 어디든 바인딩 가능하며 실행할 때 지정
- flask 관련 모듈 설치 필요 (requirements.txt)
- 실행 방법 : python3 -m flask run --host=0.0.0.0 --port=4000
hangman_web 실행
- https://labs.play-with-docker.com/ 접속
- hangman_web clone 후 requirements.txt에 기술된 모듈 설치
- flask 실행 : 기본적으로 app.py를 실행
- open port를 클릭해 4000 입력
git clone https://github.com/ss721229/hangman_web.git
cd hangman_web
pip3 install -r requirements.txt
python -m flask run --host=0.0.0.0 --port=4000
Docker Container 내부 프로세스와 호스트 프로세스 간 통신
- Docker Container로 포트 4000에 실행된 Flask app에 호스트는 접근 불가
- 해결 방법
- 포트 포워딩 : Docker Container 내부 프로세스가 오픈한 포트 번호를 외부로 노출
- Docker Container를 실행할 때 -p 옵션을 통해 포트 매핑 -> 로컬호스트로 접속 가능
- docker run -p 4000:4000 "Image_name"
Hangman를 Docker Hub에 업로드
- -d 옵션 : 백그라운드에서 서버 실행, docker ps로 보면 실행 확인 가능
- docker inspect : Image의 세부 정보 확인 가능
- docker stop : 터미널 환경에서 container 종료 가능
docker build --platform=linux/amd64 -t jelly878/hangman .
docker image ls
# docker inspect jelly878/hangman
docker run -p 4000:4000 jelly/hangman
# docker run -p 4000:4000 -d jelly878/hangman
docker push keeyong/hangman
CI/CD
소프트웨어 빌드
- 자신 (혹은 팀)이 개발한 소프트웨어를 최종적으로 출시하기 위한 형태로 만다는 것
- 참여 개발자가 많을수록 중요
- 개발이 끝나기 전부터 빌드하면 소프트웨어의 안정성 증대
- 어느 정도 프로덕트가 안정화되고 인원이 있을 때 적용 가능
빌드 실패
- 새 코드의 커밋으로 인해 테스트가 실패하는 경우
- 많은 회사가 빌드 실패 시 빌드가 다시 성공할 때까지 코드 변경을 금지
- 빌드 실패는 모든 사람을 잡아두는 족쇄
- 어느 정도 조직이 커지면 빌드만 전담하는 엔지니어가 생김
Continuous Integration, CI
- 소프트웨어 엔지니어링 방식 중 하나
- 기본 원칙
- 코드 Repo는 하나만 유지 (main)
- 코드 변경을 최대한 자주 반영
- 테스트를 최대한 추가 (Test Coverage)
- 빌드를 계속적으로 수행 (자동화)
- 성공한 빌드의 프로덕션 릴리스 (자동화, CD)
Github
Git
- Git은 분산환경을 지원하는 소스 버전 컨트롤 시스템
- 리눅스를 만든 Linus Torvalds가 개발
- CVN/CVS에 비해 현저하게 빠르나 사용법은 복잡
- 장점
- 다수의 개발자가 공동 개발
- 코드 리뷰 가능
- 코드 백업
- 과거의 코드로 롤백 가능
Github
- Git repo 호스팅 / 클라우드 서비스
- Git은 텍스트 커맨드라인 툴이지만 Github는 웹기반 인터페이스도 제공
- 자신이 만든 repo가 모두 public일 경우 무료
- 다양한 툴을 제공 : Copilot, CI/CD를 위한 Workflows, 문서화를 위한 Wikis, 리포트와 트랙킹을 위한 Issues
Git 관련 용어
- Repo : Repository의 준말로 Git으로 관리되는 소프트웨어 프로젝트
- Master / main : 한 Repo에서 기본이 되는 메인 코드 지칭
- Branch : 자신의 Repo에서 새로운 기능 개발 등을 위해 main 혹은 다른 Branch로부터 만든 코드 작업본
- Clone : 다른 계정에 존재하는 Repo로부터 새로운 Local Repo를 만드는 것
- Commit (Check-in) : 내가 만든 코드 변경을 Branch의 Local Repo에 반영하는 것
- pull : Remote Repo로부터 마지막 Pull 이후 변경된 것을 가져오는 작업
- Push : 작업 중인 Local Repo에서 Remote Repo로 변경 사항을 복사하는 것
- Merge : Pull이나 Push 했을 경우 두 Branch 간의 충돌을 해결하는 과정
Push / Merge 시점에 CI/CD를 실행
- 코드가 main이나 특정 branch에 추가되는 순간 CI/CD 트리거
- 테스트를 수행하고 최종적으로 Docker Image 등을 만들도록 하는 것이 가능
- CI/CD는 Github에 구현하는 것이 가장 자연스러움
- Github에서는 Actions 기능을 통해 Workflow로 구현 가능
Github Actions
Github Actions
- CI/CD를 Github에서 구현하기 위한 서비스로 코드 테스트, 빌드, 배포 자동화 기능 제공
- Workflow라 부르며 Event, Jobs, Actions, Runner로 구성
Workflow
- 트리거 이벤트가 발생하면 시작되는 일련의 동작들을 지칭
- 예시
- 코드 커밋 (main과 같은 특정 branch를 대상으로 제한 가능)
- Pull Request 생성
- 다른 Workflow의 성공적인 실행
- Workflow를 위한 명령어는 YAML 파일로 저장
- Workflow는 Job들로 나눠지며 각 Job은 일련의 스텝 수행
- 각 스텝은 하나 이상의 명령어 실행
- 각 스텝은 윈도우나 리눅스 서버 위에서 Runner에 의해 실행
Github Actions 사용 1 : 테스트 추가
- Git Actions를 통해 main에 push나 pull request가 있는 경우 test.py를 실행
- 하나의 repo에 대해 다수의 workflow 존재 가능
- 모두 ./github/workflows/ 밑에 yml 파일 형태로 존재
사용할 CI Template : Python Application
- 기본으로 pytest를 테스트 프레임워크로 설치
- Python code linting tool로 flake8을 설치하고 문법 에러와 코딩 스타일 체크
파이썬 코드 스타일 체크 - flake8
- 파이썬 코드에서 에러나 코딩 스타일 등에서 이슈를 체크해 주는 툴
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
python-app.yml
- Github Actions의 Python application Configure
- 기본적으로 내용이 어느 정도 적혀 있음 (수정 사항은 주석으로 적어 놓음)
- on : 해당 branch에서 push, pull request가 발생했을 때 트리거
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python application
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- 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 # pytest X
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
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 # pytest -> unittest
run: |
python -m unittest discover -p 'test*.py' # pytest -> python -m unittest discover -p 'test*.py'
Github Actions 사용 2 : Dockerization 추가
- main에 push나 pull request가 있는 경우 Docker Image를 만들고 Docker Hub로 푸시
Docker 관련 스텝
- docker login
- Docker hub ID와 PW를 하드코딩 하지 않고 Github 내에 저장
- secrets.DOCKER_USER, secrets.DOCKER_PASSWORD
- docker build
- docker push
docker-image.yml
- github repo > settings > secrets and variables > actions > repo secrets
- DOCKER_USER와 DOCKER_PASSWORD 등록
- workflow에서는 ${{ }} 형태로 가져와 사용 가능
- env 형태로 변수를 사용할 수도 있고, 직접 사용해도 됨
name: Docker Image CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: docker login
env:
DOCKER_USER: ${{secrets.DOCKER_USER}}
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
run: |
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
- name: Build the Docker image
run: docker build --tag ${{secrets.DOCKER_USER}}/hangman:latest .
- name: docker push
run : docker push ${{secrets.DOCKER_USER}}/hangman:latest
'[프로그래머스] 데이터 엔지니어링 데브코스 3기 > TIL(Today I Learn)' 카테고리의 다른 글
[TIL - 49일 차] Docker & K8S 실습 (5) (0) | 2024.05.30 |
---|---|
[TIL - 48일 차] Docker & K8S 실습 (3) (0) | 2024.05.29 |
[TIL - 46일 차] Docker & K8S 실습 (1) (0) | 2024.05.27 |
[TIL - 45일 차] 데이터 파이프라인과 Airflow (5) (0) | 2024.05.24 |
[TIL - 44일 차] 데이터 파이프라인과 Airflow (4) (0) | 2024.05.23 |