본문 바로가기

Docker

docker compose 로 springboot + react + mysql(mariadb) 3tier 컨테이너 연동 및 실행하기

728x90
반응형
SMALL

안녕하세요.

 

도커 컴포즈에 대해 이해하기에 가장 좋은 예시인 3tier 로 컨테이너를 개별적으로 띄운 뒤 연동을 해볼게요.

 

 

[3tier Info]

 

Front : react

 

Backend : springboot

 

database : mysql(mariadb)

 

 

docker-3-tier 폴더 안에 아래 해당하는 폴더를 만들어 줄게요.

 

1. docker-compose.yml

2. frontend

3. backend

4. mariadb

 

폴더 이름처럼 frontend 에는 프론트쪽 소스코드를

                      backend 에는 서버쪽 소스코드를

                      mariadb  에는 db 관련 데이터를

 

관리해줄게요.

 

 

먼저 backend 에  member 테이블에 있는 모든 데이터를 반환해주는 api 를 만들어 줄게요.

@RestController
@RequiredArgsConstructor
@CrossOrigin("*")
public class TestController {

    private final MemberRepository memberRepository;

    @GetMapping("/test")
    public List<Member> getMember(){
        return memberRepository.findAll();
    }
}

 

그리고 해당 프로젝트 최상단 디렉토리에서 Dockerfile을 만들어 줄게요.

 

 

여기서 Dockerfile을 왜 만들어야 되는지 모르는 분들을 위해 간단하게 설명을 해드릴게요.

 

도커는 기본적으로 이미지가 있어야 컨테이너를 생성하고 동작시킬수 있어서,  dockerfile은 필요한 최소한의 패키지를 설치하고 동작하기 위한 자신만의 설정을 담은 파일이고, 이 파일로 이미지를 생성(빌드)하게 됩니다.

 

결론만 말씀드리면, 자신만의 설정을 해주기위해 만들어주는거에요 (예를 들어 프로젝트배포를 위해선 프로젝트를 빌드해서 jar로 만들어주는 과정이 필요.)

 

FROM => 빌드하는 이미지와 기반 이미지를 지정

ARG => docker image build를 실행할때 사용하는 변수

COPY => 호스트에서 컨테이너로 파일 및 디렉토리를 복사

ENTRYPOINT => 컨테이너를 실행 가능 파일로 사용할 때 정의하는 명령. CMD와 ENTRYPOINT를 함께 사용할 수 있다. 

 

정리하면 amazoncorretto:17 이미지를 docker hub으로부터 다운받고 JAR_PATH 라는 이름의변수에 ./build/libs 값을 설정해주고,

./build/libs/*.jar 모든 파일을 현재 디렉토리에 카피하겠다. 또한 java jar 명령어를 돌리겠다. 라는 뜻입니다.

 

 Dockerfile 이 제대로 동작하는 지 확인 해볼까요?

 

해당 디렉토리에서 아래 명령어를 입력해보세요.

docker build -t 원하는이미지명 .

저는 docker build -t test . 명령어 입력을 했더니,

 

이렇게 test 라는 이미지가 빌드 된것을 볼 수 있어요.

 

이제 front 에 해당 api 주소로 요청해서 값을 받는 화면을 만들어볼게요.

import React, { useState, useEffect } from 'react';
import axios from 'axios';
const Api = () => {
const [data, setData] = useState([]);
// console.log("data",Response.data);



useEffect(() => {
const res = () => axios.get('http://localhost:8080/test')
.then((Response) => {
setData(Response.data)
})
.catch((Error) => { console.log(Error) })
res()
}, [])
return data.length > 0 ? (
<>
{
data.map((key, idx)=>(
<p key={idx}>
{key.name} / {key.address} / {key.age}
</p>
))
}
</>
) : <></>;
}
export default Api

여기도 동일하게, 해당 디렉토리에 Dockerfile을 만들어줍시다.

위에 설명한 것처럼, node 라는 이미지를 다운받아오고,

현재 디렉토리에서 현재 디렉토리로 컨테이너 카피를 한 후 npm install 해준다음에 npm run start를 해라 라는 뜻입니다.

 

docker build -t 원하는이미지명 .

이 Dockerfile 도 정상작동 하는지 확인 해볼게요.

저는 docker build -t test2 . 명령어를 사용했습니다.

 

아까 만들었던 test 이미지 위에 test2 이미지가 빌드 된것을 확인할수있어요.

 

이제 다 삭제를 하고, (삭제 명령어 docker rmi 이미지명)

 

 

제일 중요한 docker-compose.yml 를 작성해볼게요.

version: '3.8'

services:
  database:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 3025
      MYSQL_DATABASE: test
    ports:
      - 3306:3306
    volumes:
      - ./mariadb/data:/var/lib/mysql
      - ./mariadb/conf.d:/etc/mysql/conf.d
      - ./mariadb/db/initdb.d:/docker-entrypoint-initdb.d
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    restart: always
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://database:3306/test?useSSL=false&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 3025
    ports:
      - 8080:8080
    depends_on:
      - database
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    restart: always
    ports:
      - 3000:3000
    depends_on:
      - backend

전체 코드는 이거지만, 하나하나 분리해서 살펴봅시다.

 

 database:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 3025
      MYSQL_DATABASE: test
    ports:
      - 3306:3306
    volumes:
      - ./mariadb/data:/var/lib/mysql
      - ./mariadb/conf.d:/etc/mysql/conf.d
      - ./mariadb/db/initdb.d:/docker-entrypoint-initdb.d

먼저 데이터베이스를 구성하는 이미지 관련 설정파일입니다.

 

database 라는 이미지명을 설정하고

image : mysql 이라는 것을 docker hub로 부터 가져옵니다.

environment 로 환경변수 세팅을 하고 

ports 로 호스트와 컨테이너 간 포트포워딩을 해주고

volumes 설정을 해줬습니다.

마지막으로 restart : always 는 해당 설정이 오류가나면 다시 실행해라 라는 뜻입니다.

 

 backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    restart: always
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://database:3306/test?useSSL=false&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 3025
    ports:
      - 8080:8080
    depends_on:
      - database

backend 라는 이미지명을 설정해주고,

context로 해당 디렉토리로 이동하며

아까 설정해줬던 dockerfile 을 실행하고,

enviroment로 환경변수 세팅을 해줍니다.(데이터베이스 연결)

ports 로 포트포워딩을 하며

depends_on 을 하게 되면 database가 연결이 완료되고나서 실행해라 라는 뜻이 됩니다.

 

frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    restart: always
    ports:
      - 3000:3000
    depends_on:
      - backend

frontend 라는 이미지명을 설정해주고,

context로 해당 디렉토리로 이동하며,

마찬가지로 아까 설정해줬던 dockerfile 을 실행하고,

ports 로 포트포워딩 후

depends_on 으로 backend 이미지가 먼저 실행되고 나서 실행해라 라고 설정을 해줍니다.

 

 

이렇게 다 설정이 되었다면,

 

명령어 하나로 front, backend, database 이 3 tier가 서로 종속을 받으며 실행이 됩니다.

 

docker compose up --build

 

한번 해볼께요. (docker-compose.yml 이 들어있는 경로에서 위에 명령어를 입력하셔야 해요.  빌드하는데 시간이 조금 소요될 수 있습니다^^)

 

일단 정상적으로 이미지 빌드를 해왔네용

 

프론트에서 지정한 포트 3000번 이니까.

 

http://localhost:3000 으로 들어가 봅시다.

 

김영재 /서울 /28 데이터가 나오네요.

 

 

 

도커 컨테이너 내부 mysql 로 접속한 후 데이터를 확인해볼게요.

 

컨테이너 내부 접속 명령어 입니다.

docker exec -it 컨테이너ID /bin/bash

위에 명령어를 입력해  컨테이너 내부에 들어온 후

mysql -u root -p

비밀번호 입력후

데이터를 확인해보면 됩니다.

 

 

이상으로 docker compose 로 3tier 분리된 컨테이너를 서로 연동하여 서버에 띄어보았습니다.

 

감사합니다.

 

 

728x90
반응형
LIST