🧩 DevOps/Docker

[Docker] Docker에 Flask App 배포하기

nayoungs 2022. 5. 11. 23:16
728x90

📌Index

 

Flask마이크로 서비스 웹 프레임워크로 간단한 웹 사이트, 혹은 간단한 API 서버를 만드는 데에

특화되어있다. (python 3.7 이상 필요)



✔️ 환경 구성

Flask 환경 구성을 위해 아래의 3가지를 설치하자

  • python3
  • python3-pip
  • python3-venv

pip 는 파이썬 패키지를 설치하고 관리하는 도구이다.

  • pippython2의 패키지 관리자
  • pip3python3의 패키지 관리자
$ sudo apt install python3-pip python3-venv

 

가상 환경

가상환경(virtual environment)는 Python에만 존재하는 개념으로, 가상환경을 사용하면 가상 환경에서만 패키지를 설치하고 관리할 수 있다. Flask는 우리가 만드려는 App에만 필요하기 때문에 Global 전체에 설치하는 것이 불필요하고, 해당되는 App에만 사용할 수 있는 가상 환경을 만들고, 가상 환경에서만 사용할 수 있는 패키지를 따로 관리한다(Isolation)

 

가상환경 만들기

가상환경을 위한 별도의 디렉토리를 만들어주는 것은 중요하다

$ mkdir -p /python/hello-flask
$ cd /python/hello-flask

 

가상환경/프로젝트를 생성

$ python3 -m venv venv
  • venv는 파이썬이 관리하므로, 직접적으로 건들이지 않는 것이 좋음
  • -m venv에서 venv는 모듈명(패키지명)이고, 뒤의 venv는 가상환경의 이름
  • 가상환경의 이름을 꼭 venv로 설정할 필요는 없으나 일반적으로 venv로 지정
  • 가상 환경에 패키지를 설치하면 /venv/lib/site-packages/에 설치됨(isolation)

 

가상환경 활성화

$ . venv/bin/activate
  • 가상환경 비활성화(가상환경에서 벗어나기) : deactivate
  • 관리하는 패키지 목록 확인하기 : pip3 list
  • (venv) 를 통해 가상 환경에 들어온 것을 확인
  • 작업 디렉토리에서 가상환경을 활성화를 시켜줘야함
  • 참고) 가상환경에서 디렉토리를 빠져나와도 가상환경은 유지됨
  • 터미널을 닫았다가 다시 열면 가상환경에서 나와지기 때문에 꼭 promt를 통해 본인이 가상환경인지 확인해야함

 

Flask 설치

$ pip3 install Flask



 

✔️ Application 만들기

Minimal Application

a minimal application을 참조하여, 아래와 같이 hello.py 파일을 작성하자.

hello.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

파일 내용 설명

  • from flask import Flask : Flask 패키지를 가져옴
  • @app.route("/") : app.route decorator로, root(/) 경로로 오면 아래의 함수를 실행하도록 설정
    • Linux의 DocumentRoot라고 생각하면 이해하기 쉬울 것 같다
  • def hello_world() : 함수정의, return 값만 있음

 

Flask 실행

$ export FLASK_APP=hello
$ flask run
 * Serving Flask app 'hello' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
127.0.0.1 - - [11/May/2022 05:16:16] "GET / HTTP/1.1" 200 -
  • flask run == python3 -m flask run

 

접속 확인

단, 개발중에 외부에 노출되면 위험하기 때문에,

기본적으로 외부에서는 접속이 불가능하고 내부에서만 접속 가능하도록 구성되어있다.

$ curl localhost:5000
<p>Hello, World!</p>%

다음 명령을 통해 외부에서의 접속을 허용할 수 있다.

$ flask run --host='0.0.0.0' [--port='8080']

 

Rendering Templates

rendering-templates을 참조하여 hello.py 를 작성해보자

hello.py

from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route('/')
def hello_world():
    return "<p>Hello, World!</p>"

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

파일 내용 설명

  • root(/)로 접근하면 Hello, World가 출력
  • /hello/ 뒤에 변수(name)을 적으면 함수(hello)의 매개변수로 전달됨

/template/hello.html을 다음과 같이 작성해보자

<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

파일 내용 설명

  • {% if name %} 조건문: name이라는 변수가 있으면 Hello {{ name }}!을 출력
  • {% else %}: 없으면 Hello, World!을 출력

 

Flask 실행

$ flask run --host='0.0.0.0' --port='8080'

 

접속 확인

/hello/뒤의 변수 /encore가 들어가서 출력된 것을 확인할 수 있다.

 



 

✔️ Freeze

현재 설치된 패키지들을 보존하여 저장할 수 있다.

$ pip3 freeze > requirements.txt
$ cat requirements.txt 
click==8.1.3
Flask==2.1.2
importlib-metadata==4.11.3
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
Werkzeug==2.1.2
zipp==3.8.0

매번 애플리케이션을 개발할 때마다 필요한 패키지들을 설치하는 것은 매우 번거럽고 어렵다.

따라서 필요한 패키지들을 requirements.txt 파일로 만들어 놓고, 이 파일을 읽어서 패키지 목록을 설치할 수 있다.

$ pip3 install -r requirements.txt

파이썬 소스코드는 항상 reauirements.txt 파일을 제공한다.

개발 완료 후, 코드를 배포하기 전에 freeze 해서 requirements.txt 파일을 생성해야,

이후 사용하는 사람이 어떤 패키지의 어떤 버전을 사용했는지 알고 대응할 수 있다.

 

 

 

✔️ Flask App으로 Docker 이미지 만들기

앞서 생성한flask app을 이용하여 진행해보자

Dockerfile

FROM python:3.9-slim-buster
COPY . /app
WORKDIR /app
RUN python3 -m venv venv && . venv/bin/activate 
RUN pip3 install -r requirements.txt
ENTRYPOINT ["python3", "-m", "flask", "run"]
CMD ["--host=0.0.0.0"]

⭐참고 사항

RUN 작성 시, ; 로 명령들을 나열하는 것도 가능하나

AND 연산의 && 또는 OR 연산의 || 를 사용하는 것도 가능하다.

A ; B 가 A실행 여부와 관계없이 B가 실행되는 반면에,

A && B 의 경우 A 가 성공해야만 B 가 실행되고, A || BA 가 실패해야만 B 가 실행된다.

 

.dockerignore

venv/
Dockerfile
.dockerignore
$ docker build -t myflask .

.dockerfile 이 제대로 작용했는지 확인하기 위해 빌드한 이미지로 컨테이너를 생성해서 복사된 파일 목록을 확인해보자

$ docker run -it myflask bash
root@3af01fa6732b:/# ls app/
__pycache__  hello.py  requirements.txt  templates

이미지 myflaskdocker run 해보자

$ docker run -d -p 80:5000 myflask 
b54715c7057143a8d90676be1b48e5e252c6f1233340f1b9ec2991cca5c5df9d
$ docker ps                       
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
b54715c70571   myflask   "python3 -m flask ru…"   5 seconds ago   Up 4 seconds   0.0.0.0:80->5000/tcp, :::80->5000/tcp   condescending_cohen

 

접속 확인

 

 

728x90