도커로 mysql 띄워보자!

노요셉·2020년 8월 26일
6

포스트 목적: 스프링 부트와 AWS로 혼자 구현하는 웹 서비스에서 사용할 DB를 설치해야해요. 그런데 간편하게 설치하고 간편하게 지우는 도커를 이용해서 DB를 설치하고, 실행해보고 스프링부트와 연동해봅니다.

스프링 프로젝트는 그냥 host에서 띄웁니다!

MYSQL부터

도커 설치부터!

https://dc7303.github.io/docker/2019/11/24/dockerInstallForMac/

brew cask로 설치할 것!
$ brew cask install docker

docker 버전확인

docker --version

docker-compose

yaml(설정파일)로 여기에 도커 컨테이너를 정의하고 작동시키고~ 관리하는 툴이랍니다.

docker-compose는 docker랑 달라요. 도커 설치 부분에서 brew cask 로 설치했다면 docker-compose가 설치되어있을겁니다.

설치확인

docker-compose version

이제 docker-compose.yaml이란 이름을 만들어요.

결국 이런식으로 만들건데

version: "3.7" # 파일 규격 버전
services: # 이 항목 밑에 실행하려는 컨테이너 들을 정의 ( 컴포즈에서 컨테이너 : 서비스 )
  db: # 서비스 명
    image: mysql:5.7 # 사용할 이미지
    restart: always
    command: --lower_case_table_names=1
    container_name: mysql-test # 컨테이너 이름 설정
    ports:
      - "3307:3306" # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)  <- 컨테이너 내부는 무조건 3306
    environment: # -e 옵션
      - MYSQL_DATABASE=database이름넣음
      - MYSQL_ROOT_PASSWORD=password넣음  # MYSQL 패스워드 설정 옵션
      - TZ=Asia/Seoul

    command: # 명령어 실행
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - /Users/Shared/data/mysql-test:/var/lib/mysql # -v 옵션 (다렉토리 마운트 설정)

version??
. 파일의 규격에 따라 지원하는 옵션이 달라지는데,
"3"이라만 적으면 3으로 시작하는 최신 버전을 사용한다는 의미입니다. (파일 규격 버전에 따른 자세한 내용은 compose 파일의 버전과 호환성을 안내한 공식 문서를 참고하세요.)

출처 : https://www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose

참고 : postgresql https://evergrow.tistory.com/42

레퍼런스 :

docker-compose 명령어 - https://mycup.tistory.com/264

postgres docker-compose.yml

# https://evergrow.tistory.com/42
# https://gist.github.com/tingwei628/8584ddefc5d8e85f73566d5ab96bdc84
# https://towardsdatascience.com/how-to-run-postgresql-and-pgadmin-using-docker-3a6a8ae918b5

version: "3"
services:
  postgres:
    image: postgres:10
    container_name: nest_clone_benaward_postgres
    environment:
      POSTGRES_PASSWORD: toor
      POSTGRES_USER: root
      POSTGRES_DBNAME: test_db
    ports:
      - "5432:5432"
    volumes:
      - /Users/Shared/data/nest_clone_benaward_postgres:/var/lib/pgadmin # -v 옵션 (다렉토리 마운트 설정)

  pgadmin:
    container_name: pgadmin4_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: 1234@admin.com
      PGADMIN_DEFAULT_PASSWORD: 1234
    ports:
      - "5050:80"

docker로 pgadmin(mysql workbench)랑 postgres add server 하는데 refuse 어쩌구 나오면 이렇게 해결해버림.
https://stackoverflow.com/questions/53610385/docker-postgres-and-pgadmin-4-connection-refused

mysql workbench 설치

brew install --cask mysqlworkbench
https://formulae.brew.sh/cask/mysqlworkbench

도커 mysql 컨테이너에 샘플 데이터 넣기

docker ps -> 실행중인 컨테이너 조회

실행중인 컨테이너 터미널 열기
docker exec -it containerID /bin/bash

호스트 (mac)에 있는 샘플.sql을 도커 컨테이너 (this_is_mysql)에 넣기
docker cp employees/ this_is_mysql:/

mac에서 employee 디렉토리가 하위 디렉토리로 있는 현재 디렉토리에서 터미널을 켰어요.
docker cp 명령어로 파일을 복사할거에요. 여기선 디렉토리죠.
this_is_mysql은 도커 컨테이너의 이름이에요 저렇게 지었고
: 콜론 다음에 붙여넣을 경로를 넣어주세요.

명령어를 풀어서 쓰면~

docker cp employees/ this_is_mysql:/
docker exec -it 469f852b29c6 /bin/bash
root@469f852b29c6:/# ls
bin  boot  dev	docker-entrypoint-initdb.d  employees  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@469f852b29c6:/# cd employees/
root@469f852b29c6:/employees# mysql -u root -p
mysql> source employees.sql

volumes : docker run으로 db 컨테이너를 실행할 때 --volumn 옵션을 사용하여 데이터베이스의 데이터를 로컬컴퓨터에 저장했던 부분과 같음. 상대경로 지정이 가능하다네요.

environment : docker run 명령어의 -e 옵션에 적었던 내용들입니다.

ports : docker run 명령어의 -p 옵션에 해당하는 부분입니다.
컨테이너 외부라면 host 운영체제에서 사용하는 port고 container에서 사용할 port에요.
예를 들어, 3306은 mysql 기본포트라서 기존 host( 컴퓨터 )에 mysql을 설치했다면 docker compose로
mysql 컨테이너를 만들어도 포트가 충돌나서 안돼요. 그래서 외부포트를 임의로 정해주고 내부에서는 mysql포트를 3306에서 쓰겠다는 것입니다.

command : docker run으로 앱 컨테이너를 실행할 때 가장 마지막에 적었던 명령어 부분입니다.

도커 명령어

도커-컴포즈로 mysql 컨테이너를 만들 준비를 했으니, 이미지를 빌드하고, 컨테이너를 실행해봅시다.

docker-compose.yaml, yml 파일이 있는 디렉토리에서 터미널로 실행합니다!

docker-compose up -d
백그라운드로 실행합니다.

잘 실행되고 있는지 확인해봅니다.

docker-compose ps

멈추거나, 멈춰있는걸 실행할 줄 알아야죠.

docker-compose stop
docker-compose start

컨테이너: (컴포즈에서는 서비스)를 제거해봅니다.

docker-compose down

--volumn : 볼륨까지 지웁니다. ( 파일로 저장되있는 것까지 다 제거 해버린다는 것 같아요. )

실행중인 컨테이너(서비스)에서 명령어를 실행할 수도 있어요.

docker-compose exec node npm run test

서비스중인 컨테이너(서비스) 로그를 확인할 수 있습니다.

docker-compose logs <서비스이름>

스프링부트와 MYSQL 연동!

springboot 프로젝트 루트 디렉토리에 application.properties파일을 만들고 다음과 같이 작성합니다.

spring.datasource.url=jdbc:mysql://데이터베이스가존재하는IP:PORT/test_db?useSSL=false
spring.datasource.username=root
spring.datasource.password=패스워드
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
# DDL 정의시 데이터베이스의 고유 기능을 사용합니다.
spring.jpa.generate-ddl=true
# API 호출시, SQL 문을 콘솔에 출력한다.
spring.jpa.show-sql=true

여기서 특별한 부분은 datasource url로 ip 대신 서비스명을 줄 수 있는겁니다.
이는 docker-compose.yml에 써놓은 mysql의 서비스명과 동일한데,
이는 docker-compose.yml 내에 작성한 컨테이너들은 모두 같은 네트워크 대역으로 묶어서 생성하기 때문이라네요.

행여나 다음과 같은 에러가 난다!

mysql-springboot2 | 2020-08-27T12:57:49.186375Z 0 [ERROR] InnoDB: Unable to lock ./ibdata1 error: 11
mysql-springboot2 | 2020-08-27T12:57:49.186454Z 0 [Note] InnoDB: Check that you do not already have another mysqld process using the same InnoDB data or log files.

docker-compose에 volumns을 체크해보세요 이미 있는 volumns에 다른 서비스를 올리려고하면 이런 에러 뜹니다.

docker container 동작하는데 shell로 container 들어가서 확인하기

사실 ec2에 pm2로 node 프로그램, jar 로 java프로그램 실행하듯이, docker로 mysql 올리는거잖아요.
그러면 ec2( 외부 컴퓨터 ) shell 정도는 당연히 지원해주는 플랫폼이기 때문에 ec2에 인스턴스 ssh로 접근하듯이 docker도

root@~~# docker exec -it  <container 식별자 (숫자랑 abc섞여있는거> /bin/bash ( shell중 하나)
# docker exec -it  c456623003b1 /bin/bash

출처: https://bluese05.tistory.com/21 [ㅍㅍㅋㄷ]

docker-compose mysql 대소문자 구분

command: 에 --lower_case_table=names=1 추가해주기

version: "3.7" # 파일 규격 버전
services: # 이 항목 밑에 실행하려는 컨테이너 들을 정의 ( 컴포즈에서 컨테이너 : 서비스 )
  db: # 서비스 명
    image: mysql:5.7 # 사용할 이미지
    restart: always
    command: --lower_case_table_names=1 <----------
    container_name: mysql-test # 컨테이너 이름 설정
    ports:
      - "3307:3306" # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)  <- 컨테이너 내부는 무조건 3306
    environment: # -e 옵션
      - MYSQL_DATABASE=database이름넣음
      - MYSQL_ROOT_PASSWORD=password넣음  # MYSQL 패스워드 설정 옵션
      - TZ=Asia/Seoul

    command: # 명령어 실행
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - /Users/Shared/data/mysql-test:/var/lib/mysql # -v 옵션 (다렉토리 마운트 설정)

https://stackoverflow.com/questions/50483006/docker-mysql5-6-unknown-variable-lower-case-table-names-1

레퍼런스

도커 mysql 띄우는 것
https://joont92.github.io/docker/docker-compose%EB%A1%9C-nginx-spring-boot-mysql-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0/

도커 용어 이해
https://medium.com/withj-kr/docker-%EB%B6%80%ED%84%B0-kubernetes-%EA%B9%8C%EC%A7%80-5-docker-compose-%EC%9E%85%EB%AC%B8-ece1a6721775

docker-compose.yaml 파일
https://www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose#docker-compose.yml-%ED%8C%8C%EC%9D%BC

docker ports
https://blog.naver.com/alice_k106/220278762795

docker container에 접속하기
https://bluese05.tistory.com/21


Dockerfile

출처 : https://javacan.tistory.com/entry/docker-start-7-create-image-using-dockerfile

주요 명령어: FROM, WORKDIR, COPY, RUN, EXPOSE, CMD

FROM openjdk:8-jdk-alpine

RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime

WORKDIR /app
COPY hello.jar hello.jar
COPY entrypoint.sh run.sh
RUN chmod 774 run.sh

ENV PROFILE=local

ENTRYPOINT ["./run.sh"]

FROM : 이미지를 생성할 때 사용할 기반 이미지를 지정한다. 예제에서는 openjdk:8-jdk-alpine 이미지를 사용했다. 이 이미지는 알파인 OS에 JDK 8을 설치한 이미지이다.

RUN : 이미지를 생성할 때 실행할 코드를 지정한다. 예제에서는 패키지를 설치하고 파일 권한을 변경하기 위해 RUN을 사용했다.

WORKDIR : 작업 디렉토리를 지정한다. 해당 디렉토리가 없으면 새로 생성한다. 작업 디렉토리를 지정하면 그 이후 명령어는 해당 디렉토리를 기준으로 동작한다.

COPY : 파일이나 폴더를 이미지에 복사한다. 위 코드에서 두 번째 COPY 메서드는 entrypoint.sh 파일을 이미지에 run.sh 이름으로 복사한다. 상대 경로를 사용할 경우 WORKDIR로 지정한 디렉토리를 기준으로 복사한다.

레퍼런스:

도커파일 멸령어 설명 - https://javacan.tistory.com/entry/docker-start-7-create-image-using-dockerfile

profile
서로 아는 것들을 공유해요~

0개의 댓글