Часовой пояс и locale на сервере Linux
Неверный часовой пояс ломает логи, cron и метки времени в БД, а неправильная locale выдаёт кракозябры вместо кириллицы. Настроим и то и другое одной сессией: timedatectl, синхронизация времени по NTP и генерация UTF-8 локали.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему это важно с первого дня
Свежий VPS часто приходит с временем в UTC и минимальной локалью C. Пока сайт один — не критично, но как только появляются cron по расписанию, логи для разбора инцидентов и записи с таймстампами, расхождение времени превращается в источник багов: задача запускается не в тот час, а в логах невозможно сопоставить события.
- Часовой пояс определяет, как система показывает локальное время в логах, cron и датах файлов.
- Синхронизация NTP держит часы точными — без неё они плывут на секунды в сутки.
- Locale задаёт кодировку и язык сообщений; без UTF-8 кириллица и эмодзи ломаются.
Настроить всё это стоит сразу после создания сервера, до того как накатить приложения и базы.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS с правильным окружениемСмотрим текущее состояние
Всё, что связано со временем, в systemd управляется утилитой timedatectl. Без аргументов она показывает текущий пояс, статус синхронизации и часы.
timedatectl
В выводе важны строки Time zone (текущий пояс), System clock synchronized (синхронизированы ли часы) и NTP service (активен ли демон синхронизации). Список доступных поясов при необходимости.
timedatectl list-timezones | grep Europe
Ставим часовой пояс
Пояс задаётся одной командой — systemd сам обновит символическую ссылку /etc/localtime. Для Москвы это выглядит так.
sudo timedatectl set-timezone Europe/Moscow
Если сервер обслуживает клиентов из разных зон, часто логичнее держать системное время в UTC, а конвертацию делать на уровне приложения — тогда логи разных серверов сопоставимы без пересчёта.
sudo timedatectl set-timezone UTC
После смены пояса перезапусти сервисы, которые кэшируют время при старте (например cron и приложение), иначе они продолжат работать по старому поясу до перезапуска.
Включаем синхронизацию времени
Точность часов держит NTP. В systemd за это отвечает systemd-timesyncd — лёгкий клиент, которого достаточно для большинства серверов. Включается флагом.
sudo timedatectl set-ntp true
systemctl status systemd-timesyncd
Проверить, что синхронизация реально идёт и с каким сервером, можно так.
timedatectl show-timesync --all | head
Если нужен более точный демон (например для БД с жёсткими требованиями к времени), ставят chrony — он быстрее подстраивает часы и лучше переживает скачки.
sudo apt -y install chrony
systemctl enable --now chrony
chronyc tracking
Настраиваем locale UTF-8
locale отвечает за язык системных сообщений и, что важнее, за кодировку. Нужную локаль сначала генерируют, затем назначают системной. Для русского UTF-8.
sudo locale-gen en_US.UTF-8 ru_RU.UTF-8
sudo update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
Часто оптимально держать язык сообщений английским (проще гуглить ошибки), а региональные форматы — русскими. Проверить итог.
locale
Если в выводе появляются предупреждения Cannot set LC_* — значит нужная локаль не сгенерирована. На минимальных образах может не хватать пакета.
sudo apt -y install locales && sudo dpkg-reconfigure locales
Разберём разницу между переменными: LANG задаёт язык и кодировку по умолчанию для всех категорий, LC_ALL — жёсткий override, который перебивает всё остальное (его удобно ставить временно для одной команды), а отдельные LC_TIME, LC_NUMERIC, LC_MONETARY тонко управляют форматами дат, чисел и валют. На практике хватает LANG плюс, при желании, региональных LC_* — так система говорит по-английски, но даты и числа показывает в привычном виде.
Частые ошибки
- Locale задана через SSH-клиент — многие терминалы шлют переменную
LC_*на сервер, из-за чего кажется, что locale «не та». Проверяй черезssh server localeи настройкуSendEnvв клиенте. - Забыли перелогиниться — переменные окружения LANG подхватываются в новой сессии; после update-locale выйди и зайди заново.
- Часы плывут без NTP — если
set-ntp trueне включён, время дрейфует и ломает TLS-хэндшейки и cron. - Разные пояса у сервера и БД — MySQL/PostgreSQL имеют собственную настройку timezone; синхронизируй её с системной.
После всех правок финальная проверка одной строкой покажет, что время, пояс и синхронизация в порядке.
timedatectl && date
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS с правильным окружениемОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Держать время в UTC или в местном поясе?
Для серверов с клиентами из разных зон удобнее UTC — логи сопоставимы, нет путаницы при переходе на зимнее время. Для одного региона можно ставить местный пояс.
Обязательно ли ставить chrony?
Нет, встроенного systemd-timesyncd хватает большинству. chrony нужен, когда важна повышенная точность и быстрая подстройка часов, например для баз данных.
Почему кириллица превращается в вопросы?
Почти всегда причина — locale не в UTF-8 или несгенерированная ru_RU.UTF-8. Сгенерируй локаль, назначь LANG и перелогинься.