> ## Content Index
> Fetch the complete content index at: https://taektech.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 우분투 서버와 Ghost 블로그의 시간을 한국 시간으로 맞추기 (타임존 · NTP)
- URL: https://taektech.com/server-timezone-ntp-ghost/
- Published: 2026-06-25T00:45:52.000Z
- Updated: 2026-06-25T00:50:57.000Z
- Description: 우분투 서버가 UTC로 돌고 있어 한국 시간과 9시간 어긋났다. OS 타임존부터 NTP 동기화, Docker 컨테이너, Ghost 사이트 설정까지 네 단계로 시간을 맞춘 과정을 순서대로 기록했다.
- Author: Taektech
- Tags: 개발·터미널, Linux, Ghost, Docker, NTP, 서버운영

블로그를 운영하다 보니 서버 시간이 한국 시간과 다르게 표시되는 걸 발견했다. 글 발행 시각이나 로그 시간이 어긋나면 운영하면서 은근히 헷갈리기 때문에, 이참에 **OS 타임존**, **NTP 시간 동기화**, 그리고 **Ghost 자체 시간 설정**까지 한 번에 정리해 두기로 했다.

이 글은 내가 실제로 작업하면서 거친 순서 그대로 기록한 것이다.

---

## 1\. 문제 확인: 서버가 UTC로 돌고 있었다

먼저 현재 서버 시간이 어떤 기준으로 도는지 확인했다.

```bash
date          # 시스템 시간
date -u       # UTC 시간
timedatectl   # 타임존, NTP 동기화 상태 한눈에 보기

```

확인해 보니 타임존이 `Etc/UTC`로 잡혀 있었다. 한국 시간(KST)은 UTC보다 **9시간 빠르기 때문에**, 서버가 자정을 가리킬 때 한국은 이미 오전 9시였다. 시간 자체는 NTP로 잘 맞고 있었지만, \*\*표시되는 기준 시간대(타임존)\*\*가 한국이 아니었던 것이다.

특정 시점에 한국 시간이 어떻게 나오는지는 이렇게 바로 비교해 볼 수 있다.

```bash
TZ=Asia/Seoul date

```

---

## 2\. OS 타임존을 한국 시간으로 변경

우분투에서는 `timedatectl` 한 줄이면 끝난다.

```bash
sudo timedatectl set-timezone Asia/Seoul

```

설정 가능한 타임존을 검색하고 싶다면:

```bash
timedatectl list-timezones | grep Seoul

```

변경 후 다시 `timedatectl`을 실행하면 `Time zone: Asia/Seoul (KST, +0900)`으로 바뀐 걸 확인할 수 있다. 재부팅 없이 즉시 적용된다.

---

## 3\. 내부 NTP 서버로 시간 동기화 설정

회사/내부망 환경이라 외부 NTP(`ntp.ubuntu.com`) 대신 **내부 NTP 서버**를 쓰기로 했다. 우분투 최신 버전은 별도 설치 없이 `systemd-timesyncd`가 기본으로 시간 동기화를 담당한다.

현재 어떤 NTP 서버를 보고 있는지부터 확인했다.

```bash
timedatectl show-timesync | grep -E "ServerName|ServerAddress"

```

기본값은 외부 우분투 NTP였다. 이걸 내부 서버로 바꾸기 위해 **드롭인(drop-in) 설정 파일**을 만들었다. 메인 설정 파일을 직접 건드리지 않고 덮어쓸 수 있어 관리가 깔끔하다.

```bash
sudo install -d /etc/systemd/timesyncd.conf.d

# 내부 NTP 서버 주소를 NTP= 항목에 지정
sudo tee /etc/systemd/timesyncd.conf.d/10-custom-ntp.conf <<'EOF'
[Time]
NTP=<내부-NTP-서버-주소>
FallbackNTPServers=ntp.ubuntu.com
EOF

```

> `NTP=`에는 내부망 NTP 서버 주소를 넣고, 혹시 내부 서버가 응답하지 않을 때를 대비해 `FallbackNTPServers`로 외부 서버를 백업으로 남겨 뒀다.

설정을 적용하려면 서비스를 재시작한다. `systemd-timesyncd`는 별도의 "지금 동기화" 명령이 없고, **재시작 시 즉시 동기화를 시도**한다.

```bash
sudo systemctl restart systemd-timesyncd

```

잘 적용됐는지 확인:

```bash
timedatectl show-timesync | grep -E "ServerName|ServerAddress|NTPMessage"
timedatectl | grep -E "synchronized|NTP service"

```

- `ServerAddress`가 내가 지정한 내부 서버로 잡히고
- `NTPMessage`에 실제 응답 값이 채워지며
- `System clock synchronized: yes`

이 세 가지가 보이면 정상이다.

### 트러블슈팅 메모

NTP 서버가 **ping에 응답하지 않는 경우**가 있다. 처음엔 서버가 죽은 줄 알았는데, NTP는 **UDP 123 포트**를 사용하기 때문에 ICMP(ping) 차단과는 무관하다. 즉, ping이 안 돼도 NTP 동기화는 정상 동작할 수 있다.

만약 동기화가 끝까지 안 되면 NTP를 껐다 켜서 강제로 다시 잡게 할 수 있다.

```bash
sudo timedatectl set-ntp false && sudo timedatectl set-ntp true

```

그래도 안 되면 방화벽에서 **UDP 123**이 열려 있는지 확인이 필요하다.

---

## 4\. Docker로 띄운 Ghost 컨테이너 시간대 맞추기

내 블로그는 Docker 컨테이너로 Ghost를 운영 중이다. **호스트 OS의 타임존과 컨테이너 내부 타임존은 별개**이기 때문에, 컨테이너도 따로 한국 시간으로 맞춰야 한다.

`docker-compose.yml`의 `environment`에 `TZ` 환경변수를 추가했다.

```yaml
services:
  ghost:
    image: ghost:6-alpine
    environment:
      TZ: Asia/Seoul
      # ... 기존 설정 ...

```

여기서 주의할 점. 환경변수 변경은 **단순 재시작(`restart`)으로는 반영되지 않는다.** 컨테이너를 재생성해야 한다.

```bash
docker compose up -d

```

---

## 5\. Ghost 관리자에서 사이트 타임존 설정 (가장 중요)

마지막이자 가장 핵심이다. OS와 컨테이너 시간을 다 맞춰도, **Ghost는 자체 설정의 타임존을 기준으로 글 발행 시각·예약 발행 시간을 처리**한다.

Ghost 관리자에서 직접 바꿔야 한다.

> **Settings → General → Site timezone → `(GMT +9:00) Seoul` 선택**

이 설정을 바꾸지 않으면, 서버 시간을 아무리 맞춰도 예약 발행이 9시간 어긋나는 일이 생긴다. 실제로 시간 관련 동작에 가장 직접적인 영향을 주는 건 이 설정이었다.

---

## 정리

시간 하나 맞추는 데 의외로 **레벨이 세 개**나 있었다.

| 레벨     | 대상     | 설정 방법                               |
| ------ | ------ | ----------------------------------- |
| OS     | 호스트 서버 | timedatectl set-timezone Asia/Seoul |
| 시간 동기화 | NTP    | systemd-timesyncd 드롭인 설정            |
| 컨테이너   | Docker | docker-compose.yml의 TZ              |
| 애플리케이션 | Ghost  | 관리자 → Settings → Site timezone      |

겉으로 보이는 증상은 "발행 시간이 9시간 어긋난다" 하나지만, 원인은 이 중 어디든 될 수 있다. 다음에 또 헷갈리지 않도록, **OS → NTP → 컨테이너 → 앱** 순서로 점검하는 흐름을 기록으로 남겨 둔다.