일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Data Structure
- 알고리듬
- django
- 코딩테스트
- Vue.js
- programmers
- GitHub
- CSV
- aws
- 모의SW역량테스트
- Trie
- DFS
- hash table
- gpdb
- 구현
- spring boot
- Linked list
- Back tracking
- BFS
- SQL
- 시뮬레이션
- boj
- Bruth Force
- Python
- Priority Queue
- 코테
- JavaScript
- Algorithm
- SWEA
- 알고리즘
- Today
- Total
hotamul의 개발 이야기
[Flask] Flask & Docker (Dockerfile 작성 방법) 본문
Django
를 잠깐 맛보기로 사용해보면서 왜 인기있는 framework인지 알 수 있었다. 빠르고 쉽게 개발할 수 있고 제공하는 기능들이 굉장히 편리했다.
때마침 현업에서 API 서버 개발이 필요하게 되어서 Django
를 이용해 micro service를 만들어보려고 했었다.
하지만 현업에서는 Greenplum DB를 사용중이였고 Django
와 Greenplum DB의 호환은 어려웠다. (table을 자동으로 생성할 때 index constraints 설정에서 에러가 있었고 생각보다 해결방법을 찾는것도, 커스터 마이징 하는 것도 쉽지 않았다.)
그래서 Flask
를 사용하게 되었다. (Flask
는 ORM을 선택적으로 사용할 수 있어 DB 호환 이슈도 해결할 수 있고 자유도 높게 내 입맛대로 만들 수 있었기 때문이다.)
매우 빠르고 가볍게 서버를 구성할 수 있었지만 docu가 Django
에 비해 많지 않다고 느껴져서 Flask
API 서버를 개발하며 생겼던 문제, 문제 해결 방법들을 개발 처음부터 차근 차근 기록해보고자 한다.
Docker 환경 만들기
github repository 생성, clone
먼저 github에 repository를 생성하고 (add README.md, add .gitignore) 내가 원하는 로컬 pc 디렉토리에 git clone 해주자.
.gitignore에서 Python을 선택해주면 아래 처럼 Python 프로젝트에 형상관리가 불필요한 항목들이 .gitignore 파일에 자동으로 작성되어 있다.
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
...
# Flask stuff:
instance/
...
docker, docker-compose 준비
Docker를 사용하기 위해서 Docker, docker-compose가 필요하다
❯ docker --version && docker-compose --version
Docker version 20.10.16, build aa7e414
docker-compose version 1.29.2, build 5becea4c
docker가 없다면 Docker Desktop을 다운로드 하면 된다.
Dockerfile 만들기
자 이제 Docker, docker-compose가 준비 되었으니 Dockerfile을 생성해보자.
FROM python:3.8-alpine3.13
LABEL maintainer="github.com/toughhyeok"
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /tmp/requirements.txt
COPY ./requirements.dev.txt /tmp/requirements.dev.txt
COPY ./app /app
WORKDIR /app
EXPOSE 8000
ARG DEV=false
RUN python -m venv /venv && \
/venv/bin/pip install --upgrade pip && \
apk add --update --no-cache postgresql-client && \
apk add --update --no-cache --virtual .tmp-build-deps \
build-base postgresql-dev musl-dev && \
/venv/bin/pip install -r /tmp/requirements.txt && \
if [ $DEV = "true" ]; then \
/venv/bin/pip install -r /tmp/requirements.dev.txt; \
fi && \
rm -rf /tmp && \
apk del .tmp-build-deps && \
adduser \
--disabled-password \
--no-create-home \
flask-user
ENV PATH="/venv/bin:$PATH"
USER flask-user
위에서 부터 설명하자면 FROM python:3.8-alpine3.13
Python 3.8-alpine3.13 버전을 사용하겠다는 뜻이다. Docker Hub에서 tag들을 확인해서 원하는 이미지를 사용하면 된다. alpine 버전은 작은 경량형 파이썬 도커 이미지를 뜻한다. 자세히 말하자면 알파인 리눅스 프로젝트 기반으로 만들어진 이미지라고 할 수 있다.
LABEL maintainer="github.com/toughhyeok"
는 관리자?개발자 contact 정보를 적어 둔 것이다. 나는 그냥 github url을 적었다. 예전에는 MAINTAINER 어쩌고
이렇게 사용했는데 해당 command는 deprecated 되었다고 한다.
ENV PYTHONUNBUFFERED 1
은 출력을 버퍼링하지 않는다는 command 이다. (참고: Python PYTHONUNBUFFERED option)
COPY ./requirements.txt /tmp/requirements.txt
COPY ./requirements.dev.txt /tmp/requirements.dev.txt
COPY ./app /app
현재 프로젝트에 requirements.txt
, requirements.dev.txt
를 docker service 내에 /tmp/ 위치로 COPY
하고 app 패키지 (파이썬에서 디렉토리를 패키지 개념으로 사용하므로 패키지라고 하겠다)를 docker service 내에 /app 위치로 COPY
한다.
WORKDIR /app
그리고 작업 폴더 flask run
, flake8
, pytest
등이 수행될 wokring directory를 /app으로 설정한다.
EXPOSE 8000
local pc가 docker service와 8000 포트로 통신한다.
RUN python -m venv ./venv && \
/venv/bin/pip install --upgrade pip && \
apk add --update --no-cache postgresql-client && \
apk add --update --no-cache --virtual .tmp-build-deps \
build-base postgresql-dev musl-dev && \
/venv/bin/pip install -r /tmp/requirements.txt && \
if [ $DEV = "true" ]; then \
/venv/bin/pip install -r /tmp/requirements.dev.txt; \
fi && \
rm -rf /tmp && \
apk del .tmp-build-deps && \
adduser \
--disabled-password \
--no-create-home \
flask-user
이제 Docker의 run script 이다. python -m venv /venv
먼저 가상환경을 /venv 위치에 생성한다.
/venv/bin/pip install --upgrade pip
패키지 매니저를 최신 버전으로 upgrade 한다.
apk add --update --no-cache postgresql-client
, apk add --update --no-cache --virtual .tmp-build-deps build-base postgresql-dev musl-dev
postgresql 사용하기 위한 설치.
/venv/bin/pip install -r /tmp/requirements.txt
requirements.txt에 작성된 패키지 목록들을 다운로드 한다. (Flask
, flask-restx
, flask-sqlalchemy
, ...)
if [ $DEV = "true" ]
이 부분은 실행환경이 DEV="true
이면 requirements.dev.txt에 작성된 개발용 패키지 목록들을 다운로드 하라는 제어문이다. (pytest
, flake8
, ...)
adduser --disabled-password --no-create-home flask-user
는 flask-user라는 user를 추가한다. (password와 user home directory는 생성하지 않는다)
docker build
이렇게 Dockerfile을 작성하고 docker build .
를 해보자.
에러가 발생한다면 COPY
command에서 requirements.txt, requirements.dev.txt, ./app 을 복사 하려고 하는데 없다는 에러가 나올 것이다.
아래와 같이 ./app, ./requirements.txt, ./requirements.dev.txt를 생성해준다.
requirements.txt와 requirements.dev.txt는 아래와 같이 작성해준다.
# requirements.txt
Flask>=2.1.3,<2.2
flask_restx>=0.5.1,<0.6
Werkzeug>=2.1.2,<2.2
Flask-SQLAlchemy>=2.5.1,<2.6
# requirements.dev.txt
flake8>=4.0.1,4.1
pytest>=7.1.2,<7.2
그리고 다시 docker build .
하면 정상적으로 실행됨을 확인할 수 있다.
다음은 docker-compose.yml 작성 방법, wait for db 스크립트 작성 방법이 궁금하다면 [Flask] Flask & docker-compose wait for db 포스트를 참고해라.