전체 방문자
오늘
어제
모달조아
Better than yesterday
모달조아
  • 분류 전체보기 (147)
    • PS (86)
      • BOJ (79)
      • 프로그래머스 (6)
    • 이론 (41)
      • 자료구조 (2)
      • 알고리즘 (8)
      • 데이터베이스 (1)
      • 운영체제 (1)
      • 네트워크 (3)
      • 디자인패턴 (7)
      • Java (13)
      • Spring (4)
      • JPA (1)
      • Git (1)
    • 개발 (18)
    • 프로젝트 (1)
    • 기록 (0)
      • 후기 (0)
    • etc (1)

최근 글

티스토리

hELLO · Designed By 정상우.
모달조아

Better than yesterday

Docker 에서 /docker-entrypoint-initdb.d 를 통한 초기화 시 인코딩 오류 문제 해결법
개발

Docker 에서 /docker-entrypoint-initdb.d 를 통한 초기화 시 인코딩 오류 문제 해결법

2023. 5. 1. 05:48
version: '3'
services:
  db:
    image: mysql:8.0.32
    ports:
      - "3306:3306"
    env_file:
      - ../env/docker-compose.env
    container_name: seat-view
    environment:
      TZ: Asia/Seoul
    volumes:
      - seat-view:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./stadium.sql:/docker-entrypoint-initdb.d/stadium.sql
    restart: always

volumes:
  seat-view:

위와 같이 docker-compose 를 이용하여 MySQL 컨테이너를 생성하고 실행하면서 테이블과 초기 데이터들을 넣어주려고 하였다. init.sql 은 초기 테이블 DDL 에 관한 것이고, stadium.sql 은 초기 데이터 DML 에 관한 것이다.

 

그런데 위와 같이 한글로 입력된 컬럼들이 다 깨져서 입력되길래 데이터베이스를 관리하는 MySQL 서버의 인코딩 문제라고 생각하여서 아래와 같이 docker-compose 에 설정을 추가해주었다.

    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
  • --character-set-server=utf8mb4
    • MySQL 서버가 사용하는 캐릭터셋을 utf8mb4로 설정하는 것이다. utf8mb4 캐릭터셋은 이모지와 같은 다양한 언어의 문자를 처리할 수 있다. utf8mb4 이 utf-8 과 어떤 것이 다른지 등과 같은 정보는 아래의 글을 참고하자.
    • [링크]
  • --collation-server=utf8mb4_unicode_ci
    • MySQL 서버가 사용하는 콜레이션을 utf8mb4_unicode_ci 로 설정하는 것이다. 콜레이션은 문자열의 비교와 정렬에 사용되는 규칙을 정의한다. utf8mb4_unicode_ci 콜레이션은 대소문자를 구분하지 않으며, 다양한 언어의 문자를 각 언어의 특성에 따라 비교, 정렬하는 것을 지원한다.

서버의 캐릭터 셋을 설정해주었기에 이제 한글이 안깨질 것이라고 생각했지만, 여전히 깨져서 입력되었다.

 

stadium.sql 이 도커 볼륨으로 마운트될 때, 깨져서 전달이 되나 해서 확인해보았다.

docker exec -it seat-view bash
cd /docker-entrypoint-init.db.d
cat stadium.sql

깨지지 않고 잘 전달되는 것을 볼 수 있다.

 

MySQL 서버는 utf8mb4 로 설정되어 로컬 PC 에서 직접 INSERT 쿼리를 작성할 때에는 한글이 깨지지 않고 잘 조회되었다. 그리고, 전달된 stadium.sql 은 깨지지 않았으므로 stadium.sql 문제도 아니다. /docker-entrypoint-initdb.d 를 통해서 데이터를 입력할 때만 한글이 깨지는 상황이다. 그래서 도커 컨테이너 내부에서 sql 을 실행하는 MySQL 클라이언트의 인코딩 설정 문제라고 추측하였고 확인해보았다.

docker exec -it seat-view mysql -u root -p

 위 명령어 실행 후 docker-compose 에서 미리 설정해준 비밀번호를 입력 후,

SHOW VARIABLES LIKE 'character_set_%';

도커 컨테이너에서 실행 중인 MySQL 의 캐릭터 셋과 관련 정보를 조회했다.

실제로, 도커에서 실행 중인 MySQL 클라이언트의 캐릭터 셋은 utf8mb4 가 아니라 latin1 인 것을 확인할 수 있다.

 

이를 바꿔주기 위해 my.cnf 를 아래와 같이 작성해주고, 이를 /etc/mysql/my.cnf 로 마운트해주었다.

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
version: '3'
services:
  db:
    image: mysql:8.0.32
    ports:
      - "3306:3306"
    env_file:
      - ../env/docker-compose.env
    container_name: seat-view
    environment:
      TZ: Asia/Seoul
    volumes:
      - seat-view:/var/lib/mysql
      - ./my.cnf:/etc/mysql/my.cnf
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./stadium.sql:/docker-entrypoint-initdb.d/stadium.sql
    command: bash -c "chmod 644 /etc/mysql/my.cnf && docker-entrypoint.sh mysqld"
    restart: always

volumes:
  seat-view:

 

Warning : World-writable config file '/etc/mysql/my.cnf/' is ignored 이런 에러가 발생하면서 my.cnf 를 못읽는 에러가 발생할 수 있는데, World-writable (모든 사용자가 쓰기 권한을 가진 파일) 로 설정되어 있기 때문에 발생한다. MySQL은 보안상의 이유로 World-writable 파일을 무시한다.

소유자에게 읽기와 쓰기 권한을 주고, 그룹과 다른 사용자에게는 읽기 권한만을 부여하는 644 권한을 주자.

chmod 644 /etc/mysql/my.cnf/

컨테이너가 삭제되고 다시 새롭게 생성되거나, 다른 PC 에서 docker-compose 를 실행할 때도 644 권한을 자동으로 주는 것이 편하다. 644 권한을 준 후에 mysql 컨테이너를 생성하도록 하는 명령어를 docker-compose 내에 적어주었다.

command: bash -c "chmod 644 /etc/mysql/my.cnf && docker-entrypoint.sh mysqld"

 

클라이언트의 캐릭터 셋이 utf8mb4 로 설정되었고, 데이터도 깨지지 않고 잘 입력된 것을 확인할 수 있다. 

 

 

저작자표시 (새창열림)

'개발' 카테고리의 다른 글

이미지가 포함된 게시글 관련 API 설계  (0) 2023.05.25
한 번의 API 콜로 가져오기 vs API 콜을 여러 번 하기  (0) 2023.05.10
docker-compose 로 개발 환경의 DB 구축하기  (0) 2023.04.22
spring.config.import 설정으로 env 파일을 읽을 때 생길 수 있는 오류  (0) 2023.04.22
plugin id: 'org.asciidoctor.convert' version: '2.2.1' was not found in any of the following sources 해결법  (0) 2023.04.16
    '개발' 카테고리의 다른 글
    • 이미지가 포함된 게시글 관련 API 설계
    • 한 번의 API 콜로 가져오기 vs API 콜을 여러 번 하기
    • docker-compose 로 개발 환경의 DB 구축하기
    • spring.config.import 설정으로 env 파일을 읽을 때 생길 수 있는 오류
    모달조아
    모달조아

    티스토리툴바