オレオレdocker開発環境を作ってみた

俺が使う俺のためのオレオレdocker イメージを作った

* マイナーで容量もでかいarchlinuxベース
* 日本語環境適用
* [自分のdotfiles](https://github.com/u1and0/dotfiles)適用
* (ここから2020.4.30 update)
* [dockerでvolumeをマウントしたときのファイルのowner問題](https://qiita.com/yohm/items/047b2e68d008ebb0f001#%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8F%E6%96%B9%E6%B3%953-dockerfile%E5%86%85%E3%81%A7%E3%81%99%E3%81%A7%E3%81%AB%E4%B8%80%E8%88%AC%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%8C%E4%BD%9C%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88)で一通り悩んだ挙句、dotfilesとかhomeをchownする時間が惜しくて、どうせ自分しか使わないだろうし、結局はUID=1000, GID=1000, USERNAME=u1and0でbuildし直しました。
* u1and0/neovim, u1and0/zplugの継承関係を入れ替えました。
* Python環境をpyenv使わずに再構築しました。
* docker-in-docker環境を新規作成しました。
* docker-compose.ymlを追記しました。
* (ここから2021.1.5 update)
* [archlinux official image](https://hub.docker.com/r/archlinux/archlinux/tags?page=1&name=base-devel) の 毎日アップデートされている方のbase-devel有り版を選択しました。
* Rust環境を新規作成しました。


# ベースイメージと自分の作ったカスタムイメージの継承関係
```sh:docker_images
$ docker inspect --format="{{.Size}}" \
  u1and0/{archlinux,neovim,zplug,vim-go,python-conda,rust,docker}:latest |
  numfmt --to=iec
777M
1.2G
1.3G
2.4G
4.4G
3.3G
1.6G

archlinux/archlinux                   base-devel-20220101.0.42885         716MB      
└── u1and0/archlinux                  v5.1.0      777MB
    └── u1and0/neovim                 v5.1.1      1.2GB
        └── u1and0/zplug              v5.1.1      1.3GB
            └── u1and0/vim-go         v3.0.0      2.4GB
            └── u1and0/python-conda   v1.0.0      4.4GB
            └── u1and0/rust           v1.0.0      3.3GB
            └── u1and0/docker         v1.0.0      1.6GB
```

---
## [u1and0/archlinux](https://hub.docker.com/r/u1and0/archlinux)
![archlinuxpng](https://raw.githubusercontent.com/u1and0/docker_archlinux_env/screenshot/Screenshot%20from%202019-01-29%2022-51-31.png)

* ~~[archlinux/base](https://hub.docker.com/r/archlinux/base)をベースにしました。~~
* 公式の[archlinux/archlinux](https://hub.docker.com/r/archlinux/archlinux/)をベースにしました。
* [u1and0/dotfiles](https://github.com/u1and0/dotfiles) を適用しています。
* pacmanによる公式パッケージだけでなく、yayによるAURパッケージのインストールも可能です。
* パッケージダウンロード元サーバーをreflectorで選択したファイルを`/etc/pacman.d/mirrorlist`に適用しています。(更新日2019.02.01)
* ~~ロケール日本語 > helpとかが日本語表示(しかしmanのインストールでエラー。manを日本語どころか英語でも見れない。解決策模索中)~~ (2020.4.30 update)
* manが見れない問題はpacman.confのNoExtractを消せば見ることが出来ました。[Archlinux docker image man pages?](https://www.reddit.com/r/archlinux/comments/eemnob/archlinux_docker_image_man_pages/) (2021.1.5 update)
* yayをマルチステージビルド化 (2021.1.5 update)

```dockerfile:u1and0/archlinux
# Usage:
# $ docker run -it --rm -v `pwd`:/work -w /work u1and0/archlinux
#
# For building:
# $ git clone https://github.com/u1and0/docker_archlinux_env
# $ docker build --build-arg USERNAME=${USERNAME} --build-arg branch="develop" -t u1and0/archlinux .

# Archlinux official image daily build version
FROM archlinux/archlinux:base-devel

# Get reflector Server setting for faster download
# Same as `reflector --verbose --country Japan -l 10 --sort rate`
COPY pacman.conf /etc/pacman.conf
COPY mirrorlist /etc/pacman.d/mirrorlist

# Japanese setting
ARG SETLANG="ja_JP"
ENV LANG="${SETLANG}.UTF8"\
    LC_NUMERIC="${SETLANG}.UTF8"\
    LC_TIME="${SETLANG}.UTF8"\
    LC_MONETARY="${SETLANG}.UTF8"\
    LC_PAPER="${SETLANG}.UTF8"\
    LC_MEASUREMENT="${SETLANG}.UTF8"

# Locale setting
ARG GLIBVER="2.33"
ARG LOCALETIME="Asia/Tokyo"
RUN : "Copy missing language pack '${SETLANG}'" &&\
    curl http://ftp.gnu.org/gnu/libc/glibc-${GLIBVER}.tar.bz2 | tar -xjC /tmp &&\
    cp /tmp/glibc-${GLIBVER}/localedata/locales/${SETLANG} /usr/share/i18n/locales/ &&\
    rm -rf /tmp/* &&\
    : "Overwrite locale-gen" &&\
    echo ${SETLANG}.UTF-8 UTF-8 > /etc/locale.gen &&\
    locale-gen &&\
    : "Set time locale, Do not use 'timedatectl set-timezone Asia/Tokyo'" &&\
    ln -fs /usr/share/zoneinfo/${LOCALETIME} /etc/localtime

# Package update
# `pacman-key --init` must run at first
RUN pacman-key --init &&\
    pacman-key --populate archlinux &&\
    pacman -Syu --noconfirm git openssh &&\
    : "Clear cache" &&\
    pacman -Qtdq | xargs -r pacman --noconfirm -Rcns

ARG USERNAME=u1and0
# docker build --build-arg USERNAME=${USERNAME} -t u1and0/archlinux .
ARG UID=1000
ARG GID=1000
RUN echo "Build start with USERNAME: $USERNAME UID: $UID GID: $GID" &&\
    pacman -Sy &&\
    : "Add user ${USERNAME} for yay install" &&\
    groupadd -g ${GID} ${USERNAME} &&\
    useradd -u ${UID} -g ${GID} -m -s /bin/bash ${USERNAME} &&\
    passwd -d ${USERNAME} &&\
    mkdir -p /etc/sudoers.d &&\
    touch /etc/sudoers.d/${USERNAME} &&\
    echo "${USERNAME} ALL=(ALL) ALL" > /etc/sudoers.d/${USERNAME} &&\
    mkdir -p /home/${USERNAME}/.gnupg &&\
    echo 'standard-resolver' > /home/${USERNAME}/.gnupg/dirmngr.conf &&\
    chown -R ${USERNAME}:${USERNAME} /home/${USERNAME} &&\
    mkdir /build &&\
    chown -R ${USERNAME}:${USERNAME} /build

# yay install
COPY --from=u1and0/yay:latest /usr/bin/yay /usr/bin/yay

# My dotfiles
WORKDIR /home/${USERNAME}
USER ${USERNAME}
# `--build-arg=branch=v1.15.1` のようにしてブランチ名、タグ名指定しなければ
# デフォルトではdevelopブランチをcloneしてくる
ARG branch="develop"
RUN git clone --branch $branch\
    https://github.com/u1and0/dotfiles.git dotfiles &&\
    : "Replace dotfiles" &&\
    mv -f dotfiles/.git . &&\
    git reset --hard &&\
    rm -rf dotfiles

CMD ["/bin/bash"]

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="archlinux image. AUR packages are able to install by yay. yay -S {package}"\
      description.ja="Archlinux イメージ。yayによるAURパッケージインストール可能. yay -S {package}, dotfiles develop branch"\
      version="arlhlinux:5.1.0"
```

---
## [u1and0/neovim](https://hub.docker.com/r/u1and0/neovim)
![neopng](https://raw.githubusercontent.com/u1and0/docker_neovim_env/u1and0-screenshot/Screenshot%20from%202019-01-27%2014-29-20.png)

* u1and0/archlinuxをベースにしました。
* この記事はこのdockerイメージを使って書きました。
* <kbd>C-J</kbd>から始まるキーバインドでdenite, 例えば<kbd>C-J</kbd><kbd>C-N</kbd>で現在ディレクトリ下のファイル検索、<kbd>C-J</kbd><kbd>C-F</kbd>で現在ファイルを検索
* <kbd>F5</kbd>でファイラーNERDTreeをサイドバーで開く
* などなど

```dockerfile:u1and0/neovim
# Neovim container
# *Using my dotfiles
# *Get plugins by dein
# * Inherit from u1and0/archlinux <- archlinux/base
#
# Usage:
#    $ docker pull u1and0/neovim
#    $ docker run -it --rm -v `pwd`:/work -w /work u1and0/neovim nvim [filenames] ...

FROM u1and0/archlinux:latest

# Neovim install
# USER u1and0 or somebody except root
RUN yay -Syyu --noconfirm neovim\
                        python-neovim\
                        fd\
                        fzf\
                        ripgrep\ 
                        w3m\
                        pygmentize\
                        ctags\
                        global \
                        man \
                        man-pages-ja &&\
    : "Remove all packages cache " &&\
    yay -Scc --noconfirm

# Plugins insall
# Install & Update plguins & vimproc
RUN nvim +UpdateRemotePlugins +VimProcInstall +q

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="OS=archlinux, editor=neovim, dotfiles=u1and0/dotfiles, plugin manager=dein"\
      version="neovim:v5.1.1"
```

---
## [u1and0/zplug](https://hub.docker.com/r/u1and0/zplug)
![zplugpng](https://raw.githubusercontent.com/u1and0/docker_zplug/u1and0-patch-1-1/Screenshot%20from%202019-01-27%2017-44-12.png)

* u1and0/neovimをベースにしました。
* docker hubのビルドテストは何故か失敗していますが、ローカル環境でのビルドは成功しています。リモートのビルドが失敗する原因を調査中。
* 別環境のWindows上のVirtualBox内のArchlinuxで`docker run u1and0/zplug`で動作確認しました。

```dockerfile:u1and0/zplug
# zsh/zplug container
# * zshell powered by zplug
# * Using my dotfiles
# * Inherit from u1and0/neovim <- u1and0/archlinux <- archlinux/base
#
# Usage:
#    $ docker pull u1and0/zplug
#    $ docker run -it --rm -v `pwd`:/work -w /work u1and0/zplug

FROM u1and0/neovim:latest

# Reinstall packages required by zplug
RUN sudo pacman -Syyu --noconfirm zsh awk git tig &&\
    : "Remove cache" &&\
    pacman -Qtdq | xargs -r sudo pacman --noconfirm -Rcns

# Install zplug plugins
RUN git clone --depth 1 https://github.com/zplug/zplug .zplug &&\
    zsh -ic "source .zshrc &&\
            source .zplug/init.zsh &&\
            source .zplug.zsh &&\
            zplug install"
ENV SHELL="/usr/bin/zsh"
CMD ["/usr/bin/zsh"]

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="OS=archlinux editor=neovim shell=zsh_with_zplug"\
      version="zplug v5.1.1"
```

---
## [u1and0/vim-go](https://hub.docker.com/r/u1and0/vim-go)
![vimgopng](https://raw.githubusercontent.com/u1and0/docker_vim-go/screenshot/Screenshot%20from%202019-01-27%2020-42-18.png)

* u1and0/neovimをベースにしました。
* [fatih/vim-go](https://github.com/fatih/vim-go), ~~[zchee/deoplete](https://github.com/zchee/deoplete-go)~~  プラグインインストール済み(2020.4.30 update)
* `:GoInstallBinaries`で手に入るツール取得済み

```dockerfile:u1and0/vim-go
# Usage:
# docker run -it --rm -v `pwd`:/work -w /work u1and0/golang

FROM u1and0/zplug:latest

# Install go
RUN sudo pacman -Syu --noconfirm go &&\
    pacman -Qtdq | xargs -r sudo pacman --noconfirm -Rcns
# pacman -Scc の代わり

# gopath setting
# go install より前に指定する
ARG LOUSER=u1and0
ENV GO111MODULE="on"\
    GOPATH="/home/${LOUSER}/go"\
    PATH="$GOPATH/bin:$PATH"

# May be included vim-go GoUpdateBinaries command
# Install go tools
# RUN go install \
#         golang.org/x/tools/gopls@latest \
#         golang.org/x/tools/cmd/goimports@latest \
#         golang.org/x/tools/cmd/guru@latest \
#         golang.org/x/tools/cmd/gorename@latest &&\
#     go clean -cache
# RUN go get -u \
#         github.com/golangci/golangci-lint/cmd/golangci-lint \
#         golang.org/x/lint/golint \
#         github.com/rogpeppe/godef \
#         github.com/kisielk/errcheck \
#         github.com/jstemmer/gotags \
#         github.com/klauspost/asmfmt/cmd/asmfmt \
#         github.com/fatih/motion \
#         github.com/zmb3/gogetdoc \
#         github.com/josharian/impl \

# Install vim-go & LSP server
RUN nvim +GoUpdateBinaries +LspInstallServer +q && go clean -cache

# Install REPL
RUN go install github.com/x-motemen/gore/cmd/gore@latest &&\
    go install github.com/stamblerre/gocode@latest &&\
    go get github.com/k0kubun/pp@latest &&\
    go clean -cache

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="golang env with neovim"\
      description.ja="golang開発環境with neovim"\
      version="vim-go:v3.0.0"
```

---
## [u1and0/docker_python-conda](https://hub.docker.com/r/u1and0/python-conda)
noimage

```dockerfile:u1and0/python-conda
# Python dev docker image
#
# Usage:
#   In host machine's shell
#     $ docker pull u1and0/python-conda
#     $ docker run -it --rm -v `pwd`:/work -w /work u1and0/python-conda
#
#   Using other command with activating `conda`
#     $ docker run -it --rm -v `pwd`:/work -w /work\
#           u1and0/python-conda bash -c ". .bashrc && python"
#     $ docker run -it --rm -v `pwd`:/work -w /work\
#           u1and0/python-conda bash -c ". .bashrc && ipython"
#     $ docker run -it --rm -v `pwd`:/work -w /work\
#           u1and0/python-conda bash -c ". .bashrc && nvim"
#     $ docker run -P -it --rm -v `pwd`:/work -w /work\
#           u1and0/python-conda bash -c ". .bashrc && jupyter notebook"
#
#   In contaner
#     Just type
#     $ ipython
#         or
#     $ jupyter notebook
#         or
#     $ nvim

FROM u1and0/zplug:latest

# !!
# USER=u1and0 not root user
# !!

# Install miniconda3-latest & restore conda packages
RUN yay -Syyu --noconfirm miniconda3 &&\
    yay -Scc &&\
    sudo ln -s /opt/miniconda3/etc/profile.d/conda.sh /etc/profile.d/conda.sh

RUN sudo pacman -Syyu --noconfirm python-pip otf-ipafont &&\
    pacman -Qtdq | xargs -r sudo pacman --noconfirm -Rcns

ENV PATH /etc/profile.d/:$PATH

# Base packages
RUN source /etc/profile.d/conda.sh &&\
    sudo conda install --quiet --yes \
        numpy \
        pandas \
        scipy \
        matplotlib \
        seaborn \
        more-itertools \
        h5py \
        line_profiler \
        ipython \
        jupyter \
        notebook \
        conda-forge::jupyterthemes \
        conda-forge::jupyter_contrib_nbextensions \
        conda-forge::neovim \
        flake8 \
        pyflakes \
        pylint \
        pygments \
        yapf \
        autopep8 \
        conda-build &&\
    sudo conda remove --quiet --yes --force qt pyqt && \
    : "clean cache" &&\
    conda build purge-all

# Dev packages
RUN source /etc/profile.d/conda.sh &&\
    sudo conda install --quiet --yes \
        scikit-learn \
        plotly \
        conda-forge::cufflinks-py \
        dash \
        dash-renderer \
        dash-core-components \
        dash-html-components \
        dash-table &&\
    sudo conda remove --quiet --yes --force qt pyqt && \
    : "clean cache" &&\
    conda build purge-all

# !!
# SHELL=/usr/bin/zsh at parent layer
# !!

EXPOSE 8888

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="python dev container"\
      description.ja="python開発用コンテナ。ipython, jupyter notebook, neovimによる開発"\
      build_version="python:v1.0.0"
```

---
## [u1and0/rust](https://hub.docker.com/r/u1and0/rust)
noimage

```dockerfile:u1and0/rust
# Usage:
# docker run -it --rm -v `pwd`:/work -w /work u1and0/rust

FROM u1and0/zplug:latest

# Install Rust
RUN : "Setup Rust" &&\
    curl -sSf https://sh.rustup.rs | sh -s -- -y

RUN source ${HOME}/.cargo/env &&\
    : "Setup Rust nightly version" &&\
    rustup toolchain install nightly-2021-06-07 &&\
    rustup default nightly-2021-06-07
RUN source ${HOME}/.cargo/env &&\
    : "Install racer-src" &&\
    cargo install racer
RUN source ${HOME}/.cargo/env &&\
    : "Install Rust Language Server" &&\
    rustup component add rust-analysis \
                         rust-src
# rls install tips [Nightly Rustにおいて、RLSがrustupコマンドでインストールできない時に代わりに探してくれるツール(cargo-rls-install)を作った](https://qiita.com/s4i/items/0538f7fe4874980ccf27)
RUN source ${HOME}/.cargo/env &&\
    : "Install rls Rust Language Server" &&\
    cargo install cargo-rls-install \
                  cargo-edit &&\
    cargo rls-install -y
#RUN :"Install rust-doc" &&\
    # curl -fsSL https://static.rust-lang.org/dist/rust-1.0.0-i686-unknown-linux-gnu.tar.gz | tar -xz

LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="rust lang env with neovim"\
      version="rust:v1.0.0"
```

---
## [u1and0/docker](https://hub.docker.com/r/u1and0/docker)
noimage

```dockerfile:u1and0/docker
# My shell env built on Archlinux.
# docker manager for docker.
# sync docker directory of host machine.
#
# * docker
# * tmux
# * neovim
# * zsh( zplug )
# * dotfiles(@u1and0)
#
# Usage:
#     `docker run -it -v /var/run/docker.sock:/var/run/docker.sock u1and0/docker` -v `pwd`:/work

FROM u1and0/zplug:latest

# Install tmux && tmux-plugins
RUN git submodule update --init --recursive .tmux/plugins/tpm &&\
    sudo pacman -Syyu --noconfirm tmux &&\
    ${HOME}/.tmux/plugins/tpm/scripts/install_plugins.sh &&\
    pacman -Qtdq | xargs -r sudo pacman --noconfirm -Rcns

# Install docker
RUN sudo pacman -Syyu --noconfirm docker pigz &&\
    pacman -Qtdq | xargs -r sudo pacman --noconfirm -Rcns

ENV SHELL "/usr/bin/zsh"
CMD ["/usr/bin/zsh"]
LABEL maintainer="u1and0 <e01.ando60@gmail.com>"\
      description="Docker in Docker with archlinux image"\
      version="v1.0.0"
```

詳しくはページ上のREADMEで。


## docker compose

`docker-compose up`するだけで環境が整う

```yaml:docker-compose.yml
# maintainer: u1and0 <e01.ando60@gmail.com>
# version 3.7 for docker version 18.06+
# see https://docs.docker.com/compose/compose-file/
# What for:
#    docker in docker dev.env
#
#    * master: zsh & zplug env. Parents for all docker image.
#    * jupyter: python env. It can use ipython & jupyter
#    * vim-go: golang env.
#
# Usage:
#	 $ cd /path/to/composeset
#    $ docker-compose up
#    $ docker exec -it composeset_master_1 zsh -l
#
# 	 # Login master container then...
#    $ tmux
#
#    # Login go env
#    $ docker exec -it composeset_vim-go_1 zsh -l
#
#    # Login python env
# 	 $ docker exec -it composeset_jupyter_1 bash -c ". .bashrc && zsh"
#
#    # Login python env as ipython
# 	 $ docker exec -it composeset_jupyter_1 bash -c ". .bashrc && ipython"
#
#    # Setup git after login
#    $ git stash
#    $ git fetch
#    $ git checkout origin/develop
#    $ git switch -c develop
#    $ git stash pop
#       for shortly
#    $ gst && g fetch && gch origin/develop && g switch -c develop && gst pop
#
#    # Setup pacman after login
#    $ pacman -Sy archlinux-keyring
#    $ pacman -Syu
version: '3'
services:

    master:
        image: "u1and0/docker:latest"
        tty: true
        volumes:
            - "${HOME}:/home/u1and0/home"
            - "${HOME}/Dropbox:/home/u1and0/Dropbox"
            - "${HOME}/.zsh_history:/home/u1and0/.zsh_history"
            - "${HOME}/yankring_history_v2.txt:/home/u1and0/yankring_history_v2.txt"
            - "/mnt/e/Users/U1and0:/mnt/e"
            - "/var/run/docker.sock:/var/run/docker.sock"
        restart: "always"
        environment:
            - "HOST=master"
        ports:
            - "8000:8000"

    jupyter:
        # jupyter tagはpasswordを設定したイメージ
        # [Jupyter on Dockerでパスワードの設定方法が分からないあなたへ](https://qiita.com/Yusuke-Shimizu/items/731ca71b3c4c3649ec7f)
        image: "u1and0/python-conda:latest"
        volumes:
            - "${HOME}:/home/u1and0/home"
            - "${HOME}/Dropbox:/home/u1and0/Dropbox"
            - "${HOME}/.zsh_history:/home/u1and0/.zsh_history"
            - "${HOME}/yankring_history_v2.txt:/home/u1and0/yankring_history_v2.txt"
            - "/mnt/e/Users/U1and0:/mnt/e"
        environment:
            - "PYTHONPATH=/home/u1and0/Dropbox/Program/python"
            - "HOST=conda"
        command: "bash -c '. .bashrc && jupyter notebook'"
        ports:
            - "8888:8888"  # jupyter notebook
            - "8880:8880"  # plotly dash

    vimgo:
        image: "u1and0/vim-go:latest"
        tty: true
        volumes:
            - "${HOME}:/home/u1and0/home"
            - "${HOME}/Dropbox:/home/u1and0/Dropbox"
            - "${HOME}/.zsh_history:/home/u1and0/.zsh_history"
            - "${HOME}/yankring_history_v2.txt:/home/u1and0/yankring_history_v2.txt"
            - "/mnt/e/Users/U1and0:/mnt/e"
        environment:
            - "HOST=vim-go"
            # - "GOPATH=/home/u1and0/go"
        working_dir: "$GOPATH"
        ports:
            - "8080:8080"
        cap_add:
            - "SYS_PTRACE" # for golang debugger

    rust:
        image: "u1and0/rust:latest"
        tty: true
        volumes:
            - "${HOME}:/home/u1and0/home"
            - "${HOME}/Dropbox:/home/u1and0/Dropbox"
            - "${HOME}/.zsh_history:/home/u1and0/.zsh_history"
            - "${HOME}/yankring_history_v2.txt:/home/u1and0/yankring_history_v2.txt"
            - "/mnt/e/Users/U1and0:/mnt/e"
        environment:
            - "HOST=rust"
        ports:
            - "8089:8089"
```



# なぜArchlinuxか
## 新しいバージョンのパッケージが手に入りやすいから
`pacman -S [package name]` で最新版のパッケージをインストールします。
UbuntuやCentOSに落ちているパッケージは古い安定版が多いですが、Archlinux標準のパッケージマネージャ`pacman`を使えばより新しいバージョンを手に入れることができます。

Archlinuxは[ローリング・リリース](https://ja.wikipedia.org/wiki/Arch_Linux#%E3%83%AD%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%BB%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9)
方式を取るLinuxディストロです。
pacmanデータベースが管理している最新のパッケージ同士の依存関係を解決することがOSアップデートの役割も担っています。


## pacman使いたいから
上と同じ。[MSYS2](https://www.msys2.org/)や[Cmder](http://cmder.net/)からUNIX入門したので、パッケージマネージャーはpacman[^1]が一番慣れているし、pacmanが一番いいパッケージマネージャだとと思ってます。(デスクトップPCはUbuntuユーザー、仮想環境はArchlinuxユーザー。)
bacpacというpacmanのバックアップツールがあり、ワンコマンドで次の機能が使えます。
* pacmanで入れたパッケージのgistへのバックアップ
* ローカルへ復元
* バックアップしたパッケージのリスト表示
* バックアップと現在インストール状況の差分表示
forkして自分で使いやすく改造しています[u1and0/bacpac](https://github.com/u1and0/bacpac)。
[bacpacの親リポジトリ](https://github.com/davidbailey00/bacpac)はメンテナンスを終了しています。


## AURからもインストールできる
yay[^2]をインストールしてあるdockerイメージをベースにしているのでyayがつかえます。
`pacman -S`で見つからないパッケージはたいてい`yay -S`で手に入ります。
yayは [AUR](https://blog.tiqwab.com/2017/07/10/aur.html)からパッケージを落としてきます。
Ubuntuでいう`apt-add-repository [reponame] && apt install [packagename]`を`yay -S [packagename]`で済ませるということですね。


## 実験用
上述の通りArchlinuxベースのコンテナは最新版のパッケージを手に入れやすいので、パッケージの最新機能を試してはコンテナを壊して、再構築してまた試して、という使い方を想定しています。
dockerはきれいな本番環境を作っていく目的にもいいですが、こういう実験的環境構築にも向いていると思います。
Archlinuxは上述したようなアップデート方式から「永遠の不安定版」と呼ばれているので、実機環境よりは仮想環境向きでしょう。


# Powerlineフォントについて
三角形のフォントを表示するにはホストマシンに[Powerline font](https://github.com/powerline/fonts)のインストールと「ターミナルのフォント変更作業」が必要です。
インストール方法はgithubに書かれているので従ってください。


# docker開発環境を作ってみたとき気づいたメリットとデメリット

## メリット
* エラーやワーニングがでないようにdotfilesを最適化できた
* Dockerfileが出来上がってしまえば環境の再構築がVirtualBoxよりも早い
* Go開発の環境構築がワンコマンドですむようになった


    1. git pull https://github.com/u1and0/dotfiles
    2. 初回はdotfilesをホームに置き換え
    3. 初回はneovimプラグインインストール
    4. :GoInstallBinariesで長時間待つ
    ↓
    1. docker pull u1and0/vim-goで長時間待つ

* (ここから2020.4.30 update)
* Go開発に限らずなんの環境でも自分のdotfilesが摘要済み、プラグインインストール済みの環境が整う
* docker-composeを使えばますますラクさを実感できる


## デメリット
* dotfilesが個人依存なので配布できる形で公開する意味はあるのか？dotfilesにinstallスクリプトも用意してあるし、ダブりじゃないか？
* ~~dotfiles更新の度にレイヤーの更新をする仕事が増えた~~ コンテナ内でgit pullして適用する。気が向いたらイメージアップデートするときに親のu1and0/archlinuxイメージのdotfileをアップデートする。~~masterブランチにdotfilesの最新版を挙げておけば`docker build --no-cache(適宜) -t u1and0/archlinux .`で自動的に更新できるので、結果的に仕事は楽になる。(2020.4.30 update)~~ Dockerhubでautomate buildを利用するには有料版にアップデートしないといけません。(2021.1.5 update)
* ~~historyが残らないのがツラい。開発においては過去のコマンドも資産なので。~~ >> docker-compose上で解決.docker-composeじゃなくても`docker run -v`のボリュームで共有すれば解決すると思う(2020.4.30 update)
* ~~historyを残すにはホストマシンとボリューム共有してhistoryファイルをリンクするとかcommitするとか一手間必要。~~(2020.4.30 update)
* レイヤーが重い。ディスク容量を食いつぶす。VirtualBoxでさえディスク容量食いつぶしてるのに。これは最適化の余地あり
* ホストにもゲストにも同じバイナリ（基本的なgrepとかvimとか、/binとか/usr/bin下にあるようなやつら）があって「それってエコシステムなの？」と自問自答している


## 総評
(ここから2020.4.30 update)

* 使って１年以上経つけど、docker-compose使ってますますコンテナ開発環境が手放せなくなりました。
* k8sはフクザツすぎて勉強を断念しました。
* ~~multipassはポートフォワーディングのやり方がわからなくて止まっています。誰か教えてください。~~
    * multipassのポートフォワーディング記事化 → [Windows上でLinux活動するための環境構築します](https://qiita.com/u1and0/items/d9876c8002d5c88a0149)

[^1]: [archlinux wiki pacman](https://wiki.archlinux.jp/index.php/Pacman)
[^2]: [Arch Linux – AURヘルパー「yay」を試す](https://slacknotebook.com/testing-out-arch-linux-aur-helper-yay/)