Search
Write a publication
Pull to refresh

Docker + Neovim: поднимаем конфиг на любом сервере и не засоряем систему

Level of difficultyEasy
Reading time6 min
Views8K

Предисловие

Иногда нужно запустить nvim на старом сервере. Но тут сразу куча проблем: одно не поставить, другое не собрать, а если что-то обновить — можно развалить весь проект.

Этот подход удобен и для новых систем. Docker позволяет поднять nvim с последним Python, nvim-treesitter и своим конфигом прямо в контейнере, не засоряя основную ОС.

При этом можно редактировать локальные файлы на сервере так, как будто nvim установлен на самой системе. В статье показано, как всё это запустить на CentOS 7.
А если заработало там — значит, на любом современном Linux тем более проблем не будет.

Установка и запуск докера

Можно пропустить, если у вас и так есть докер или у вас не centos.

Мне пришлось для установки пакетов обновить /etc/yum.repos.d/CentOS-Base.repo - на столько все там было уже мертво. Далее я поставил докер:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager  --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker

Просто hello-world контейнер тоже поставил, чтобы убедиться, что докер работает:

sudo yum install -y docker-ce docker-ce-cli containerd.io

Запустил sudo docker run hello-world увидел там Hello from Docker! Значит все ок. Можно ехать дальше.

Я еще добавил своего юзера в группу, чтобы можно было без sudo запускать всё хозяйство: sudo usermod -aG docker $USER и от лица своего юзера newgrp docker

Подготовка завершена. Можно теперь создать контейнер для nvim и попробовать с его помощью начать редактировать код на нашем стареньком Centos.

Контейнер для neovim с готовой сборкой AstroNvim

AstroNvim
AstroNvim

Создал папочку

mkdir ~/devcontainer
cd ~/devcontainer

И положил туда файл Dockerfile с таким содержимым

Dockerfile Astro
FROM ubuntu:22.04

# Обновляем и ставим все зависимости
RUN apt update && apt install -y \
    ninja-build gettext cmake unzip curl git \
    python3 python3-pip python3-venv \
    nodejs npm \
    ripgrep fzf

# Устанавливаем свежий Neovim из исходников
RUN git clone https://github.com/neovim/neovim.git /tmp/neovim && \
    cd /tmp/neovim && \
    git checkout stable && \
    make CMAKE_BUILD_TYPE=Release && \
    make install

# Python и Node tooling
RUN pip3 install --upgrade pip pynvim
RUN npm install -g pyright typescript typescript-language-server

# Создаем пользователя и директории для конфига
RUN useradd -ms /bin/bash dev
USER dev
ENV HOME=/home/dev
WORKDIR /home/dev

# Гарантируем создание .config
RUN mkdir -p /home/dev/.config

# Клонируем AstroNvim template и core в явные пути
RUN git clone https://github.com/AstroNvim/template /home/dev/.config/nvim && \
    git clone https://github.com/AstroNvim/AstroNvim /home/dev/.config/nvim/lua/astro

# Headless установка плагинов AstroNvim
RUN NVIM_APPNAME=nvim nvim --headless "+AstroUpdate" +qa

CMD ["bash"]

Я в данном случае добавил туда просто готовую сборку AstroNvim со всеми пирогами.

Собрал контейнер

docker build -t astro-nvim-dev .

И запустил командой

docker run -it \
  -v /home/you/project:/home/dev/project \
  astro-nvim-dev

И вот здесь /home/you/project — путь к директории с моим кодом, который я хочу на старом CentOS редактировать.

Контейнер запустил. Далее я ввел команду nvim и увидел:

Астра готова к работе
Астра готова к работе

Нажал f увидел весь свой код в fzf на centos 7. Всё работает!

Контейнер для neovim со своим nvim-конфигом

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

mkdir ~/devcontainer-my-conf
cd  ~/devcontainer-my-conf

Кладем туда файл с таким именем и содержимым:

Dockerfile
FROM ubuntu:22.04

# Обновляем систему и ставим всё для сборки Neovim
RUN apt update && apt install -y \
    ninja-build gettext cmake unzip curl git \
    build-essential

# Собираем последний Neovim
RUN git clone https://github.com/neovim/neovim.git /tmp/neovim && \
    cd /tmp/neovim && \
    git checkout stable && \
    make CMAKE_BUILD_TYPE=Release && \
    make install

# Ставим Python и pynvim
RUN apt install -y python3 python3-pip && \
    pip3 install --upgrade pip && \
    pip3 install pynvim

# Ставим Node и LSP
RUN apt install -y nodejs npm && \
    npm install -g pyright typescript typescript-language-server

# Добавляем ripgrep и git для удобства
RUN apt install -y ripgrep git

# Создаём юзера
RUN useradd -ms /bin/bash dev
USER dev
WORKDIR /home/dev

CMD ["bash"]

Собираем:

docker build -t my-dev-nvim .

И далее запускаем:

docker run -it \
        -v /home/user/www/my_app:/home/dev/www/my_app \
        -v /home/user/.config/nvim:/home/dev/.config/nvim \
        -v /home/user/.local/share/nvim:/home/dev/.local/share/nvim \
        -v /home/user/.cache/nvim:/home/dev/.cache/nvim \ 
        my-dev-nvim

Первый путь /home/user/www/my_app — это папка с кодом на хосте, которую нужно редактировать. /home/dev/www/my_app — путь к этой же папке внутри контейнера.

Второй путь /home/user/.config/nvim — папка с конфигурацией nvim, подключаемая в Docker для работы в том же окружении, что и на хосте.

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

Скорость работы. Что мы теряем?

Запуск Neovim и LSP внутри Docker — вполне жизнеспособный путь. Это не будет “тупить” значительно, по сравнению с локальной установкой:

  • Docker использует изоляцию на уровне ядра, почти без накладных расходов на производительность.

  • На r/neovim народ пишет, что "не так много overhead при запуске процесса в namespace". Короче, docker-daemon добавляет немного, но ничего критичного

Alias

Все что осталось, это прописать алиас в ~/.bashrc, чтобы запускать nvim одной командой в консоли.

Для Астры:

alias av='docker run -it \
  -v /home/user/www/my_app/:/home/dev/project \
  astro-nvim-dev  nvim'

И для своей сборки:

alias v='docker run -it \
        -v /home/user/www/my_app:/home/dev/www/my_app \
        -v /home/user/.config/nvim:/home/dev/.config/nvim \
        -v /home/user/.local/share/nvim:/home/dev/.local/share/nvim \
        -v /home/user/.cache/nvim:/home/dev/.cache/nvim \ 
        my-dev-nvim'

Применяем изменения source ~/.bashrc и запускаем Астру командой: av, а свою собственную сборку командой v.

Всё, можно пользоваться.

LAZYVIM

LazyVim
LazyVim

И вот еще готовый Dockerfile для LazyVim, который сейчас тоже очень модный и современный.

Dockerfile
FROM ubuntu:22.04

# Устанавливаем все зависимости
RUN apt update && apt install -y \
    ninja-build gettext cmake unzip curl git \
    python3 python3-pip python3-venv \
    nodejs npm \
    ripgrep fzf

# Устанавливаем Neovim последней стабильной версии
RUN git clone https://github.com/neovim/neovim.git /tmp/neovim && \
    cd /tmp/neovim && \
    git checkout stable && \
    make CMAKE_BUILD_TYPE=Release && \
    make install

# Устанавливаем Python tooling
RUN pip3 install --upgrade pip pynvim

# Устанавливаем Node tooling и LSP
RUN npm install -g pyright typescript typescript-language-server

# Создаём пользователя
RUN useradd -ms /bin/bash dev
USER dev
ENV HOME=/home/dev
WORKDIR /home/dev

# Создаём папку для конфигов
RUN mkdir -p /home/dev/.config

# Клонируем LazyVim template
RUN git clone https://github.com/LazyVim/starter /home/dev/.config/nvim

# Выполняем headless init чтобы установить все плагины
RUN nvim --headless "+Lazy! sync" +qa

CMD ["bash"]

Собирается он точно так же, как сборка с AstroNvim.

Перенос настроенного Neovim в Docker на другой сервер

Допустим, Neovim уже настроен внутри Docker-контейнера: установлены последние LSP, Treesitter, любимые и полезные плагины. Возникает задача — перенести это окружение на другой хост и сразу получить готовую конфигурацию без лишних действий.

1. Сохранение образа на исходном сервере

Пусть контейнер называется modern-nvim-final. Тогда сохранение образа выглядит так:

docker save modern-nvim-final | gzip > nvim-done.tar.gz

2. Перенос образа на другой хост

С помощью SSH можно передать и сразу загрузить образ:

cat nvim-done.tar.gz | ssh user@example.com 'gunzip -c | docker load'

3. Запуск контейнера на новом сервере

docker run -it \
  -u $(id -u):$(id -g) \
  -v /home/you/project:/home/dev/project \
  modern-nvim-final

Что в итоге?

После переноса сразу получаете привычный редактор, который уже полностью настроен под ваши задачи. Всё работает «из коробки»: автодополнение, LSP, подсветка, плагины — именно так, как вы привыкли. Можно сразу приступать к редактированию кода, не отвлекаясь на установку и настройку окружения.

Почему это удобно

  • можно использовать самую свежую версию редактора без риска что-то сломать в системе;

  • вся конфигурация и плагины изолированы от хоста;

  • при ошибках легко откатиться к сохранённому состоянию с помощью docker load;

  • перенос между серверами занимает считанные минуты — ничего не нужно переустанавливать.

Tags:
Hubs:
+11
Comments22

Articles