Flask로 Web App을 개발을 하고 데이터베이스(MariaDB)와 연동을 하는 방법을 알아본다. CURL을 사용 하여 기본적인 REST API(HTTP methods: GET, POST, DELETE)를 테스트 해본다.
* test-net
=> Docker Container는 격리된 환경에서 실행되기 때문에 다른 컨테이너와 통신이 불가능
이 때, network를 통해 여러개의 컨테이너를 연결시켜 통신이 가능하게 할 수 있음
1) MariaDB image를 생성 (내부데이터 有)
FROM mariadb:latest
# mariadb:latest를 기반 이미지로 이미지 생성
ENV MYSQL_ROOT_PASSWORD=189756
# DB의 비밀번호 설정
ENV MYSQL_DATABASE=alswkdrb
# DB의 이름 설정
COPY *.sql /docker-entrypoint-initdb.d/
# 디렉토리의 모든 .sql파일을 docker-entrypoint-initdb.d 파일에 복사
* Docker image가 실행 시에 docker-entrypoint-initdb.d에 있는 sql 스크립트 파일을 읽어 데이터베이스에 저장
CREATE TABLE IF NOT EXISTS `cloud_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(45) DEFAULT NULL,
`user_email` varchar(45) DEFAULT NULL,
`user_bio` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ;
INSERT INTO `cloud_user` (
`user_id`,`user_name`,`user_email`, `user_bio`)
values
(1,'jk M','alswkdrb1@gmail.com', 'student');
* NOT NULL : 공백 비허용
DEFAULT NULL : 공백 허용
AUTO_INCREMENT=2 : 2부터 1씩 증가하는 값
$ docker build -t alswkdrb1/box1:mariadb_v2 .
=> mariadb image 생성
2) Mariadb container 생성
$ docker run -p 3306:3306 --net test-net --name my-mariadb -d alswkdrb1/box1:mariadb_v2
=> 직전에 생성한 image를 포트 = 외부 3306 : 내부 3306, network = test-net, 이름 = my-mariadb 로
detach모드로 실행
3) Flask 이미지 만들기 + Flask Container와 Mariadb container 연동하여 DB읽고 쓰기
3-1) main.py
#main.py
# third-party imports
import pymysql
from flask import jsonify, render_template, request, redirect
# local imports
from app import app
from models import Results
from db_config import mysql
# route
@app.route('/')
def index_page():
return render_template('index.html')
@app.route('/user', methods=['GET'])
def users():
conn = None
cursor = None
try:
conn = mysql.connect()
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT * FROM cloud_user")
rows = cursor.fetchall()
res = jsonify(rows)
res.state_code = 200
return res
# table = Results(rows)
# table.border = True
# return render_template('users.html', table=table)
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
@app.route('/add', methods=['POST'])
def add_user():
conn = None
cursor = None
try:
if request.is_json:
req = request.get_json()
_name = req['name']
_email = req['email']
_bio = req['bio']
if _name and _email and request.method == 'POST':
sql = "INSERT INTO cloud_user(user_name, user_email, user_bio) VALUES(%s, %s, %s)"
data = (_name, _email, _bio,)
conn = mysql.connect()
cursor = conn.cursor()
cursor.execute(sql, data)
conn.commit()
return redirect('/user')
else:
return 'Error while adding user'
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
@app.route('/delete/<int:id>', methods=['DELETE'])
def delete_user(id):
conn = None
cursor = None
try:
conn = mysql.connect()
cursor = conn.cursor()
cursor.execute("DELETE FROM cloud_user WHERE user_id=%s", (id,))
conn.commit()
return redirect('/user')
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
@app.errorhandler(404)
def not_found(error=None):
message = {
'status': 404,
'message': 'Not Found: ' + request.url,
}
res = jsonify(message)
res.state_code = 404
return res
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
3-2) models.py
from flask_table import Table, Col
class Results(Table):
user_id = Col('Id')
user_name = Col('Name')
user_email = Col('Email')
user_bio = Col('Bio')
3-3) db_config.py
from app import app
from flaskext.mysql import MySQL
import os
mysql = MySQL()
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = os.environ['DB_USER']
app.config['MYSQL_DATABASE_PASSWORD'] = os.environ['DB_PASSWORD']
app.config['MYSQL_DATABASE_DB'] = os.environ['DB_NAME']
app.config['MYSQL_DATABASE_HOST'] = os.environ['DB_HOST']
mysql.init_app(app)
3-4) app.py
from flask import Flask
app = Flask(__name__)
app.secret_key = "secretkey"
3-5) requirements.txt
flask
pymysql
flask_table
flask-mysql
3-6) Dockerfile
FROM python:3.9.5-alpine
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
CMD ["python", "main.py"]
$ docker build -t alswkdrb1/box1:cloudflask_v1 .
=> flask 이미지 생성
$ docker run -p 5000:5000 --net test-net --env-file ./env.list alswkdrb1/box1:cloudflask_v1
=> 이전에 만든 flask이미지로 환경파일(env.list)을 읽어들이며 실행
# env.list
DB_USER=root
DB_PASSWORD=189756
DB_NAME=alswkdrb
DB_HOST=my-mariadb
4) Docker Compose
Docker Compose를 활용하면 여러개의 컨테이너를 손쉽게 구성하고 관리할 수 있다.
docker-compose.yml
version: "2"
services:
my-mariadb:
image: alswkdrb1/box1:mariadb_v2
ports:
- "3306:3306"
my-flask-app:
links:
- my-mariadb
image: alswkdrb1/box1:cloudflask_v2
ports:
- "5000:5000"
environment:
- DB_USER=root
- DB_PASSWORD=189756
- DB_NAME=alswkdrb
- DB_HOST=my-mariadb
$ docker-compose up -d
$ docker-compose down
'프로젝트' 카테고리의 다른 글
[동계 프로젝트] 전동킥보드 주행 중 헬멧 착용 여부 확인 프로그램 (0) | 2021.11.03 |
---|---|
[졸업 논문] 스마트 안전 장비 (0) | 2021.11.03 |
Application 배포 (By AWS EKS, Kubernetes) (0) | 2021.08.04 |
도커 컨테이너 구성 및 활용(1) (0) | 2021.08.02 |
Cloud 환경 구성 및 환경 설정 (0) | 2021.08.02 |
댓글