WordとPDFによるドキュメント運用を変えたくて、WSL+DockerでMKDocsの環境を立ててみた。

## はじめに

システム開発の現場を中心に近年はコンテナ技術が広く使われるようになり、`Docker` とか `Kubernetes` というソフトウェアの利用が常識になりつつある空気を感じます。

BizRobo!も既にコンテナには対応しており、インストールフォルダの配下には `docker-win` 内に各種サーバ機能の `Dokerfile` や `docker-compose.yml` のサンプルが提供されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/a77d46b8-92b2-f0ce-06e9-c4bb91d0a843.png)

今後社内の環境も `Docker` に移行していこうかなと考えており、今回はその準備運動として業務PCへ `Docker` を構築してみます。

:::note warn
BizRobo!における Docker の利用は、選択肢の提供という観点でマテリアル一式を製品同梱提供しています。
一方で Docker はOSS製品であり、その利用については導入者の判断により各自が運用できる範囲で採用すべきことは前提として記述しておきます。
:::

## WSLの利用要件

WSLとは Windows Subsystem for Linux の略称で、Windows OS上で Linuxを稼働させる仕組みです。現在はWSL2というのが最新ですが、ここ数年で頻繁にバージョンアップしており、バージョンごとの差異が大きく利用できるWindowsのバージョン（Windows10であってもバージョンは複数あり、、、）にも制約があったりで、直近まで興味はあれど着手はしない状態でした。

https://learn.microsoft.com/ja-jp/windows/wsl/about

https://learn.microsoft.com/ja-jp/windows/wsl/compare-versions?source=recommendations

とはいえ先日ついにMicrosoft Store版が正式リリースし、「機は熟した」という判断のもと社内で利用していく動きを始めた次第です。

https://forest.watch.impress.co.jp/docs/news/1456259.html

WSL＋Dockerの利用条件は上記の文脈を含め書き出す[^1]のが面倒なので、今回は以下のPCを「正」として進めていきます。

敢えて言うならば、BIOSレベルで `仮想化テクノロジー`[^2] が有効になっているPCをご用意ください。
```cmd:本稿で使用する業務PCのWindows仕様
エディション	　　Windows 10 Pro
バージョン	　　22H2
インストール日   ‎2023/‎01/‎17
OS ビルド	　　19045.2604
シリアル番号	　　YZ940095
エクスペリエンス	Windows Feature Experience Pack 120.2212.4190.0
```

また、インターネットで「WSL2 インストール」などのキーワード検索で得られるページには軒並み

> 「Windows の機能の有効化または無効化」において 
> * Hyper-V
> * Linux用 Windows サブシステム
> * 仮想マシン プラットフォーム
> * コンテナー
> 
> を有効化してください。

と記載があるものの、解説されているページによって対象としている項目にばらつきがあり、最低限何が本当に必要か不明だったため、今回は敢えて上記の項目はすべて「無効化」してインストールを実施します。（必要なものはインストールの過程で自動的に有効化されました）
<details><summary>無効化した様子の図</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/a3a330a1-091b-3c58-ec8a-f141b94df60a.png)

</details>

最後に、インストール開始前にWSLの状態を確認します。
```powershell:セットアップ前の状態
PS C:\xx\xx> wsl -l -v

Copyright (c) Microsoft Corporation. All rights reserved.

使用方法: wsl.exe [Argument]

引数:
：
```
WSLインストール前なのに「コマンドがありません」ではなく「使用方法」が表示されるのは違和感ですが、そういうものらしいので異常ではありません。

:::note 
作業は主にWindows上の`PowerShell` とWSL上の `bash` を使って実施します。コマンド行の冒頭`PS`から始まるものは`PowerShell`のコマンド、`~$`から始まるものは `bash` のコマンドです。
:::

## WSLのインストール

`PowerShell` を管理者権限で起動し`wsl --install` とコマンドを実行することにより、後は自動的にインストールが実行されます。
```powershell:wsl --install
PS C:\xx\xx> wsl --install
要求された操作には管理者特権が必要です。
：
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
```
ただ今回はうっかり通常モードで実行してしまいました。
それが理由かインストール処理中は進捗表記が文字化けして焦りましたが、最終的には無事インストールできました。

インストールを完了させるために、Windowsを再起動しましょう。

:::note warn
今回は「管理者として実行する」を選ばずにそのまま開いてしまいましたが、その後気づいたこととしてログインユーザ自身に管理者権限が割り当てられているユーザで実行していました。一般ユーザでWSLのインストールをする際には管理者としてPowerShellを実行してください。
<details><summary>管理者として実行する</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/ebeb6842-4820-e7b1-231d-acba4e679391.png)

</details>
:::


再起動後、Windowsへログインするとコンソールが表示されるのでユーザー名とパスワード[^3]を設定します。
```powershell:ディストリビューションのインストール
Ubuntu は既にインストールされています。
Ubuntu を開始しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username ・・・.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: xx
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
：
```

:::note warn
既にWSLがインストールされている端末に対して再インストールを実施した場合、以下のようなエラーが表示された際には個別の対応が必要になります。
```bash
ディスク 'C:\xx\xx\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx'を WSL2 に接続できませんでした: 指定されたファイルが見つかりません。
Error code: Wsl/Service/CreateInstance/MountVhd/ERROR_FILE_NOT_FOUND
続行するには何かキーを押してください...
```

<details><summary>個別の対応詳細</summary>

```powershell:wslのディストリビューションとバージョンの確認
PS C:\xx\xx> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Stopped         2
```
```powershell:ディストリビューションの解除
PS C:\xx\xx> wsl --unregister Ubuntu
登録解除。
この操作を正しく終了しました。
```
解除したうえでディストリビューションを再セットアップ
```powershell:インストール可能なディストリビューション確認
PS C:\xx\xx> wsl -l -o
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
：
```
```powershell:ディストリビューションのインストール
PS C:\xx\xx> wsl --install Ubuntu-22.04
インストール中: Ubuntu 22.04 LTS
Ubuntu 22.04 LTS はインストールされました。
Ubuntu 22.04 LTS を開始しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username ・・・.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: xx
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
：
xx@xx:~$
```
再度確認
```powershell
PS C:\xx\xx> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Running         2
```
</details>
:::

## WSLの初期セットアップ

### OSの最新化
Windows Updateのようなものですね、インストールしたOSのパッケージリストを最新化します。
```bash
xx@xx:~$ sudo apt-get update
[sudo] password for xx:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
：
Need to get 33.6 MB of archives.
After this operation, 121 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 motd-news…
:
```
その後、最新化したパッケージリストに基づいてパッケージを最新化します。
```bash
xx@xx:~$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
：
```

### Systemdを有効にする。
Systemdを有効化し、dockerがWSL起動時に自動的に立ち上がるようにします。

https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/

```bash:事前の状態確認
xx@xx:~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2296  1608 ?        Sl   22:49   0:00 /init
root         4  0.0  0.0   2312    68 ?        Sl   22:49   0:00 plan9 --cont…
root        27  0.0  0.0   2300   100 ?        Ss   22:49   0:00 /init
root        28  0.0  0.0   2316   104 ?        R    22:49   0:00 /init
rpat        29  0.0  0.1   6080  5096 pts/1    Ss   22:49   0:00 -bash
rpat      1537  0.0  0.0   7480  3140 pts/1    R+   22:59   0:00 ps aux
```
#### WSLの設定ファイルを編集

wsl.confファイルを編集し、[boot]以下の記述を追加します。
追記したら `Ctrl+O` で保存し、 `Ctrl+X` でエディタを閉じましょう。
```bash
xx@xx:~$ sudo nano /etc/wsl.conf
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/5d1562f0-0997-db88-da8a-99936df0dcdc.png)
```
[boot]
systemd=true
```

#### WSLの再起動
設定内容を反映させるために、一度 `PowerShell` から WSLを終了させて、再度起動します。[^4] 
```powershell
PS C:\xx\xx> wsl --shutdown
```

WSL再起動後、実行プロセスの状況を `ps aux` コマンドで確認します。
```bash
xx@xx:~$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  1.8  0.3 101408 12232 ?        Ss   23:02   0:00 /sbin/init
root           2  0.0  0.0   2296  1236 ?        Sl   23:02   0:00 /init
root           5  0.0  0.0   2312    68 ?        Sl   23:02   0:00 plan9 --cont…
root          36  0.7  0.3  39472 14908 ?        S<s  23:02   0:00 /lib/systemd/sy…
root          64  0.8  0.1  22084  5728 ?        Ss   23:02   0:00 /lib/systemd/sy…
：
root         352  1.0  0.1  14692  6264 ?        Ss   23:02   0:00 /lib/systemd/sy…
root         388  0.0  0.0   2300   100 ?        Ss   23:02   0:00 /init
root         390  0.0  0.0   2316   104 ?        R    23:02   0:00 /init
rpat         393  0.5  0.1   6080  5088 pts/0    Ss   23:02   0:00 -bash
root         394  0.2  0.1   7524  4880 pts/1    Ss   23:02   0:00 /bin/login -f
rpat         425  1.2  0.2  16940  9052 ?        Ss   23:02   0:00 /lib/systemd/sy…
rpat         426  0.0  0.1 104192  4324 ?        S    23:02   0:00 (sd-pam)
rpat         431  0.5  0.1   6120  4952 pts/1    S+   23:02   0:00 -bash
rpat         448  0.0  0.0   7480  3124 pts/0    R+   23:02   0:00 ps aux
```

PIDの1が /init から /sbin/init に代わっており、systemdが起動していればOKです。

## Dockerのインストール

:::note
Windows PC上でDockerを使うなら Docker Desktop を利用するのが一番簡単だと思いますが、せっかくなので直接Dockerを使う選択をしました。
:::

WSLから docker.io と docker-compose をインストールします。
今回の実施範囲で docker-compose は使いませんが、今後 Dockerを使っていくうえで必要になることは間違いないので一緒にインストールしておきます。

```bash
xx@xx:~$ sudo apt-get install docker.io docker-compose
[sudo] password for xx:
Reading package lists... Done
：
After this operation, 294 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 pigz amd64 2.6-1 [6…
：
Processing triggers for man-db (2.10.2-1) ...
```

インストールした docker のバージョンを確認します。
```
xx@xx:~$ docker -v
Docker version 20.10.21, build 20.10.21-0ubuntu1~22.04.2
```

インストールした docker-compose のバージョンを確認します。
```
xx@xx:~$ docker-compose -v
docker-compose version 1.29.2, build unknown
```

インストール時の状態では以下の様に `docker` コマンドが実行できません（管理者権限が必要）。
```bash
xx@xx:~$ docker container ls
Got permission denied while trying to connect to the Docker daemon socket at 
　　unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
xx@xx:~$
```
ログインユーザでも `docker` コマンドを扱えるようにするために権限の付与を行います。
```bash
xx@xx:~$ sudo usermod -aG docker $USER
```

権限付与を反映させるために、一度 WSLのコンソールを閉じて開きなおします。
```bash
xx@xx:~$ docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```
OKです。



## MKDocsを使ってみよう

今回はマテリアルデザインを反映した `Material for MKDocs` をDockerでセットアップして使ってみましょう。

https://squidfunk.github.io/mkdocs-material/getting-started/

### Dockerでセットアップ

まずは、Dockerイメージがまだ存在していないことを確認します。
```bash:事前確認
xx@xx:~$ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
```

Docker.hubから`Material for MKDocs`のイメージを取得します。
```bash:Docker イメージの取得
xx@xx:~$ docker pull squidfunk/mkdocs-material
Using default tag: latest
latest: Pulling from squidfunk/mkdocs-material
c158987b0551: Pull complete
：
docker.io/squidfunk/mkdocs-material:latest
```
ダウンロードしたイメージを確認します。
```bash:取得イメージの確認
xx@xx:~$ docker images
REPOSITORY                  TAG       IMAGE ID       CREATED        SIZE
squidfunk/mkdocs-material   latest    6f5d2266a3b6   17 hours ago   137MB
```

### ワークフォルダの作成

MKDocsを使ってドキュメントを作成・編集する作業領域を作成します。
Windowsログインユーザのドキュメントフォルダに `MKDocs` というフォルダを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/9dbfd3df-d2e7-9bee-d2cc-1c93eaf6f6f4.png)

WSL上でワークフォルダを指定してMKDocsを初期化します。
```bash
xx@xx:~$ docker run --rm -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material new .
INFO     -  Writing config file: ./mkdocs.yml
INFO     -  Writing initial docs: ./docs/index.md
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/918d9d4d-4fa4-8435-cf9b-747d80ae7f49.png)

* `-v /mnt/c/Users/xx/Documents/MKDocs:/docs` において Dockerコンテナ上のパスとWSL上のパスを紐づけます。Windows上のフォルダを指定する際には区切り文字は `\` ではなく `/` とし、`/mnt/` から始める必要があります。
* 例えば `C:\Users\xx\Documents\MKDocs` は `/mnt/c/Users/xx/Documents/MKDocs` と表すことができます。

### MKDocsの設定

前段初期化処理にて生成された mkdocs.yml の内容を編集します。
テキストエディタを使って以下の様に追記し保存します。
```diff_yaml: mkdocs.yml
site_name: My Docs
+ use_directory_urls: false

```

### 動かしてみる

MKDocsのサーバを起動し、ドキュメントを編集してみます。

```bash
xx@xx:~$ docker run -rm -it -p 8000:8000 -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material
:
            production-ready server instead.
INFO     -  Building documentation...
INFO     -  Cleaning site directory
INFO     -  Documentation built in 0.21 seconds
INFO     -  [15:07:40] Watching paths for changes: 'docs', 'mkdocs.yml'
INFO     -  [15:07:40] Serving on http://0.0.0.0:8000/
```

サーバが起動するとブラウザが自動的に立ち上がります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/f8326275-0861-bdc8-1c4b-fb143447f6be.png)

サーバが動作している状態でワークフォルダ配下の `docs` フォルダ内にテキストファイルを作成し、拡張子を `.md`に変更すると、リアルタイムでサイト側のドキュメントに反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/4470feac-a56d-5819-ef7e-cce7f0193fd4.png)

同様に、`.md` ファイルに `markdown` 形式で記入した情報もファイルを保存するたびにサーバへ反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/2dd360d0-1cd4-9d79-b7b3-f00e03082c29.png)


### 制的サイトのビルド

編集したオンラインドキュメントをビルドし、静的ファイルとしてローカルで利用できるようにしましょう。
実行中のコンテナを `Ctrl＋C`で一度停止し、以下のコマンドを打ちます。
```
xx@xx:~$ docker run --rm -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material build
INFO     -  Cleaning site directory
INFO     -  Building documentation to directory: /docs/site
INFO     -  Documentation built in 1.92 seconds
```

ワークフォルダ直下に `site` というフォルダが生成され、静的サイトとして変換されたリソースが一式展開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/24adf573-1cb0-3e22-78e5-3096a5967f41.png)
フォルダ内の`index.html`をダブルクリックすると、ドキュメントが再現されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/299e766b-602e-6909-10a4-8bd36ad8e7ff.png)

## さいごに：運用のための準備

ここまでで環境の構築手順と大まかな使い方がわかりました。今後MKDocsを使ってドキュメントの開発・管理を実施していくためにやるべきことは多く、次回続きを書く際にはドキュメントの運用システム観点になると思います。

最後に明日からのドキュメント開発に向けた手順とスクリプトを備忘として載せておきます。

### 新規ドキュメントの作成手順

1. PCに [Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code) をインストールします。
1. 新しいドキュメントを作成するためのフォルダを任意の場所に作成し、以下の2つのPowerShellスクリプトファイルを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/deb037b6-00ea-10cc-261a-f6a1d464a1ab.png)
1. 作成したフォルダ上でコンテキストメニュー（右クリック）を表示し、`Code で開く` を選択します。（当該フォルダをカレントフォルダとして Visual Studio Code を開きます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/56686e54-6a6e-66ca-613b-660085c7ae5c.png)
1. Visual Studio Code が起動したら `Ctrl + Shift + @` を押し、ターミナルを表示させます。
1. ターミナルに `.\Start-MKDocs.ps1` と入力し `Enter` を押すと、MKDocs が動き始めます。
1. 終了する場合には必ず `Ctrl + C` で MKDocsサーバを停止しましょう。

```powershell:Start-MKDocs.ps1
# 実行ポートの指定
$port = "8001"

# WSLのDockerイメージを実行するPowerShellコマンド
function Run-DockerImage {
    param(
        [string]$image,
        [string]$workdir,
        [string]$volume,
        [string]$portForward,
        [string]$cmd
    )

    $volumeStr = "/mnt/c" + $volume.Replace('\', '/').Substring(2) + ":" + $workdir

    if( $cmd -eq "new ."){
        $dockerCmd = "docker run --rm -v $volumeStr $image $cmd"
    } else {
        $dockerCmd = "docker run --rm -it -p $portForward -v $volumeStr $image"
    }
    
    # WSLのDockerにアクセスしてコマンドを実行
    & wsl sh -c $dockerCmd
}

# 現在のディレクトリパスを取得する
$currentDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# フォルダが存在するかどうかを確認する
$folderPath = Join-Path $currentDir "docs"
if( !(Test-Path $folderPath) ){
    # 新しいMKDocsプロジェクトを作成する
    Run-DockerImage `
        -image "squidfunk/mkdocs-material" `
        -workdir "/docs" `
        -volume $currentDir + ":/docs" `
        -cmd "new ."
} 

# MKDocsサーバーを起動する
Run-DockerImage `
    -image "squidfunk/mkdocs-material" `
    -workdir "/docs" `
    -volume $currentDir + ":/docs" `
    -portForward ($port + ":8000")

# サーバーが起動したらブラウザで表示する
Start-Process "http://localhost:$port"
```
```powershell:Build-MKDocs.ps1
# WSLのDockerイメージを実行するPowerShellコマンド
function Run-DockerImage {
    param(
        [string]$image,
        [string]$workdir,
        [string]$volume,
        [string]$cmd
    )

    $volumeStr = "/mnt/c" + $volume.Replace('\', '/').Substring(2) + ":" + $workdir
    $dockerCmd = "docker run --rm -v $volumeStr $image $cmd"
    
    # WSLのDockerにアクセスしてコマンドを実行
    & wsl sh -c $dockerCmd
}

# 現在のディレクトリパスを取得する
$currentDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# 新しいMKDocsプロジェクトを作成する
Run-DockerImage `
    -image "squidfunk/mkdocs-material" `
    -workdir "/docs" `
    -volume $currentDir + ":/docs" `
    -cmd "build"

```
### 既存ドキュメントの編集

新規ドキュメントの作成と手順は同じです。実行する `.\Start-MKDocs.ps1` プログラムがフォルダの状況を判断し処理します。

### 作成したドキュメントのビルド

ドキュメントの新規作成と同様に Visual Studio Code のターミナルを開き、`.\Build-MKDocs.ps1` と入力し `Enter` を押します。


## まとめ

DockerというとLinuxコンテナがメインストリームだと思います。Windowsコンテナという方法もありますが、自分たちでまず使用してみようと調べた範囲ではメリットが感じられませんでした。（PCで使う前提だったので）

ということで Docker を使用するための最低限の Linux の知識は必要ですね。
今後、開発環境や検証環境などできるだけ便利に Docker を活用していきたいと思います。

テクサポなどは不具合発生時に複数バージョンの環境で確認作業が必要になる場合もありますが、そのたびにサーバを準備するのは大変ですし、サーバも使い込めば環境が徐々に汚れていきます。

そんな時には Docker をうまく使っていつもクリーンな環境をコマンド一発で構築することで検証・再現テストの準備工数はだいぶ削減できるのかもしれません。（知らんけど）




[^1]: 各WSLのバージョンにより何がどう違うのかという情報は別途よくまとめられているページがインターネット上にはたくさんあるので、正確で詳しい解説はそちらに譲ります。

[^2]: 仮想化テクノロジーに対応しており有効かどうかについては、以下の様にタスクマネージャ > パフォーマンスの画面から確認ください。画面右下部分の「仮想化：」が `有効` であれば大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d15c4259-696e-2bbf-8dac-e79530d062d6.png)

[^3]: WSL上で動作するディストリビューションのユーザ名とパスワードです。

[^4]: WSLを起動する方法としては、`PowerShell` や `cmd` から wslコマンドを実行して起動する方法の他、スタートメニューからWSLを選択してコンソールを起動する方法、インストールしたディストリビューション（Ubuntuなど）を同じくスタートメニューから選択してコンソールを起動する方法などがあります。