OpenWRTをDockerでビルドしてみよう　①ビルド環境構築編

# OpenWRTとは
初心者向けでは無いので、この辺は他の方が解説されていますので、それを参照してください。
OpenWRTで検索すれば、いっぱいヒットします。
Wikipediaにも解説があります。https://ja.wikipedia.org/wiki/OpenWrt
## OpenWRTの不満な点
* サイトからOpenWRTファームをダウンロードして、ルーターにインストールする訳ですが、標準の状態ではサポートされない機能が多々あります
![{6FB53AF2-1BC3-4C4C-A03F-0F6090045776}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215200/44582435-045b-c9c4-b8c6-d2401bba2f35.png)
上の画面から検索してインストールしますが結構面倒で、どれをインストールするかメモしておかないと、ほぼ確実に忘れます。またルーターを初期化すると、せっかく追加した機能が消えてしまうんです。
そうすると、また同じ手順でインストールし直さないといけない。１つ２つならいいですが、５つ６つとなるとちょっと面倒と感じるようになります。また、フラッシュの空き容量も心配になってきます。（容量は機種によるのでなんとも言えません）
自分でビルドすれば、初期状態ですでに使いたい機能が含まれた状態になっています。初期化しても元に戻ることはありません。
* 最新の機能を使ってみたい。具体的にはメッシュWifiとか
古いバージョンのOpenWRTでは、最新の機能が使えなかったりします。でも公開されているのは古いバージョンのものしか無い。そんな時には、自分でビルドしてしまおう。
## 自分でビルドして、自分だけのファームを作ってみよう
そんな理由で、自分でビルドしてみようというのが、この記事の目的です。
ビルドする環境はLinux環境が必要ですが、ほらDockerという便利な環境があるじゃないですか。まずは、Dockerを準備する必要があります。
* Dockerのインストール方法などは、他の方が解説されていますので、それを参照してください
Docker インストール方法　で検索すれば、いっぱいヒットします。マック、Windows それぞれ方法が違いますので、自分の環境に合わせてセットアップしてください。Dockerを触るのは、Windows ならPowerShellとかありますが、VS Codeをおすすめします。VS CodeとDockerの連携も、他の方が解説されていますので、そちらを参考にしてください。
* 失敗したときのために、メーカー標準ファームで最低限の設定を済ませたルーターを用意しておく
OpenWRTのビルドに失敗して、やり直すときにはインターネットに繋ぐ必要があります。しかし、ルーターが起動しないことにはインターネットに繋がりません。こんなときのために、安いルーターで構わないので、最低限の接続設定を済ませたルーターを１台用意しておきましょう。スマホでテザリングでも良いですが、スマホの料金がすごいことになってしまいます。
# Docker内でビルド環境構築
まずは、Dockerと言えばDockerfileですね。
```Docker:Dockerfile
FROM ubuntu:22.04

# ユーザー／グループ指定
ARG USERNAME="openwrt"
ARG GROUPNAME="openwrt"
ARG UID="1200"
ARG GID="1200"
# BRANCH 指定
ARG BRANCH="main"
# GET_OPENWRT_SH シェルスクリプト
ARG GET_OPENWRT_SH="get-dockerbuild.sh"
# 環境変数
ENV TZ="Asia/Tokyo"
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo "${TZ}" > /etc/timezone

# ツール等インストール
RUN apt-get update \
 && apt-get dist-upgrade -y \
 && apt-get install -y \
    bison build-essential clang coreutils curl fakeroot file flex g++ g++-multilib gawk gcc-multilib gdb gettext libgl1 libglx-mesa0 \
    git git-core htop libdrm-amdgpu1 libev-dev libpam-dev libgl1-mesa-dev libgraphene-1.0-0 libgraphene-1.0-dev libncurses5-dev libncurses-dev \
    libpcre3 libpcre3-dev libreadline-dev libssl-dev libwayland-bin libwayland-dev libz-dev lzma man-db patch \
    python2.7 python3 python3-distutils python3-pip rsync sharutils subversion sudo swig tzdata \
    unzip vim wayland-protocols wget wget2 xorg-dev xterm zip zlib1g-dev \
    qemu-system qemu-system-common qemu-utils
# 後片付け
RUN apt-get clean \
 && apt-get autoclean \
 && apt-get -y --purge autoremove \
 && rm -rf /var/lib/apt/lists/* > log.txt
# ユーザー追加
RUN groupadd -g ${GID} ${GROUPNAME} && useradd -m -s /bin/bash -u ${UID} -g ${GID} -G sudo ${USERNAME} && \
    sudo echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# openwrt Git取得 シェルスクリプト
COPY ${GET_OPENWRT_SH} /home/${USERNAME}/
RUN chown ${USERNAME}  /home/${USERNAME}/*.sh && \
    chgrp ${GROUPNAME} /home/${USERNAME}/*.sh && \
    chmod +x /home/${USERNAME}/*.sh

# openwrt 取得
RUN sudo -iu ${USERNAME} /home/${USERNAME}/${GET_OPENWRT_SH} ${BRANCH}

# VOLUME は Windowsでは下記の場所に存在
# \\wsl.localhost\docker-desktop\mnt\docker-desktop-disk\data\docker\volumes\
VOLUME ["/home/$USERNAME"]

CMD ["/bin/sh"]
# config を行う場合 ~/openwrt/.config ファイルを削除した後 make menuconfig

# ビルドは Linux上で以下を実行
# make -j10 詳細を表示させたい場合 make -j10 V=sc

# 完成したイメージは bin/targets 配下に作成される
```
`ubuntu 22.04`をベースで使用します。他のバージョンだとうまくビルドできません。
ビルドに必要なツール類をインストールしたり、rootでビルドするのは嫌なので、openwrtユーザを作ったりしています。
```bash
# openwrt Git取得 シェルスクリプト
COPY ${GET_OPENWRT_SH} /home/${USERNAME}/
RUN chown ${USERNAME}  /home/${USERNAME}/*.sh && \
    chgrp ${GROUPNAME} /home/${USERNAME}/*.sh && \
    chmod +x /home/${USERNAME}/*.sh
```
上記で、Linux側で使うシェルスクリプトをコピーしています。
それで、そのシェルスクリプトが以下です。
```bash:get-dockerbuild.sh
#!/bin/sh

# 使い方
# get-dockerbuild.sh [ブランチ名]

# openwrt Git取得
cd ~/
rm -rf ./openwrt
git clone --branch $1 https://github.com/openwrt/openwrt.git
cp ./openwrt/feeds.conf.default ./openwrt/feeds.conf
./openwrt/scripts/feeds update -a
./openwrt/scripts/feeds install -a
./openwrt/scripts/feeds install libev libpam libnetsnmp liblzma libgnutls libstdcpp libuuid

# ビルドは Linux上で以下を実行
# make -j10 詳細を表示させたい場合 make -j10 V=sc

# 完成したイメージは bin/targets 配下に作成される

exit 0
```
Linuxシェル上で `./get-dockerbuild.sh main` とやると、最新のmainのSnapshotを取得してきます。安定バージョンをビルドする場合は
`./get-dockerbuild.sh openwrt-23.05` などお好みで変更してください。
この辺のブランチ一覧は、https://github.com/openwrt/openwrt で見ることができます。
![{A119B6BB-39D1-4B8D-AF3B-11EA5DFE41BA}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215200/a91effac-a44d-4723-bbc9-a5cfbacbf77c.png)
タグ付きの安定版を指定したいなら
![{620CED5E-6EA0-45F6-8209-B9CCAC9F6A4B}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215200/187ac555-8760-4f59-8d65-e0d9f839f14e.png)
あと、Windows版ですが、cmdファイルも用意しましたので参考にしてください。
```bat:DockerBuild.cmd
docker builder prune -a --force

rd /S/Q docker-openwrt-buildroot\
md docker-openwrt-buildroot\

copy Dockerfile                           .\docker-openwrt-buildroot\
copy get-dockerbuild.sh                   .\docker-openwrt-buildroot\
cd .\docker-openwrt-buildroot
docker build --tag openwrt-buildroot --no-cache=true .
docker container run --name openwrt-build -it openwrt-buildroot sudo -iu openwrt bash
```
```bat:DockerRun.cmd
docker container exec -it openwrt-build sudo -iu openwrt bash
```
`DockerBuild.cmd` はDockerイメージとコンテナを生成するコマンド。
`DockerRun.cmd` は作成したコンテナを起動するコマンドです。
一度生成してしまえば、2回目からはDockerのイメージビルドは必要ないので、`DockerRun.cmd` で起動することができます。

これらの４つのファイルをどこか適当な場所にフォルダを作って置きます。
![{90B4D29F-6327-4057-8781-F02F3CDC51FF}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215200/b5f13c60-8c3a-6858-c7ff-89cb593cd3ca.png)
自分の場合は、**DockerBuild** というフォルダを作りました。アーカイブファイルとして取得したい方は、GoogleDriveに置いたので、[ここから](https://drive.google.com/file/d/1Kh0PFH9uPVlAMWrcTviReRNYAsjfSBBB/view?usp=drive_link)取得してください。
ここで `./DockerBuild.cmd` を実行すると、イメージのビルドが始まります。
イメージのビルドが終わると、コンテナ化して実行するので、Docker内のLinuxのシェルスクリプトが起動した状態になります。![{A247D9EB-0E53-4BD7-B2D3-2EC0118FABDE}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215200/71c8cacc-9f9e-4a88-30c3-e56770e04cbe.png)
この状態で、openwrt mainのsnapshotを取得した状態です。
ビルドするブランチを変更する場合は
`./get-dockerbuild.sh [ブランチ名]`
としてブランチを切り替えてください。

これでビルド環境は整いました。あとは実際にビルドする訳ですが、それは次回
[**②OpenWRTビルド編**](https://qiita.com/satotaka0409/items/246d820d57e0ee389c8f)で解説します。