Синхронизация .dot файлов

Устал вручную копировать настройки на разных компьютерах? Эта статья расскажет о синхронизации дотфайлов, благодаря которой настройки среды и приложений будут оставаться одинаковыми.

В этой статье поговорим о том, как использовать dotfiles, чтобы сохранять системные настройки неизменными на разных устройствах. Следуя простым шагам с помощью Git, ты сможешь легко управлять всем: от профилей bash до настроек приложений. Такой подход обеспечивает бесперебойную работу вне зависимости от того, какую платформу ты используешь.

Если торопишься, то переходи сразу на пошаговое руководство по настройке синхронизации дотфайлов. А если хочешь понимать, что и для чего там делается, то читай дальше.

Дот файлы (dotfiles) - это файлы конфигурации в Unix-подобных системах, таких как MacOS, Linux и BSD. В них хранятся настройки приложений, инструментов и служб, работающих в твоей системе, включая такие как git, ssh, .bashrc, .zshrc, .nanorc, .vimrc и многие других.

Название таких файлов начинается с точки (.), чтобы по умолчанию скрыть эти файлы от пользователя и упростить списки файлов в каталогах. А вот почему они скрыты от пользователя - читай в сноске ниже (кликни, чтобы открыть ее).

Как .dot файлы стали скрытыми файлами

Эта история началась много лет назад, когда в UNIX были созданы первые файловые системы. Чтобы обеспечить удобную навигацию, в каждый каталог добавлялся один файл с точкой (.). И еще один файл с двойной точкой (..) добавлялся, чтобы легко перемещаться вверх по структуре каталогов.

Поскольку в этих файлах не было реальных данных, то в код команды LS был добавлен быстрый хак, чтобы скрыть такие файлы от вывода по умолчанию. Здесь есть полная история этого хака о том, как лень позволила создавать такие скрытые файлы 😉.

Многие разработчики делятся своими файлами настроек. В интернете всегда можно найти ссылки на популярные репозитории с настройками других людей.

Синхронизация dotfiles необходима тем, кто использует несколько компьютеров (и / или серверов) и на каждом хотят иметь привычные настройки окружения, сервисов и приложений. Это повышает производительность, сокращает время настройки новых машин и обеспечивает доступность одинаковых инструментов и конфигураций сервисов и приложений, независимо от используемого компьютера.

Мне, например, недавно пришлось запускать в работу сразу два новых макбука подряд. На основном все настройки сделаны уже давно и редко меняются. Там уже привык к определенным утилитам, сочетаниям клавиш и многие действия выполняются просто на автомате. А на новом пришлось настраивать все с самого начала.

Первая проблема была в том, чтобы вспомнить - что и для чего необходимо установить и как настроить, чтобы все было привычно. Затем возникла вторая проблема - как синхронизировать настройки программ, да ещё так, чтобы при их изменении на одном компьютере все это автоматически менялось на других.

Для начала необходимо понимать, что синхронизация абсолютно всего - установленных приложений и сервисов, их настроек, переменных окружения и т.п. до сих пор не решена на все 100%. Существуют вещи, привязанные к конкретному аппаратному обеспечению, и простое их копирование на другой компьютер приведет к неработоспособному приложению.

Поэтому все до сих пор мучаются, используют Ansible, Chef.io, OpenTofu и другие инструменты, или решают вопрос хотя бы с основными приложениям. Я также настроил синхронизацию пока лишь для следующих файлов конфигурации:

  • .gitconfig - конфигурация для работы с Git.
  • .gitignore - какие файлы игнорировать. (👉 конфигуратор .gitignore)
  • .muttrc - почта в терминале.
  • .p10k.zsh - тема для ZSH.
  • .vimrc - настройки для Vim.
  • .zimrc - модули для Zim.
  • .zshrc - настройки ZSH.

Любой файл можно добавить и убрать из синхронизации в любое время.

В интернете есть масса статей на эту тему. Список самых толковых и полезных из всего, что я перечитал на эту тему, ты найдешь в самом конце данной статьи. Большая часть описывает использование различных систем контроля версий.

Наиболее популярная система - это, конечно, Git. На картинке можно видеть доли рынка разных систем, а также то, что Git - это явный лидер в среди всех.

Доли рынка разных систем контроля версий.
Доли рынка разных систем контроля версий.

Ссылка на актуальную информацию: Топ 5 технологий управления версиями.

Что такое Git и GitHub и как они различаются

Git - это бесплатная распределенная система контроля версий с открытым исходным кодом для отслеживания изменений в файлах, предназначенная для быстрой и эффективной работы с любыми проектами - от небольших до очень крупных.

GitHub - это коммерческая компания, предлагающая облачный хостинг для репозиториев Git. Он позволяет отдельным энтузиастам и целым командам хранить, отслеживать и контролировать изменения в коде (файлах) проекта.

Проще говоря, Git можно использовать без Github, а GitHub без Git нельзя.

Система Git популярная, удобная, привычная, так что я решил использовать именно ее. При использовании Git есть два наиболее распространенных способа как синхронизировать файлы настроек - через обычный каталог и через bare каталог.

Как синхронизировать настройки среды через обычный каталог? Для этого в твоем домашнем каталоге необходимо создать специальный каталог (директорию, папку), в котором будут сохраняться все необходимые тебе файлы настроек и конфигураций. Далее для них создаются символические ссылки в твоем домашнем каталоге.

Вот конкретные шаги для настройки синхронизации этим способом. Все команды выполняются в консоли.

# Переходим в свой домашний каталог
cd ~

# Создаем каталог для хранения файлов настроек
# Название может быть любым, я использовал dotfiles
mkdir dotfiles 

# Переносим существующие файлы настроек в созданный каталог
mv .vimrc .zimrc .zshrc dotfiles/

# Создаем символические ссылки в домашнем каталоге
# -s: эта опция устанавливает символическую связь
# -f: перезаписывает файл связи без уведомления
ln -sf ~/dotfiles/.vimrc ~/.vimrc
ln -sf ~/dotfiles/.zimrc ~/.zimrc
ln -sf ~/dotfiles/.zshrc ~/.zshrc

Простыми словами: команды выше переносят файлы настроек в специальный каталог (dotfiles) и заменяют их в твоем домашнем каталоге ссылками на них. Когда программа, например vim, при запуске пытается прочитать файл со своими настройками, который по умолчанию лежит в твоем домашнем каталоге, она открывает ссылку, которая переводит ее на сам файл в каталоге dotfiles.

Следующим шагом нужно через браузер зайти на свой GitHub (если у тебя его нет, то зарегистрируй аккаунт, это бесплатно) и создать там репозиторий, где ты будешь хранить свои файлы конфигурации. Потом возвращаемся в консоль на компьютере и переходим в созданный нами каталог dotfiles

cd dotfiles

Инициализируем его как Git каталог:

git init
git add .
git commit -m ‘First commit’
# В команде ниже замени ссылку на адрес своего репозитария на GitHub
git remote add origin https://github.com/YOURNAME/dotfiles
git push origin main

С таким каталогом удобно работать привычными командами Git - status, push, pull и пр. Когда тебе надо добавить новый файл настроек для синхронизации, например, .nanorc то выполни следующую последовательность действий:

mv .nanorc dotfiles/
ln -sf ~/dotfiles/.nanorc ~/.nanorc

cd dotfiles
git add .nanorc
git commit -m ‘Add nanorc config’
git push

ВАЖНО! Обрати внимание, что команды Git выполняются внутри каталога проекта, который был инициализирован, в папке .git. Стандартная логика работы Git предполагает, что рабочее дерево проекта находится в этом же каталоге. Поэтому, чтобы выполнять действия для синхронизации файлов (добавить, изменить, скачать и т.п.), тебе каждый раз нужно будет заходить внутрь каталога dotfiles.

Однако опционально можно создать специальный алиас, который позволит тебе исполнять команды Git в каталоге dotfiles из любого места, не заходя в него каждый раз. Назвать этот алиас ты можешь как тебе удобно, я назвал cfg. Вот что нужно для этого сделать.

# Создаем алиас с названием, которое тебе легко запомнить
alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'

# Сохраняем его в настройках среды, чтобы не создавать каждый раз
echo "alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.zshrc

# И отключаем показ неотслеживаемых файлов, чтобы видеть нужные
cfg config --local status.showUntrackedFiles no

Если пользоваться этим алиасом, то процесс добавления новых файлов или версий будет выглядеть так:

cd ~
mv .nanorc dotfiles/
ln -sf ~/dotfiles/.nanorc ~/.nanorc

cfg add .nanorc
cfg commit -m ‘Add nanorc config’
cfg push

Заметь, что при этом нет необходимости входить в каталог dotfiles - команду cd dotfiles мы не исполняли. То есть ты можешь исполнять эти команды из любого места. Ещё раз напомню, что этот шаг полностью опционален, он нужен лишь для удобства. Если тебе не лень каждый раз заходить в каталог dotfiles, чтобы дополнить или обновить файлы настроек, то можешь алиас не создавать.

Как синхронизировать настройки на другом компьютере?

Теперь… На другом компьютере для синхронизации настроек с исходным запускаем консоль и выполняем следующие команды:

# Переходи в домашний каталог
cd ~

# Чтобы избежать рекурсии, заранее добавь каталог .cfg в глобальный игнор
echo ".cfg" >> .gitignore

# Клонируй свой репозиторий с GitHub
git clone https://github.com/YOURNAME/dotfiles $HOME/.cfg

# Если пользуешься алиасом, сохрани его в настройках окружения
echo "alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.zshrc

# Отключи показ неотслеживаемых файлов
cfg config --local status.showUntrackedFiles no

# И переноси содержимое репозитория на новый компьютер
cfg checkout

При этом ты можешь получить предупреждение, что некоторые из уже существующих локальных файлов, например, .bashrc или .gitignore могут быть перезаписаны. Сохрани их, если они тебе нужны или удали, после чего повтори команду - cfg checkout. Готово!

Некоторые пользователи отмечают, что данный способ не влияет негативно на производительность других программ.

Неудобство же заключается в том, что нужно всегда помнить про символические ссылки, и что сами файлы конфигурации лежат теперь в специальном каталоге. Если ты что-либо изменил, то ссылки нужно обновить или отредактировать. А если нужда в синхронизации отпадет, то ссылки необходимо будет удалить и вернуть сами файлы на место.

Ну и еще надо иметь ввиду, что некоторые приложения просто не работают с символическими ссылками. Им нужны только оригинальные файлы конфигурации.

Другая группа решений использует опцию --bare при создании каталога Git. Я использовал именно этот метод, поскольку мне очень не хотелось возиться с отдельным каталогом и символическими связями. Хотя все и автоматизируется, но данный метод мне показался изящнее и удобнее.

👉 Здесь я уже не буду углубляться, но в чем разница между обычным и bare каталогами ты можешь почитать в этом информативном ответе про основные задачи bare репозитория.

Итак, что нужно сделать, чтобы настроить синхронизацию дотфайлов методом bare каталога? Для этого выполняем следующие шаги.

# Переходим в домашний каталог
cd ~

# Создаем bare репозиторий Git в домашнем каталоге
git init --bare $HOME/.cfg
alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
cfg config --local status.showUntrackedFiles no
echo "alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.zshrc

Когда ты настраиваешь синхронизацию дот-файлов, важно помнить о безопасности. Иногда файлы конфигурации могут включать чувствительные данные, такие как ключи доступа и пароли. Вот несколько простых советов, которые помогут тебе защитить свои дот-файлы:

  1. Приватные репозитории: Если ты используешь GitHub или другую платформу для хранения своих дот-файлов, обязательно сделай репозиторий приватным. Это поможет избежать несанкционированного доступа к твоим файлам конфигурации.

  2. Шифрование данных: Не добавляй в репозиторий файлы, содержащие пароли, ключи API, приватные SSH ключи и другую чувствительную информацию. Для таких данных лучше использовать специальные менеджеры секретов, например, git-crypt или SOPS или GPG.

  3. Регулярные проверки: Периодически проверяй, кто имеет доступ к твоему репозиторию, и обновляй пароли и ключи. Это поможет защитить твои данные от несанкционированного доступа.

  4. Использование SSH-ключей: Подключайся к удалённым серверам и репозиториям с помощью SSH-ключей, а не паролей. Это повысит безопасность твоих соединений.

  5. Ограничение доступа: Убедись, что доступ к твоим дот-файлам имеют только те, кому это действительно нужно. Включи двухфакторную аутентификацию для дополнительной защиты.

В заключение хочу поделиться некоторыми моментами.

Во-первых, заморачиваться с синхронизацией стоит только в том случае, если у тебя больше двух серверов / компьютеров, для которых тебе важно иметь одинаковые инструменты и настройки. Иначе возни будет больше, чем толку. Во-вторых, постарайся понять, что именно тебе надо синхронизировать. Если речь об одной-двух утилитах, то возможно, что опять оно того не стоит. И не забывай про безопасность!

Когда я начал настраивать синхронизацию дот-файлов, то все казалось очень сложным. После того, как все настроил и выучил служебные команды, то все стало быстро и просто. Работает отлично, так что в моем случае усилия себя оправдали.

Однако, по прошествии определенного времени, я понял, что мне гораздо чаще приходится поднимать новые сервер или настраивать новый компьютер, чем менять настройки. А это уже совсем другая история, которая требует немного другого подхода и инструментария. Я уже изучаю очередной набор информации на эту тему, есть очень интересные находки. Как обычно, планирую обобщить и упростить опыт умных людей и поделиться этим всем в своем блоге, так что заглядывай снова.

Привожу список материалов, которые пришлось перелопатить, чтобы разобраться в теме.

Желаю успехов и если будут вопросы, свяжись со мной по любому из каналов.

😎