docker 안의 DB를 사용할 때 timezone 문제
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, SYSTIMESTAMP``
- https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions172.htm
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 단계 진행하면 된다.
- TZ 설정 or /etc/localtime 설정
- /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"
```
'RDBMS > specific' 카테고리의 다른 글
Flyway (0) | 2021.05.13 |
---|---|
PostgreSQL 설치 (0) | 2020.12.04 |
[Oracle] 오라클 개요 및 정리 (0) | 2019.05.31 |
DB 접근 툴 : Universal Database Tool (0) | 2019.05.27 |
[mysql] 일반적인 SQL (0) | 2017.06.11 |