제 컴에선 되는데요

개발자들간의 대화에서 자주 나오는 변명이다. 지금 고군분투하고 있는 졸업작품에서 뼈저리게 느껴지는 말이다. 테스트 환경(로컬)과 운영 환경이 정말 다르다. localhost에선 잘만 되던 것이 도커로 서버에 배포하면 기대와 정말 다르다. 이번 문제는 도커로 배포된 MySQL 컨테이너의 시간대가 UTC로 설정되어 있어서 발생했다.

삽질의 시작

백엔드(Node)에서 DB에 대한 config를 수정해야겠다 싶어서 구글링하다가 비슷한 문제에 대한 해결방법을 찾았다. Sequalize를 사용하지는 않지만 MySQL 설정에 대한 방법은 동일하겠다 싶었다.

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
connectionLimit: 30,
host: process.env.DATABASE_HOST,
user: "root",
password,
database,
dateStrings: "date",
charset: "utf8mb4",
debug: false,
insecureAuth: true,
};

이 config를

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {
connectionLimit: 30,
host: process.env.DATABASE_HOST,
user: "root",
password,
database,
timezone: "Asia/Seoul",
dateStrings: true,
typeCast: true,
charset: "utf8mb4",
debug: false,
insecureAuth: true,
};

이렇게 바꿨다. 배포해보니 결과는 똑같았다.

9시간 전으로 타임스탬프가 찍힌다.. timezone: '+09:00'으로 설정해도 먹히지 않았다. 대체 왜 이러는걸까 생각하다가 도커로 배포한 MySQL에서 직접 select current_timestamp()를 찍어봐야겠다 생각했다.

그러니 문제의 timezone과 동일한 시간이 출력되어서 데이터베이스의 timezone만 바꾸면 되겠다고 생각했다. (여기서 해결한 줄 알았다)

1
SET time_zone = 'Asia/Seoul';

이제 현재시간도 정상적으로 찍힌다.

그런데 배포했는데 또 안된다. 9시간 전으로 (UTC 시간으로) 찍힌다.

해결 방법

데이터베이스에서 timezone을 설정하는 방법은 맞았다. 하지만 데이터베이스 컨테이너 내 모든 DB의 Global 값을 설정해야 모든 테이블에 대해 timezone이 정상적으로 적용되는 것이었다.

1
SET GLOBAL time_zone = 'Asia/Seoul';

이제 정상적으로 찍힌다. 사실 이 설정들을 바꾸는 건 어렵지 않은데, 아무리 배포 자동화가 되어 있어도 깃에 푸시하고 서버에 접속해서 스크립트를 실행하면 몇 초만에 끝나는 것도 아니라서 꽤 번거로웠다. 로컬 환경에서 배포 환경 기준으로 테스트할 수 있는 방법이 있으면 좋겠다..