app.py
requirements.txt
pip3 install requirements.txt
로 설치 해당 프로그램 실행에 필요하여 설치해야 할 패키지들로 구성 (flask 모듈들 설치) requirements.txt
를 얻기 위해서는 pip3 freeze
명령어를 사용한다.test.py
README.md
cat requirements.txt
cat
명령어를 통해 requirements.txt
에 기술된 내용을 보며 확인한다.pip3 install -r requirements.txt
pip3 install requirements.txt
만 실행하면 ERROR: Could not find a version that satisfies the requirement requirements.txt (from versions: none) HINT: You are attempting to install a package literally named "requirements.txt" (which cannot exist). Consider using the '-r' flag to install the packages listed in requirements.txt ERROR: No matching distribution found for requirements.txt
이라는 오류가 발생한다. requirements.txt
내부에 있는 패키지를 설치해야 한다는 것을 알려 주기 위해 -r
을 붙여 주어야 한다.python3 -m flask run --host=0.0.0.0 --port=4000
localhost:4000
으로 접속할 수 있게 포트를 열어 준다.✍ Docker 컨테이너 내부 프로세스와 호스트 프로세스 간의 통신
- 만약 어떤 웹서비스를 Docker Container 내에서 실행한다면 특정 Port 번호를 오픈해야 한다.
- 이때 Docker가 없으면 문제 없이 실행된다.
- 그런데 만약 Docker Container 내에 특정 Port 번호로 실행된 Flask App이 있다면
- 이 앱이 Container 밖에서도 실행될까?
- Docker Container는 컴퓨터 안의 컴퓨터라고 생각하면 된다.
- 그렇기 때문에
docker run
으로 구동하여도 Container 밖에서는 실행되지 않는다.- Container는 완전 별개의 공간이라 바깥 프로세스는 읽을 수 없기 때문이다.
- 이를 해결하는 방법은?
- Port Forwarding 해 주어야 한다.
- 밖에서도 Container 내부의 Port 번호가 보이게 해 주어야 하는데 다음과 같이
docker run -p 4000:4000 image_name
Port 번호를 명령 시 같이 매핑해 주면 된다.
FROM
으로 설정LABEL
는 key-value 포맷으로 되어 있고, docker 이미지에 대한 메타데이터를 지정한다. LABEL
은 docker inspect
명령어를 통해 찾을 수 있다.COPY
명령어를 통해 해당 위치에 뒤에 붙는 파일 app.py
와 requirements.txt
를 복사한다.RUN
을 통해 이미지 build 시 해당 명령을 실행한다.EXPOSE PORT_NUMBER
는 docker image가 실행될 때 이 포트 번호를 사용하니 포트 맵핑을 할 때 참고하라는 뜻이다. 실제 동작에는 전혀 관여하지 않는 명령 중 하나다.FROM python:3.8-slim-buster
LABEL Maintainer="keeyong@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"]
docker build -t docker_image_name .
--platform=
을 통해 수정해 준다.docker inspect docker_image_name
Dockerfile
에서 LABEL
로 지정해 준 내용도 확인할 수 있다.docker run docker_image_name
Container
내부에만 열리게 되므로 localhost:4000에 접속했을 때 오류가 발생한다.docker run -p 4000:4000 docker_image_name
Container
외부에서도 실행되게 하기 위해서 -p port_number:port_number
를 설정해 주어야 한다.docker stop container_id
Docker Image
이다.Continuous Integration
라고 하며 이 역시 소프트웨어 안정성 증대를 위해 진행한다.Software Engineering Practice
의 하나이다.📌 CI/CD란?
Code Commit -> CI (테스트 수행) -> CD (소프트웨어 배포) -> 모니터링
Git
은 분산 환경을 지원하는 소스 버전 컨트롤 시스템SVN/CVS
는 네트워크가 안 되는 환경이거나 보안 때문에 인증이 안 된다면 사용할 수 없는데 Git
은 로컬에서 서버단 소스에 백업을 가지고 개발이 끝나면 서버단에 올리는 형태이기 때문에 네트워크가 안 되어도 혼자 개발할 수 있다.📌 Git 관련 용어
- Repo: Repository의 줄임말로 Git으로 관리되는 소프트웨어 프로젝트
- Master/Main: 한 Repo에서 기본이 되는 메인 코드로 Git에서 master이고 Github에서는 Main
- Branch: 자신의 Repo에서 새로운 기능 개발을 위해 Master 혹은 다른 Branch로부터 만든 코드 작업본을 지칭 (원본 Branch와 병합하려는 목적으로 생성)
- Clone: 다른 계정에 존재하는 repo로부터 새로운 local repository를 생성
- Commit (Check in): 내가 만든 코드 변경을 Local Repository에 반영
- Pull: Master와 같은 Remote Repo로부터 마지막 Pull 이후 변경된 것을 다시 가지고 오는 작업 (Master와 동기화)
- Push: 작업 중인 Local Repo에서 Remote Repo로 복사하는 것
- Merge: Pull이나 Push 했을 경우 두 Branch 가간의 충돌(Conflict)를 해결하는 과정 (직접 해결하기도 함)
서비스**이다.
Git
은 텍스트 Command Line 툴이지만 Github
는 웹 기반 인터페이스도 제공한다.📌 Push나 Merge 시점이 CI/CD를 해야 할 순간
- 코드가 main/master branch에 추가되는 순간 CI/CD를 트리거
- 이때 테스트를 수행하고 최종적으로 Docker Image 등을 만들도록 하는 것이 가능
- CI/CD는 Github에 구현하는 것이 가장 자연스러움
- Github에는 Actions라는 기능을 통해 Workflow라는 이름으로 구현 가능
YAML 파일
로 저장된다.actions
라고 부르는 명령어의 집합이 될 수도 있다.import random
def lower(a)
return a.lower()
lower("aBC") # 테스트 출력 예
$ flake8 sample.py
sample.py:3:12: E999 SyntaxError: invalid syntax
오류를 안내해 주게 된다. unittest
를 사용하거나 pytest
를 사용한다.pytest
를 더 많이 사용하고 있다.python3 -m unittest test.py
를 사용한다.python3 test.py
를 사용한다.Comments
는 #
과 같이 시작한다.key-value
의 구조라면 콜론과 공백을 사용해 준다. name: John Doe
age: 30
List
형식을 표현하고 싶다면 이렇게 표현한다. hobbies:
- reading
- hiking
Nested key-value
를 사용한다면 두 번의 공백이 들어가게 된다.contact:
email: john.doe@example.com
phone:
home: 555-1234
work: 555-5678
multi-line string
의 경우 콜론 뒤에 파이프(|)를 사용해 준다.description:|
This is a
multi-line
string
repo_name/.github/workflows/
밑에 위치하게 된다.yml
혹은 yaml
파일로 생성된다.unittest
는 총 5 번의 테스트가 존재했으며 모두 성공한 것을 볼 수 있다.Docker Image
라는 템플릿을 사용해 준다.✍ 어떻게 Docker Hub의 ID와 PASSWORD를 Github 내에서 사용할 수 있게 저장할 수 있을까?
- 먼저
settings
를 선택해 준다.
Secrets and Variables
를 선택해 준다. 이때Secrets
밑에 두 개의 변수를 만들어 준다.
- 다음과 같이
New repository secret
를 통해Secrets
밑에 Docker Hub의 ID와 PASSWORD를 저장(설정)해 준다.
- 이렇게 생성된 변수는
${{secrets.변수명}}
을 통해 호출해 줄 수 있다.