競馬AI用Dockerコンテナ導入手順

# 概要

開発中の以下のリポジトリにてDockerコンテナを作成したので、開発メンバーがこれを導入・使用する方法をメモしておく。Windows前提で話を進めるが、MacでもLinuxでもなんとかなるはず。

https://github.com/KeibaAI-developer/KeibaAI.git

# 導入手順
### 0.リモートリポジトリをclone or 最新の状態にpull

```:powershell
git clone git@github.com:KeibaAI-developer/KeibaAI.git
```
でリモートリポジトリをcloneする
すでにcloneしていてローカルリポジトリがある場合は
```:powershell
git pull origin main
```
でローカルリポジトリを最新の状態にする

### 1.DockerDesktopのインストール

以下の記事を参考に[こちら](https://www.docker.com/get-started/ "docker.com")からインストールした

https://qiita.com/zembutsu/items/a98f6f25ef47c04893b3

### 2.DockerImageのビルド

リポジトリ内のDockerfileを元にDockerイメージをビルドする。

```:powershell
cd <C:your/own/directory/path/KeibaAI> # 各自のKeibaAIディレクトリのパス
docker build -t keiba-ai .
```
このコマンドを実行すると、keiba-aiという名前でDockerイメージがビルドされる。

### 3.Dockerコンテナの作成と起動
コンテナを作成し、ホスト環境（ローカルマシン）とコンテナ間で作業ディレクトリを同期させるために、以下のコマンドを実行する

```:powershell
docker run -it --name keiba-ai -v "<C:your/own/directory/path/KeibaAI>:/KeibaAI" -w /KeibaAI keiba-ai
```
-vオプションでホストマシンのローカルディレクトリ`<C:your/own/directory/path/KeibaAI>`とコンテナ内の/KeibaAIを同期させる。これにより、コンテナ内の変更がローカルディレクトリにも反映され、逆も同様となる。
無事にコンテナには入れれば
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/cffead7c-4a43-b08d-94fa-745ded7e1488.png)
だったものが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/3cc83a74-14d0-1e0d-a0af-c3b939737ddf.png)
みたいになる

### 4.VSCodeでDockerコンテナを操作
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/fb345498-4c76-cf0b-b17a-5adebe067a18.png)

VSCodeを使ってコンテナ内のコードを操作するために、拡張機能「Remote Development」をインストールする
インストール後、左側にモニターみたいなアイコンが現れるので「Remote Explorer」を開く


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/24961389-8d58-a944-c6c3-71931b89b8b8.png)

「開発コンテナー」セクションにkeiba-aiコンテナが表示されるので、「現在のウィンドウでアタッチする」もしくは「新しいウィンドウでアタッチする」（推奨）を選択。
コンテナには入れると左下の青い部分にコンテナの名前が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/492903a2-4715-2186-bd4d-54c2adf3bf80.png)
コンテナから出るときはこの青い部分をクリックすると真ん中上に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/8826e35d-24d3-e87d-f80c-e1a58d74f096.png)

が出てくるので、一番下の「リモート接続を終了する」を選択する。


# 普段の運用

### 1.DockerDesktopの起動
なぜか毎回起動する必要がある
一度起動したらウィンドウは消してもいい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/0b8ca7f6-fe7c-d55a-f028-8304ed216fa5.png)

### 2.Dockerコンテナに入る

```:powershell
docker start -ai keiba-ai
```
でコンテナには入れる
現在のコンテナの状態を確認したいときは

```:powershell
docker ps -a
```

を実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/91c9946f-8454-7371-f535-19f8622ed54c.png)
のようなものが出てきて確認できる
STATUSがUpならコンテナが無事に起動できている


### 3.VSCodeで操作
4の手順で開発コンテナにアタッチする
rootディレクトリに案内されてしまった場合はctrl+K ctrl+Oで「フォルダを開く」が出てくるので、`/`まで戻って`/KeibaAI`を選択すればKeibaAIに入れる

### 4.Git操作

コンテナ内にGitをインストールしてないのでコンテナから変更をpushすることはできない。
変更をpushしたい場合はローカルのKeibaAIを開いて行う。
（そのため、コンテナは現在のウィンドウではなく新しいウィンドウで開いておくと楽）


### 5.終了手順

- VSCodeの左下の青いところを押して「リモート接続を終了する」を選択
- コンテナ内で`ctrl+d`を押す、もしくはローカルで以下を実行してコンテナを停止する

```:powershell
docker stop keiba-ai
```

dockerが停止できていれば、

```:powershell
docker ps -a
```
を実行したとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955850/1814169c-587a-78cf-a7c3-6cd0c0b0369b.png)

となり、STATUSがExitedになる

# ライブラリを追加するとき

pipを使ったインストールも可能だが、コンテナを停止すると記憶を失って次回またインストールし直さないといけないため面倒である。
そのため、必要なライブラリがあった場合は`requirements.txt`に追記して再度イメージをビルドする。

以下、手順

**1. pipでインストールして動作とバージョン確認**

```:コンテナ内
pip install <library>
```

で普通にライブラリをインストールし、コードを実行してちゃんと動くことを確認する。
問題なければ
```:コンテナ内
pip show <library>
```
でバージョンを確認し、`requirements.txt`に
```:requirements.txt
<library>==x.x.x
```
として追記する

**2\. イメージを再ビルド**

現在のコンテナを
```:powershell
docker rm keiba-ai
```
で削除する。
```:powershell
docker ps -a 
```
で`keiba-ai`が消えていればOK
続いて最初のイメージビルド時と同様に
```:powershell
cd <C:your/own/directory/path/KeibaAI> # 各自のKeibaAIディレクトリのパス
docker build -t keiba-ai . 
```

でイメージをビルドし、最後に
```:powershell
docker run -it --name keiba-ai -v "<C:your/own/directory/path/KeibaAI>:/KeibaAI" -w /KeibaAI keiba-ai
```
でコンテナを作成すれば新しいライブラリがインストールされた状態で今後コンテナを使える。

**3\. 古いイメージを削除**
```:powershell
docker images
```
とすると
```:powershell
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
keiba-ai     latest    54c4bf91efcb   3 hours ago    26.1GB
<none>       <none>    e5d859c4c1f8   6 hours ago    26GB
```
と出てきて、古いイメージは`<none>`となっている。
残していてもいいがストレージを圧迫するだけなので、
```:powershell
docker image prune
```
とすると使っていないイメージだけすべて削除してくれる。

# 使用したDcokerfileとrequirements.txt

参考までに、使用したDcokerfileとrequirements.txtを載せておく。
selenium用にchromeとchromedriverをインストールしないといけないのがめんどくさかった。
chromedriverは https://googlechromelabs.github.io/chrome-for-testing/ から対応するchromeバージョンのURLを選択した。
seleniumを使用するときのドライバのパスは`"/usr/local/bin/chromedriver-linux64/chromedriver"`を指定すればよい

```:Dcokerfile
# ベースイメージ
FROM python:3.12.4

# 作業ディレクトリを設定
WORKDIR /KeibaAI

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y --no-install-recommends \
    wget \
    gnupg \
    unzip \
    fonts-noto-cjk  # 日本語フォントを追加

# Google Chromeのバージョンを手動で指定
ENV CHROME_VERSION=132.0.6834.83

# Google Chrome のインストール
RUN wget -q https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}-1_amd64.deb && \
    apt-get install -y ./google-chrome-stable_${CHROME_VERSION}-1_amd64.deb && \
    rm ./google-chrome-stable_${CHROME_VERSION}-1_amd64.deb

# ChromeDriver のインストール
RUN wget -O /tmp/chromedriver.zip "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chromedriver-linux64.zip" && \
    unzip /tmp/chromedriver.zip -d /usr/local/bin/ && \
    rm /tmp/chromedriver.zip

# 依存ライブラリをコピー
COPY requirements.txt /KeibaAI/

# 必要なライブラリをインストール
RUN pip install --no-cache-dir -r /KeibaAI/requirements.txt

# ipykernel をインストール（requirements.txt に含めてもよいが、環境全体に必要なものと区別するため直接 Dockerfile で指定する）
RUN pip install --no-cache-dir ipykernel

# ソースコードをすべてコピー
COPY . /KeibaAI/

# デフォルトで実行するコマンド
CMD ["/bin/bash"]
```

```:requirements.txt
beautifulsoup4==4.12.3
bs4==0.0.2
isoduration==20.11.0
isort==5.13.2
japanize-matplotlib==1.1.3
jsonpointer==2.1
lightgbm==4.5.0
numpy==1.26.4
optuna==4.1.0
optuna-integration==4.1.0
pandas==2.0.3
scikit-learn==1.6.1
seaborn==0.13.2
selenium==4.27.0
tqdm==4.66.4
trueskill==0.4.5
webdriver-manager==4.0.2
xgboost==2.1.1
lxml==5.3.0
```