3 분 소요

이전 글에 이어서 진행해보자.

Docker Container

5. MySQL (MariaDB)

order-service에서 사용할 MariaDB를 컨테이너화 시켜보자.
(원래는 MariaDB를 사용하는데, 나는 에러가 발생해 MySQL을 사용할 것이다.)

1) init 데이터 생성

방법 1 과 방법 2 중 아무렇게나 해도 상관없다.
(나는 방법 2를 선택했다.)

[방법 1] 로컬 mysql에서 생성한 테이블 데이터를 옮기기

로컬에서 사용하던 DATABASE가 저장되어있는 위치로 이동한 뒤, 해당 데이터 파일들을 Dockerfile을 생성할 위치에 미리 복사해 두자!

MySQL에서 저장된 DATABASE의 경로를 확인하는 방법

이 글을 참고했다.
(보통 /usr/local/mysql/bin 위치에 있다는데 나는 없었다..ㅜㅜ)

$ mysql -u admin -p

# DATABASE 경로 확인
mysql> show variables like 'datadir';

스크린샷 2022-10-18 오전 12 37 09

스크린샷 2022-10-18 오전 12 34 19

스크린샷 2022-10-18 오전 12 38 15

이제 이 데이터들을 우리가 원하는 폴더로 옮겨보자.

# 폴더 생성
$ mkdir docker-files
$ cd docker-files

$ mkdir mysql-data
$ cd mysql-data

# mysql 데이터 copy
$ cp -R /opt/homebrew/var/mysql .

스크린샷 2022-10-18 오전 12 43 53

[방법 2] init 스크립트 생성

이 글을 참고했다.
깃 허브 주소는 여기이다.

Dockerfile이 있는 위치에 mysql-init-files 디렉토리를 생성한 뒤, 그 안에서 create.sql 파일을 생성한다.

create.sql

-- CREATE DATABASE mydb;

create table mydb.users(
    id int auto_increment primary key,
    user_id varchar(20),
    pwd varchar(20),
    name varchar(20),
    created_at datetime default NOW()
);

create table mydb.orders (
    id int auto_increment primary key,
    product_id varchar(20) not null,
    qty int default 0,
    unit_price int default 0,
    total_price int default 0,
    user_id varchar(50) not null,
    order_id varchar(50) not null,
    created_at datetime default NOW()
);

-- create masteruser and grant privileges
-- create user root'%' identified by '1234';
-- grant all privileges on *.* to root'%' identified by '1234';

2) Dockerfile을 통해 이미지 만들기

[방법 1] 선택

init 데이터를 생성할 때, [방법 1]을 선택했다면 아래와 같이 하자.
Dockerfile은 아까 복사해둔 mysql-data 디렉토리와 같은 위치에 생성하자.

FROM mariadb

ENV MYSQL_ROOT_PASSWORD 1234

ENV MYSQL_DATABASE mydb

COPY ./mysql-data/mysql /var/lib/mysql

EXPOSE 3306

ENTRYPOINT ["mysqld","--user=root"]

스크린샷 2022-10-18 오전 1 35 31

  • COPY ./mysql-data/mysql /var/lib/mysql
    - 데이터 베이스를 만들 때, 초기에 생성할 테이블 정보를 스크립트를 이용해 생성해도 괜찮지만,
    지금은 로컬 db에서 만들어둔 테이블을 컨테이너 안으로 복사하여 사용해볼 것이다.
    - 이 때, COPY ./mysql-data/mysql 자리에는 로컬에서 기동시킨 mariadb의 데이터들이 저장되어 있는 위치를 명시해주면 된다.

[방법 2] 선택

init 데이터를 생성할 때, [방법 2]를 선택했다면 아래와 같이 하자.
Dockerfile은 아까 생성한 mysql-init-files 디렉토리와 같은 위치에 생성하자.

FROM mysql

MAINTAINER minju412 <mj441@naver.com>

ADD ./mysql-init-files /docker-entrypoint-initdb.d

ENV MYSQL_ROOT_PASSWORD 1234
ENV MYSQL_DATABASE mydb

EXPOSE 3306

스크린샷 2022-10-18 오후 2 56 33
(mysql-data 디렉토리는 이전에 시도할 때 생성했던 것이므로 없어도 된다.)

패스워드는 1234로 지정해보자. (지금 새로 만드는 것!)

3) 이미지 빌드

# 이미지 파일 빌드
$ docker build -t ln8847/my_mysql:1.0 .

# 생성된 이미지 확인
$ docker images | grep my_mysql

만약 아래와 같은 오류가 발생한다면?

m1 Mac에서 이미지 빌드 시, 아래와 같은 에러가 발생할 수 있다.

failed to solve with frontend dockerfile.v0: failed to create LLB definition: no match for platform in manifest sha256:94176d0ad4ed85767fc0d74b8071387109a0390e7c1afd39788269c96d2dad74: not found

이 경우에는, --platform 옵션을 추가하자.

$ docker build --platform linux/x86_64 -t ln8847/my_mysql:1.0 .

스크린샷 2022-10-18 오후 2 43 51

4) 도커 컨테이너 실행

실행 전에 기존에 로컬에서 기동 중인 mysql이 있다면 먼저 중지하자! (포트가 겹치면 에러가 발생한다.)

# mysql 기동 중인지 확인
$ brew services list

# mysql 정지 (기동 중이라면..)
$ brew services stop mysql
# 컨테이너 실행
$ docker run -d -p 3306:3306 --network ecommerce-network \
--name mysql \
ln8847/my_mysql:1.0

# 로그 확인
$ docker logs mysql

196237367-6cb89f67-0e3a-4c4e-bf0e-c687b40fda0c

스크린샷 2022-10-18 오후 5 12 13

정상적으로 기동되었을 때 로그는 아래와 같다.
스크린샷 2022-10-18 오후 5 18 20

이전과 마찬가지로 네트워크를 확인해보자.

$ docker network inspect ecommerce-network

스크린샷 2022-10-18 오후 5 13 08

만약 Dockerfile을 수정하고 싶다면?

Dockerfile을 수정한 뒤에,
아래 순서대로 다시 도커 컨테이너를 기동하자.

# 기존 컨테이너 중지
$ docker stop mysql

# 실행중이지 않은 컨테이너 및 네트워크, 캐시 삭제
$ docker system prune

# 이미지 빌드
$ docker build -t ln8847/my_mysql:1.0 .

# 컨테이너 실행
$ docker run -d -p 3306:3306 --network ecommerce-network \
--name mysql \
ln8847/my_mysql:1.0

실행을 확인해보고, 정상적으로 기동되지 않았다면 로그까지 확인해보자.

$ docker ps -a

$ docker logs mysql

5) db 접속 후 테이블 확인 및 권한 설정

mysql 컨테이너 내부에 접속한 뒤,
mydb 라는 데이터베이스에 접속해 usersorders 테이블이 만들어져 있는지 확인해보자.
그리고 mysql의 root 계정이 어떠한 IP Address로 접속한다 하더라도 접속 가능하도록 권한을 설정해보자.

$ docker exec -it mysql /bin/bash

bash-4.4# mysql -h127.0.0.1 -uroot -p
# 패스워드는 아까 지정한대로 1234 입력

# 데이터 베이스 확인
mysql> show databases;

mysql> use mydb;

# 테이블 확인
mysql> show tables;

아래와 같이 두 개의 테이블이 생성되어 있는 것을 확인할 수 있다.
스크린샷 2022-10-18 오후 5 35 55

이제 권한을 설정하자.

# 권한 부여
mysql> grant all privileges on *.* to 'root'@'%';

# 적용
mysql> flush privileges;

# 권한 확인
mysql> show grants for 'root'@'%';

root 라는 계정의 어떤 IP Address로 접속하더라도, 모든 데이터베이스에 접속 가능하도록 권한을 부여하는 커맨드이다.
스크린샷 2022-10-18 오후 5 43 13



💛 개인 공부 기록용 블로그입니다. 👻

맨 위로 이동하기