Windows11のWSL2でSingularity上のAnaconda仮想環境を構築する手順 [外部SSD保存]

# 概要 #
本記事では、Windows11でWSL2をセット、Linuxディストリビューションをインストールし、Anaconda仮想環境を持つUbuntu 22.04のSingularityイメージを作成、起動したコンテナでJupyter notebookを実行するまでの手順を説明しています。

※外部SSDにコンテナイメージを作成して使用する場合の手順を記載しています。

## WSL２導入

１．コントロールパネル->プログラム->windowsの機能の有効化または無効化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872129/9ae98480-ecad-a1f2-6250-324d46130f38.png)

２．「Hyper-V」「Linux用Windowsサブシステム」にチェックを入れ、OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872129/a0a3df03-bb48-387b-8b4c-45362b163b55.png)

３．PCを再起動

４．PowerShellを管理者権限で起動

５．WSLの最新バージョンをインストール

`wsl.exe --update`

:::note warn
５．を実行せずにUbuntuをインストールしようとしたところ、インストール後に自動で開く`Ubuntu22.04.3 LTS`ウインドウにて下記のエラーが発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872129/4a2f449e-ad7d-7800-62b4-dfb5f419baa2.png)

この場合、メッセージにて指定されているURLを確認し、`手順4-Linuxカーネル更新プログラムパッケージをダウンロードする手順`と`手順 5 - WSL 2 を既定のバージョンとして設定する`の内容を実施することで、エラーを解消できます。
:::

６．WSL2をデフォルトにセット
`wsl --set-default-version 2`

７．Ubuntuをインストール
下記コマンドを実行
`wsl --install d Ubuntu-22.04`

→`Ubuntu 22.04 LTS は既にインストールされています。Ubuntu 22.04 LTS を起動しています...`と表示され、Ubuntuの起動を確認

８．singularityをダウンロード

ubuntu上で下記を実施
```
wget https://github.com/sylabs/singularity/releases/download/v4.0.0/singularity-ce_4.0.0-jammy_amd64.deb
```
## singularityイメージ構築

９．singularityをインストール

```
sudo apt install ./singularity-ce_4.0.0-jammy_amd64.deb
```

```:下記エラーが発生
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
 singularity-ce : Depends: libfuse2 (>= 2.6) but it is not installable
Depends: uidmap but it is not installable
Recommends: squashfs-tools-ng but it is not installable
E: Unable to correct problems, you have held broken packages.
```

以下を実施することで、インストールを完了
　　1.`sudo apt-get update`でaptの更新
　　2.`sudo apt-get install -f`でaptの破損ファイルを修復
　　3.`sudo apt-get install -y libfuse2 uidmap squashfs-tools-ng`
　　 　で、インストールできていなかったパッケージをインストール
　　4.	再度、`sudo apt install ./singularity-ce_4.0.0-jammy_amd64.deb`を実行

```:出力メッセージ抜粋
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'singularity-ce' instead of './singularity-ce_4.0.0-jammy_amd64.deb'
The following additional packages will be installed:
  cryptsetup-bin runc
The following NEW packages will be installed:
  cryptsetup-bin runc singularity-ce
0 upgraded, 3 newly installed, 0 to remove and 84 not upgraded.
Need to get 4412 kB/36.7 MB of archives.
After this operation, 154 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 /home/OOOO/singularity-ce_4.0.0-jammy_amd64.deb singularity-ce amd64 4.0.0-jammy [32.3 MB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 cryptsetup-bin amd64 2:2.4.3-1ubuntu1.2 [145 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 runc amd64 1.1.7-0ubuntu1~22.04.2 [4267 kB]
Fetched 4412 kB in 4s (1093 kB/s)
Selecting previously unselected package cryptsetup-bin.
(Reading database ... 24249 files and directories currently installed.)
Preparing to unpack .../cryptsetup-bin_2%3a2.4.3-1ubuntu1.2_amd64.deb ...
Unpacking cryptsetup-bin (2:2.4.3-1ubuntu1.2) ...
Selecting previously unselected package runc.
Preparing to unpack .../runc_1.1.7-0ubuntu1~22.04.2_amd64.deb ...
Unpacking runc (1.1.7-0ubuntu1~22.04.2) ...
Selecting previously unselected package singularity-ce.
Preparing to unpack .../singularity-ce_4.0.0-jammy_amd64.deb ...
Unpacking singularity-ce (4.0.0-jammy) ...
Setting up cryptsetup-bin (2:2.4.3-1ubuntu1.2) ...
Setting up runc (1.1.7-0ubuntu1~22.04.2) ...
Setting up singularity-ce (4.0.0-jammy) ...
Processing triggers for man-db (2.10.2-1) ...
N: Download is performed unsandboxed as root as file '/home/ OOOO /singularity-ce_4.0.0-jammy_amd64.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
```

１０．外部SSDにマウント
```:dドライブにマウント
OOOOO:~$ sudo mkdir /mnt/ssd
OOOOO:~$ sudo mount -t drvfs D: /mnt/ssd -o metadata,uid=1000,gid=1000,umask=022
```
:::note info
`-o`オプションを指定することで、マウントされたファイルシステムが適切に扱われ、ファイルのpermissionや所有者情報が維持されます。
:::

１１．外部SSDをマウントした場所へ移動

```
cd /mnt/ssd
```

１２．singularity definitionファイルの作成

singularityのコンテナイメージ(.sif)を作成するための設定ファイル(.def)を作成する。
ここでは、ubuntu 22.04上のAnadconda仮想環境でjupyter notebookを使用するための設定ファイルを用意する。

```:.defファイルの例
Bootstrap: docker
From: ubuntu:22.04

%post
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
    apt-get -y update
    apt-get -y upgrade
    apt-get -y install language-pack-ja git nano zsh vim
    apt-get -y install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl
    apt-get -y install llvm libncurses5-dev libncursesw5-dev libpng-dev protobuf-compiler python3-pil python3-lxml python-tk
    apt-get install libreadline-dev
    apt -y install libvips libvips-dev
    apt -y install libgl1-mesa-dev
    export PYENV_ROOT=/opt/pyenv
    export PATH="/opt/pyenv/bin:$PATH"
    curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
    pyenv install anaconda3-2023.09-0
    pyenv global anaconda3-2023.09-0
    echo 'export PYENV_ROOT=/opt/pyenv' >> $SINGULARITY_ENVIRONMENT
    export PYENV_ROOT=/opt/pyenv
    export PATH="$PYENV_ROOT/bin:$PATH"
    .  $PYENV_ROOT/versions/anaconda3-2023.09-0/etc/profile.d/conda.sh
    conda activate base
    conda update -n base -c defaults conda
%environment
%startscript
```

:::note info
%postには、ベースとなるosのインストール後に実行するコマンドを記入します。ここで、インストールや設定などを行うことができます。
:::
:::note info
%startscriptには、singularityコンテナ起動時に実行されるコマンドを記入します。
:::

１３．singularity イメージファイルを作成

ユーザーがroot権限を持たない場合、下記のように`fakeroot`として`build`を実行する。sifファイル名は自分で決める。

```:defファイル名がsg_ubuntu_anaconda.defの場合
singularity build --fakeroot ubuntu_anaconda.sif sg_ubuntu_anaconda.def
```
１４．singularityコンテナを起動する

```
singularity shell --bind /mnt/ssd:/mnt/ssd /mnt/ssd/ubuntu_anaconda.sif
```

:::note info
`--bind host:local`でホストとコンテナのディレクトリ間でファイルの共有が可能になります。
:::

## anaconda仮想環境でjupyter notebookを実行

１５．condaコマンドを使用できるようにパスを設定
```
. /opt/pyenv/versions/anaconda3-2023.09-0/etc/profile.d/conda.sh
```

:::note info
このコマンドでAnacondaがパスに追加され、condaコマンドやその他のAnaconda関連のツールが使用できるようになります。
:::

１６．anaconda仮想環境を起動

```
conda activate base
```

１７．jupyter notebookを実行

```
jupyter notebook --port 50000
```