데이터센터프로그래밍18(2)

서유리·2022년 5월 12일
1
post-thumbnail

18-실습) 서로 다른 docker image를 2개 이상 만들고 통신주고받기

🟣 서로 다른 docker image를 2개 이상 만듦

  • "09-실습)도커파일과 도커이미지 생성"에서 했던 DOCKER FILE과 더불어 다른 DOCKER FILE도 만들었습니다.
  • DB serverDOCKER FILE의 code
FROM ubuntu:18.04
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install mysql-server -y
RUN apt-get install vim -y
EXPOSE 3306
  • Web serverDOCKER FILE의 code
FROM ubuntu:18.04
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install mysql-client -y
RUN apt-get install vim -y
RUN apt-get install -y python3-pip python3-dev
RUN pip3 install --upgrade pip
RUN pip3 install pymysql
RUN pip3 install fastapi uvicorn
RUN pip3 install python-multipart
RUN apt-get install -y python3-jinja2
COPY content/. /home/
EXPOSE 80
CMD cd /home && export LC_ALL=C.UTF-8 && python3 -m uvicorn main:app --reload --host=0.0.0.0 --port=80

🟣 서로 다른 image 간에 통신을 하여 무언가를 주고 받음

  • 서로 다른 image 간에 통신을 하기 위해 작성한 code(power-shell 사용)
  • database
# 파일이 있는 경로에 cd함
cd C:\Users\yuri\Desktop
# docker build -t [이미지이름]
docker build -t yuri0329/yuricontainer2:1.0 .
# docker run -itd --name [컨테이너이름] yuri0329/yuricontainer2:1.0
docker run -itd --name yuridatabase yuri0329/yuricontainer2:1.0
# docker inspect
docker inspect bridge
# docker container exec -ti [컨테이너이름] /bin/bash
docker container exec -ti yuridatabase /bin/bash
#
vi /etc/mysql/mysql.conf.d/mysqld.cnf
# 
:wq
# 
service mysql start
#
mysql -u root -p
# password 입력 : --> ubuntu
# CREATE USER '[MYSQL ID]'@'%' IDENTIFIED BY '[MYSQL_PASSWD]';
CREATE USER 'yuri95'@'%' IDENTIFIED BY 'dbfl#####';
# CREATE DATABASE IF NOT EXISTS [MYSQL_DATABASE이름];
CREATE DATABASE IF NOT EXISTS yuridatabase;
# GRANT ALL PRIVILEGES ON [MYSQL_DATABASE이름].* TO '[MYSQL ID]'@'%';
GRANT ALL PRIVILEGES ON yuridatabase.* TO 'yuri95'@'%';
#
quit
#
mysql -h ###.##.#.# -u yuri95 -p
#
quit
#
exit
  • docker container 1개 추가
# docker build -t [이미지이름] .
docker build -t yuri0329/yuricontainer3:1.0 
# docker run --name [컨테이너이름] -d -p 80:80 yuri0329/yuricontainer3:1.0
docker run --name yuriweb -d -p 80:80 yuri0329/yuricontainer3:1.0
  • docker image push
# container1
docker push yuri0329/yuricontainer2:1.0
# container2
docker push yuri0329/yuricontainer3:1.0

🟣 Main.py

  • database는 통신하기 위한 준비이고, main.py에서 직접적인 통신이 이루어짐
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import pymysql
#------------------------------- 사전 정의부분
host = '172.17.0.2'       # docker inspect bridge 로 컨테이너 IP주소 확인
user_id = 'yuri95'        # maria DB 사용자 id
user_pw = 'dbfl#####'    # maria DB 사용자 PW
user_name = 'yuri'       # maria DB 사용자 테이블에 저장할 사용자이름
db_name = 'yuridatabase' # maria DB 사용할 데이터베이스명
#--------------------------------------------
# Database 초기화
def init_database():
  # pymysql 모듈을 이용하여 Database서버의 mariaDB에 접근 (mariaDB 포트 3306)
  db = pymysql.connect(host=host, port=3306, user=user_id, passwd=user_pw, db=db_name, charset='utf8')
  #DB과 통신하기위해 사용하는 cursor
  cursor = db.cursor()
  #테이블이 존재하면 무시, 존재하지 않으면 CUSTOMER라는 이름으로 테이블 생성 (ID, PASSWS, USER_NAME) 컬럼을 가짐
  create_table ='''
  CREATE TABLE IF NOT EXISTS CUSTOMER (
          ID VARCHAR(20) NOT NULL,
          PASSWD VARCHAR(20) NOT NULL,
          USER_NAME VARCHAR(20) NOT NULL
      );
  '''
  # create_table에 문자열로 입력한 SQL명령을 cursor로 DB에 보내서 실행
  cursor.execute(create_table)
  # 테이블에 이미 들어가있다면 무시, CUSTOMER테이블에 사전에 정의한 user_id, user_pw, user_name을 테이블에 입력
  insert_data='''
  INSERT IGNORE INTO CUSTOMER(ID, PASSWD, USER_NAME)
  VALUES (\'{user_id}\', \'{user_pw}\', \'{user_name}\');
  '''
  #문자열로 입력한 SQL명령을 cursor로 DB에 보내서 실행
  cursor.execute(insert_data)
  #변경된 DB상태 저장
  db.commit()
  #DB연결해제
  db.close()
# ID와 PASSWD
def SearchID(ID, PASSWD):
    db = pymysql.connect(host=host, port=3306, user=user_id, passwd=user_pw, db=db_name, charset='utf8')
    cursor = db.cursor()
    #로그인 성공, 실패 정보를 전달하기위한 표시
    flag = False  
    #문자열로 테이블에서 ID와 PW가 같은 정보 검색하는 SQL명령어를 문자열로 저장
    search_table_right ="SELECT * FROM CUSTOMER WHERE ID=\'{ID}\' AND PASSWD=\'{PASSWD}\';".format(ID=ID, PASSWD=PASSWD)
    cursor.execute(search_table_right)
    #SQL명령어 실행 후, DB에서 나온 결과를 row에 저장
    row = cursor.fetchone()
    # row에 아무것도 없으면 => ID와 PASSWD가 일치하는게 없으면
    if row == None:
            flag = False
            row=('0', '0', '0')
    # ID와 PASSWD가 일치하는 정보가 있어서 로그인 성공이라면
    else:
            flag = True
    db.close()
    # 실패하면 [False, 0, 0, 0], 성공하면 [True, ID, PASSWD, USER_NAME] 반환
    return [flag, row[0], row[1], row[2]]   
#Database 초기설정
init_database()
app = FastAPI()
# image, css들어가있는 static 디렉토리 마운트
app.mount("/static", StaticFiles(directory="static"), name="static")
# html을 읽어주는 Jinja2에 html들어있는 templates 디렉토리를 지정 
templates = Jinja2Templates(directory="templates")
# 메인화면, index.html 띄워줌
@app.get("/")
async def read_root(request: Request):
        return templates.TemplateResponse("index.html", {"request": request})
# 로그인 버튼 눌렀을 때, ID와 PASSWD정보가 들어옴
@app.post("/login")
async def login(request:Request, ID: str=Form(...), PASSWD: str=Form(...)):
   # Database에서 ID와 PASSWD를 검색
    result = SearchID(ID, PASSWD)
   print(ID, PASSWD)
    # 정보가 없을 떄, 로그인 실패, 메인페이지(index.html)로 돌아감
   if not result[0] :return templates.TemplateResponse("index.html", {"request": request})
    # 정보가 있을 떄, 로그인 성공, 로그인성공페이지(login.html)와 USER_NAME반환
   else :return templates.TemplateResponse("login.html", {"request": request, "USER_NAME":result[3]})

🟣 http://localhost/ --> 화면결과 (1)

  • 로그인 전의 모습
  • 정보를 받은 후 로그인 후의 모습

🟣 만든 docker image들을 docker Hub에 업로드한 결과

  • docker hub 홈페이지에서 로그인 후, create repository에 들어가서 yuricontainer2, yuricontainer3라는 이름으로 만들었다.
  • 만든 결과

🟣 docker image 확인

🐷 정리를 하자면...

  • Fast API는 nginx, django와 같은 웹서버로, 파이썬 기반임
  • django가 아닌, Fast API를 선택한 이유는? : 도커 컨테이너 간의 통신을 빠르게 실습하기 위해서 사용하였고, 이를 통해 html동작과 파이썬 코드로 데이터베이스서버와 통신을 실습하였음
  • fastapi를 구동할때 main.py에서 DB서버의 테이블을 세팅 (없다면 생성 및 초기화), 실습을 위해 기본 계정 생성을 진행함
  • 웹에서 post방식으로 아이디와 비밀번호가 들어오면 데이터베이스에서 select문으로 검색해서 확인
  • 맞다면, 유저이름과 로그인페이지 반환, 다르다면 초기화면 반환함
  • Django와 fastapi 차이점에 대한 참고링크: https://tech.toktokhan.dev/2021/06/28/python-web-framework/
profile
best of best

0개의 댓글

관련 채용 정보