DockerでubuntuのPlayground環境をつくる

# きっかけ

手元のPCで何らか開発を行うには、当然まず環境を整える必要があります。

例えばWebアプリを作るとして、私が理解している範囲で作ろうとすると、

* GoogleCloudPlatform
* FireBase
* Python + FastAPI
* Dart + Flutter

このあたりの開発環境整備が必要になります。

ところで、今目の前にあるMacはもちろん既に環境が整っているわけですが、これら環境整備に必要な手順を技術記事にしてみようと思ったら、はて、どうするのがいいんでしょうか。（みなさんどうしてるんでしょう）

例えば、Pythonの開発環境を以下で整備するとして、

anyenv + pyenv + poetry

この整備手順の記事を書いてみようと思っても、すでに環境が整っている手元のMacでは手順を再現できません。
実際に手順を実行してみて、実際のコンソールの表示を記事に記載したり、手順に誤りがないか確認しながら記事にしたいのに、面倒くさくなってやめちゃいます。


## DockerでubuntuのPlayground環境を作ることにした

というわけで、DockerでubuntuのPlaygroundな環境を作り、そこで環境整備手順を再現させて、その記録を元に記事を書くのがいいのかなと考えました。ただ、素のubuntuのイメージを起動するだけだと不便なので、以下を含むイメージを作ります。

* デスクトップ環境（LXDE）
* 日本語環境
* curl/wget/git
* コピペ
* VNCサーバ
* Homebrew
* asciinema
* anyenv

```text:dockerfileと起動スクリプト
.
├── dockerfile
└── start.sh
```

```Dockerfile:dockerfile
FROM ubuntu:20.04

RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y \ 
    lxde \
    fcitx-mozc \
    language-pack-ja-base \
    language-pack-ja \
    fonts-ipafont-gothic \
    fonts-ipafont-mincho \
    sudo \
    curl \
    wget \
    git \
    autocutsel \
    tigervnc-standalone-server tigervnc-xorg-extension

# Install visual code
WORKDIR /opt
RUN curl -L https://go.microsoft.com/fwlink/?LinkID=760868 -o vscode.deb && \
    apt install ./vscode.deb

# Locale
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo 'Asia/Tokyo' > /etc/timezone
RUN locale-gen ja_JP.UTF-8 \
    && echo 'LC_ALL=ja_JP.UTF-8' > /etc/default/locale \
    && echo 'LANG=ja_JP.UTF-8' >> /etc/default/locale
ENV LANG=ja_JP.UTF-8 \
    LANGUAGE=ja_JP:ja \
    LC_ALL=ja_JP.UTF-8

# User
ENV USER=hogeuser \
    PASSWD=password

RUN groupadd -g 1000 developer && \
    useradd  -g      developer -G sudo -m -s /bin/bash ${USER} && \
    echo $USER:$PASSWD | chpasswd
    
RUN echo 'Defaults visiblepw' >> /etc/sudoers
RUN echo $USER 'ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers


# Start script
COPY start.sh /opt/
RUN chmod +x /opt/start.sh

# Change user
USER ${USER}
WORKDIR /home/${USER}

# Install homebrew
RUN echo ${PASSWD} | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
RUN echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/${USER}/.profile
ENV PATH $PATH:/home/linuxbrew/.linuxbrew/bin

# Install asciinema
RUN brew install asciinema; exit 0

# Install anyenv
RUN git clone https://github.com/anyenv/anyenv ~/.anyenv
RUN echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
ENV PATH $PATH:/home/${USER}/.anyenv/bin
RUN anyenv init; exit 0
RUN echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
RUN yes | anyenv install --init

# Command
CMD ["/opt/start.sh"]
```

### 起動用シェルスクリプト

```sh:start.sh
#!/bin/bash -e

# Set login use rname
echo "USER: $USER"
export USER=${USER}

# Set login password
echo "PASSWD: $PASSWD"
mkdir ${HOME}/.vnc \
    && echo ${PASSWD} | vncpasswd -f > ${HOME}/.vnc/passwd \
    && chmod 600 ${HOME}/.vnc/passwd
touch ${HOME}/.Xresources

echo "#############################"

## Run VNC server
vncserver :1 -geometry 1280x800 -depth 24 -localhost no  -fg
```

上記２つを見てわかるように、GUIの表示にVNCを利用するので、VNCクライアントが必要になります。
自分は以下を使っています

https://www.realvnc.com/en/connect/download/viewer/


## Dockerイメージをビルド

```shell-session
$ docker build -t ubuntu-playground .
```

## コンテナを実行
```shell-session
$ docker run -p 5901:5901 ubuntu-playground
```

## VNCクライアントから127.0.0.1:5901へ接続

dockerfileに記載してあるuser/passwordでVNC接続するとデスクトップが表示されます。
起動時にいくつかダイアログとエラーが出ますが、とりあえず気にしないことにします。
（このあたりは、デスクトップ環境の設定ファイルをDockerホスト側に持たせてから設定変更するとうまくいくようになる）

![スクリーンショット 2022-03-11 20.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123579/2d9941c6-9e58-b2e4-daba-c5a048cf046d.png)

## asciinemaを利用して作業手順を記録する

たとえば `anyenv`で`pyenv`をインストール。そこから `Python3.8.12`をインストールするには、

(1) `$ anyenv install pyenv`

<script id="asciicast-gLFBUdzB30aUmVNl0fE1Lb9eS" src="https://asciinema.org/a/gLFBUdzB30aUmVNl0fE1Lb9eS.js" async></script>

(2) 表示の通りに、`$ exec $(SHELL) -l`を実行するか、新しいセッションを開く

```
$ exec $(SHELL) -l
```

(3) pythonのビルドに必要なものをインストールしてから、 `$ pyenv install 3.8.12` を実行 (表示がすこし崩れてしまった。。)

<script id="asciicast-oCCiRTWzfwqfjYX5adOlSBy6t" src="https://asciinema.org/a/oCCiRTWzfwqfjYX5adOlSBy6t.js" async></script>

こんなかんじで、記事が書けるかな。（mac向けになってない気もするけど、、）


### ちなみに

記事を書くための環境というよりも、単純にLinuxで何でも遊べる環境があるのが楽しい気がしてきました。
`pluseaudio`を利用すれば音声も再生できるし、VNC経由のGUIもかなり高速に動作するのでストレスないので楽しいです。