Oracle로 설명했지만 대부분의 DB in docker image에서 통하는 내용이다.

 

문제 상황

Oracle docker image를 사용해서 DB 올리고 작업하고 있는데, insert된 row들 날짜 필드 시간이 안맞는다.

(UTC -> Asia/Seoul)로 timezone 설정이 필요한 상황이다.

```sql

SELECT SYSDATE, CURRENT_DATE, DBTIMEZONE, SESSIONTIMEZONE FROM DUAL;

 

-- 현재 시각은 한국 기준 05-19 00:38:51

+-------------------+--------------------------+----------+---------------+
|SYSDATE            |CURRENT_DATE              |DBTIMEZONE|SESSIONTIMEZONE|
+-------------------+--------------------------+----------+---------------+
|2021-05-18 15:38:51|2021-05-18 15:38:51       |+00:00    |UTC            |
+-------------------+--------------------------+----------+---------------+

```

 

timezone 설정은 크게 2가지가 있다 [ OS timezone, DB timezone ]

OS ( docker image인 linux ) timezone에 영향을 받는 Oracle 내장 함수

SYSDATE returns the current date and time set for the operating system on which the database resides

 

DB timezone에 영향을 받는 Oracle 내장 함수

  • `` CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP``

 

DB timezone 바꾸는 방법

  • 여기서는 SESSIONTIMEZONE만 변경. SYSDATE는 변함없고 CURRENT_DATE만 바뀐 것을 볼 수 있다.

```sql

ALTER SESSION SET TIME_ZONE='Asia/Seoul';

-- [DB 재시작 필요하다] ALTER DATABASE SET TIME_ZONE = 'Asia/Seoul';

+-------------------+-------------------+----------+---------------+
|SYSDATE            |CURRENT_DATE       |DBTIMEZONE|SESSIONTIMEZONE|
+-------------------+-------------------+----------+---------------+
|2021-05-18 15:58:08|2021-05-19 00:58:08|+00:00    |Asia/Seoul     |
+-------------------+-------------------+----------+---------------+

```

 

docker OS timezone 바꾸는 방법

GNU libc (and thus any non-embedded Linux), 
reads /etc/localtime to determine the system's time zone (the default timezone if not overridden by the TZ environment variable or by an application-specific setting). 
https://unix.stackexchange.com/questions/452559/what-is-etc-timezone-used-for

 

따라서 다음 2 단계 진행하면 된다.

  1. TZ 설정 or /etc/localtime 설정
  2. /etc/timezone 설정

 

그러나!!! 애초에 도커 이미지의 /usr/share/zoneinfo 에 timezone 파일이 없다면 위 설정이 동작하지 않는다.

Alpine 등 가벼운 base image를 사용한 도커 이미지라면 내부에 timezone 파일이 없을 수 있다.

 

그래서 먼저 docker 내부에 timezone 파일이 있는지 확인하고, 없다면 넣어주어야 한다.

 

docker 내부에 zoneinfo 파일 생성하기

외부의 timezone 파일을 복사해서 넣어주는 방법

```docker

COPY {outter OS에 위치한 Asia/Seoul path} /usr/share/zoneinfo/Asia/Seoul

ENV TZ=Asia/Seoul

RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime

RUN echo $TZ > /etc/timezone

```

 

timezone 파일 직접 설치하는 방법

```docker

apt-get update

apt-get install -y tzdata

 

- 이후 아래 3가지 방법 중 아무거나 써서 설정해도 된다.

1. 직접 ln으로 설정

2. $ tzselect 커맨드 -> env $TZ 통해 설정해준다.

3. $ dpkg-reconfigure tzdata  커맨드 -> /etc/localdate, /etc/timezone 통해 설정해준다.

```

 

결과

  • DB 껐다 킬 필요는 없고 세션만 새로 열면 적용된다. SYSDATE만 변경된 것 확인 가능하다.

```sql

+-------------------+--------------------------+----------+---------------+
|SYSDATE            |CURRENT_DATE              |DBTIMEZONE|SESSIONTIMEZONE|
+-------------------+--------------------------+----------+---------------+
|2021-05-19 00:24:54|2021-05-18 15:24:54       |+00:00    |UTC            |
+-------------------+--------------------------+----------+---------------+

```

 

기존 이미지에 timezone 설정을 추가한 docker 이미지 빌드하기

```docker

FROM oracleinanutshell/oracle-xe-11g

ENV TZ=Asia/Seoul

RUN apt-get update && apt-get install -y tzdata && \

    echo $TZ > /etc/timezone && \

    ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

LABEL org.opencontainers.image.authors="sungbum.um@navercorp.com"

```

 

 

'Data Store' 카테고리의 다른 글

docker 안의 DB를 사용할 때 timezone 문제  (0) 2021.05.19
[Oracle] Pagination  (0) 2021.05.17
Flyway  (0) 2021.05.13
[Oracle] longest match  (0) 2021.02.16
DB 이중화 / 클러스터링  (0) 2020.09.23
redis  (0) 2020.03.10