7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VimAdvent Calendar 2023

Day 23

dotfiles(neovim,vim,tmux) + Docker でどこでも環境構築

Last updated at Posted at 2023-11-07

dotfiles + Dockerの利点

私は、普段neovimとwslを使って開発をしています。
しかし、学校・職場で同じ環境を再現するのは不可能なことが多いです。また、できたとしても(dotfilesの)OSごとの設定は面倒です。

そこで、dotfilesとDockerfileを使い、環境ごとgitで管理します。
githubに上げれば、いつでもどこでも自分の好きな環境がdocker compose up -dで立ち上がります。面倒な依存関係も、OSごとの対応もいりません。

構成

TL;DR すぐに環境を立ち上げたい人へ

  1. dotfiles + Dockerの作り方
  2. 詰まったところとその対応

環境

  • win11 * wsl2
  • ubuntu22.04(docker)
  • nvim

TL;DR

早くイメージを使いたい人へ

1. 以下をgit clone

Dockerfiles

2. sample-docker-compose.ymlを自分の環境に合わせて編集

  • 直接、編集したいディレクトリをdocker-composeのvolumeでマウント
  • ホストマシンと同じsshのkeyを使用することでDocker内のterminalから、githubへのpushが可能に
docker-compose.yml
version: '3'
services:
  dotfiles:
    image: hwata001/dotfiles:latest
    volumes:
      - type: bind
        source: "<you-working-dir>"
        target: "/home"
      - type: bind
        source: "<your-ssh-key>" #your github ssh key dir
        target: "/root/.ssh"

3. コンテナの立ち上げ

これで立ち上がって入れるはず

docker compose up -d
docker compose run -it dotfiles /bin/bash

4. コンテナの削除

終わったら削除も忘れずに

docker ps -a
docker stop <containerID>
docker rm <containerID>

dotfiles Dockerfiles Docker-image

dotfiles

Dockerfiles

dotfiles Docker image

Docker + dotfiles の作り方

  1. dotfilesをgithubで管理
  2. Dockerfileを作成
  3. Docker imageをDocker hubにpushする
  4. docker-compose.ymlの作成・volumeの指定

1. dotfilesをgithubで管理

githubで管理します。リポジトリはpublicにしましょう。

2. Dockerfileを作成

Dockerfile
FROM ubuntu:22.04

SHELL ["/bin/bash", "-c"]

RUN apt update && \
    apt-get update && \
    apt install -y curl git ripgrep tar unzip vim wget python3 python3-pip python3-venv tmux

# nvim install
RUN wget https://github.com/neovim/neovim/releases/download/stable/nvim-linux64.tar.gz && \
    tar -zxvf nvim-linux64.tar.gz && \
    mv nvim-linux64/bin/nvim usr/bin/nvim && \
    mv nvim-linux64/lib/nvim usr/lib/nvim && \
    mv nvim-linux64/share/nvim/ usr/share/nvim && \
    rm -rf nvim-linux64 && \
    rm nvim-linux64.tar.gz

RUN apt install -y locales && \
    locale-gen ja_JP.UTF-8

# add my dotfiles
RUN git clone -b main https://github.com/WATA-Haru/dotfiles.git

# you can mount your github ssh-key by using docker compose volume
RUN mkdir ~/.ssh

# bash symbolic link
RUN rm -f ~/.bashrc && \
    ln -s /dotfiles/.bash_aliases ~/.bash_aliases && \
    ln -s /dotfiles/.bashrc ~/.bashrc

# nvim symbolic link
RUN rm -rf ~/.config/nvim && \
    mkdir ~/.config/ && \
    ln -s /dotfiles/nvim ~/.config/nvim

# vim symbolic link
RUN rm -f ~/.vimrc && \
    rm -rf ~/.vim && \
    ln -s /dotfiles/vim/vimrc ~/.vimrc && \
    ln -s /dotfiles/vim/vim ~/.vim

# tmux plugin manager install
RUN git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

# tmux symbolic link
RUN rm -f ~/.tmux.conf && \
    ln -s /dotfiles/tmux/tmux.conf ~/.tmux.conf
	
# install npm for lsp
RUN apt-get install -y ca-certificates gnupg && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    NODE_MAJOR=20 && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ 
    apt-get update && \
    apt-get install nodejs -y

# dev tools for 42school
# norminette
RUN python3 -m pip install --upgrade pip setuptools
RUN python3 -m pip install norminette

RUN . ~/.bashrc
RUN nvim +:q

Dockerfilesについて

重要なのはこのコードです。先ほどのdotfilesをcloneしています。

# add my dotfiles
RUN git clone -b main https://github.com/WATA-Haru/dotfiles.git

Dockerfileを作ったらbuildします。

docker build -t dotfiles .

(注意) build後にdotfilesを変更した場合

Dockerfileを作っている途中で変更点に気付き、dotfilesを編集したとします。
この場合、--no-cacheをつけて再びbuildしましょう。

docker build --no-cache -t dotfiles .

Dockerは、Dockerfileに変更がなければ、CACHEされた内容を使いまわします。dotfilesが変更されていたとしてもDockerfile内のリポジトリのURLに変更がないのでDocker側は検知できません。そのため、dotfilesの最新の内容を読み込みたい場合は--no-cacheを指定するというわけです。

※後半にnorminetteという、筆者の入っている学校で使うための設定が入っています。ほとんどの人は必要ありません。自作する方は不要なので消してください。

3. Docker imageをDocker hubにpushする

Docker Hubに登録しておいてください。
リポジトリは自身の<My-Docker-ID>/<My-Repository-Name>になります。自分の好きな名前のリポジトリ名を作成してください。このリポジトリ名はあとで使用します。

1. イメージ名変更
先ほど作ったイメージ(dotfiles)の名前を、登録したリポジトリ名に変更します。

docker tag dotfiles <My-Docker-ID>/<My-Repository-Name>

これで、docker image lsすると、dotfilesと同じIDを持った<My-Docker-ID>/<My-Repository-Name>が確認できます。

2. Docker hubにpush

docker push <My-Docker-ID>/<My-Repository-Name>

4. docker-compose.ymlの作成・volumeの指定

docker-compose.yml
version: '3'
services:
  dotfiles:
    image: hwata001/dotfiles:latest
    volumes:
      - type: bind
        source: "<you-working-dir>"
        target: "/home"
      - type: bind
        source: "<your-ssh-key>" #your github ssh key dir
        target: "/root/.ssh"

<you-working-dir>に自身のマウントしたい作業ディレクトリ
<your-ssh-key>に自身のgithubのsshキーが入っているディレクトリ
を指定してマウントします。

こちら非常に参考になりました。

そして、

docker compose up -d
docker compose run -it dotfiles /bin/bash

これでDocker内のターミナルにアクセスできます。
tmuxも使えます!

image.png

詰まったところとその対応

tmuxでなぜか日本語入力ができない -> tmux -u

tmux -uをエイリアスに指定しました。utf-8が使えるようになるオプションです。

tmuxのpluginを入れたのに背景色が変わらない!(凡ミス) -> PowerShellの設定だった

  • terminal(筆者の環境ではPowershell)本体の色設定が必要でした。
  • Powershellの上部を右クリック->settings->Appearance->背景色変更

tmuxに入ったが、ユーザ名が白いままだ

image.png

こんな感じです。wslと同じようにこうしたかったので、wslの.bashrcを流用しました。
image.png

こちらをご覧ください。
https://github.com/WATA-Haru/dotfiles/blob/main/.bashrc

Neovim, vimのカラースキームの色が変わらない

以下を追加しました。

tmux.conf

set-option -g default-terminal "screen-256color"
set-option -ga terminal-overrides "$TERM:Tc"
set -sa terminal-overrides "*:Tc"
.vimrc
if $TMUX != ""
   let &t_8f = "\<Esc>[38:2:%lu:%lu:%lum"
   let &t_8b = "\<Esc>[48:2:%lu:%lu:%lum"
endif

init.luaの設定はいらない。

参考

NeovimとTmuxのClipboardをホストマシン(windows * wsl)と共有する

※Macでは動作未検証です。

こちらを参考にそのまま書きました。

neovim

init.lua
vim.opt.clipboard = "unnamedplus"

if vim.env.TMUX then
    vim.g.clipboard = {
        name = 'tmux',
        copy = {
            ["+"] = {'tmux', 'load-buffer', '-w', '-'},
            ["*"] = {'tmux', 'load-buffer', '-w', '-'},
        },
        paste = {
            ["+"] = {'tmux', 'save-buffer', '-'},
            ["*"] = {'tmux', 'save-buffer', '-'},
        },
        cache_enabled = false,
    }
end

tmux

tmux.conf
# tmux clipboard
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"

vimでホストマシンのクリップボードからペースト(ctrl + v)した際にインデントが崩れる

こちらを参考にそのまま書きました。

.vimrc
if &term =~ "xterm"
    let &t_ti .= "\e[?2004h"
    let &t_te .= "\e[?2004l"
    let &pastetoggle = "\e[201~"

    function XTermPasteBegin(ret)
        set paste
        return a:ret
    endfunction

    noremap <special> <expr> <Esc>[200~ XTermPasteBegin("0i")
    inoremap <special> <expr> <Esc>[200~ XTermPasteBegin("")
    cnoremap <special> <Esc>[200~ <nop>
    cnoremap <special> <Esc>[201~ <nop>
endif

docker内で、gitのsafe.directoryが指定できない

以下だとなぜかできないときがありました。

 git config --global --add safe.directory <dir>

以下の書き方ならできました。謎です。

git config --system --add safe.directory "${PWD}"

解決していない問題

  1. vimからホストOSへのクリップボード共有(Neovimからはできる)

    vimはホストOSとのクリップボード共有ができませんでした。vim-gtk3をインストールしたり、stack overflowを見たりしても無理でした。何かいい方法があれば教えてください。

  2. コンテナに入るタイミングで毎回githubのユーザ情報を打つ必要がある

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

これを毎回聞かれるので自動化しようとしましたが、Dockerfilesに書く以外の方法が見つからなかったので諦めました。Dockerfileはpublicなので、私の固有の情報は入れたくありませんでした。

参考にした記事

こちらの記事が非常に参考になりました。ありがとうございました。

(再掲) dotfiles Dockerfiles Docker-image 一覧

dotfiles

Dockerfiles

dotfiles Docker image

Docker初心者なので不十分な点があればご指摘ください。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?