Raspberry Pi 4上のDockerコンテナでtensorflowを走らせるのに少しハマったので書く

タイトルの通り

# 前提
docker-composeを使ってpythonコンテナを走らせようと思いました．
何の変哲もないpythonコンテナで，x86_64のDocker環境だと普通に動いていました．

```yaml:docker-compose.yml
version: '3'
services:
  hogehoge-backend:
    restart: always
    build:
      context: ./hogehoge-backend
      dockerfile: ./Dockerfile
    container_name: hogehoge-backend
    working_dir: '/root/'
    tty: true
    volumes:
      - ./opt:/root/opt
```

```dockerfile:Dockerfile
FROM python:3.6
USER root

RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptoolslibxkbcommon0 xdg-utils libgtk-3-0
RUN apt-get update
RUN apt-get -y install python3-pip

```

加えて，コンテナ内でアプリケーションを利用するためにpip用のrequirements.txtを用意していました．
下記の通り．

```text:requirements.txt
pandas
tensorflow
requests
keras
urllib3
sklearn
```

初回起動時に

`pip3 install -r requirements.txt`

でインストールするのを想定してました（ビルド時に自動化はしてない）

前述の通り，x86_64環境でアプリケーション作ってから，「RPi4で動かせば電気代安いんじゃね・・・？」と素朴に欲を出して試してみたところ次節に述べる通りハマりました

# ハマったところ

## tensorflowがpipで入らない

### 状況

pipでrequirements.txtを用いてtensorflowをインストールしようと試みると下記のようなエラーが出る

```console
$ pip3 install -r requirements.txt

ERROR: Could not find a version that satisfies the requirement tensorflow
ERROR: No matching distribution found for tensorflow

$ uname -a
Linux 24aa5e15abb5 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux
```

### 解決策

pipをupgradeしてもダメだったので，結局wheelをダウンロードしてきた．


```console
$ wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v2.0.0/tensorflow-2.0.0-cp37-none-linux_armv7l.whl
$ python3 -m pip uninstall tensorflow
$ python3 -m pip install tensorflow-2.0.0-cp37-none-linux_armv7l.whl
```

バージョン選びたい方はこちらから選択して所望のバージョンのwhlを落としてくると良いと思います

https://github.com/lhelontra/tensorflow-on-arm/releases/

※なお，tensorflow-on-armは `cp35` か `cp37` しか用意されていない様子だったので（どうやらcpの後の数字はpythonのバージョンらしい），あらかじめコンテナ上ではpython3.7を利用するようにDockerfileを書き換えてビルドしておいた

```dockerfile:Dockerfile
- FROM python:3.6
+ FROM python:3.7
```

## h5pyが入らない

### 状況

前述の通りtensorflowをインストールしたところ，h5pyのインストール時にエラーが出る

```console
$ python3 -m pip install tensorflow-2.0.0-cp37-none-linux_armv7l.whl

Building wheels for collected packages: numpy, termcolor, wrapt, h5py
  Building wheel for numpy (PEP 517) ... done
  Created wheel for numpy: filename=numpy-1.20.2-cp37-cp37m-linux_armv7l.whl size=15411079 sha256=1934c0d7b18fcc872ff7b95a361b9580d7586aabab8bada8991e6df443ed047f
  Stored in directory: /root/.cache/pip/wheels/dc/89/4e/d661a082dcb028182ea7b4561c34dbcf717169c443ea0087a2
  Building wheel for termcolor (setup.py) ... done
  Created wheel for termcolor: filename=termcolor-1.1.0-py3-none-any.whl size=4830 sha256=0844dee89ff65f17c6d1d00bd40ef6ac414156937121fa8e51773d7658511f64
  Stored in directory: /root/.cache/pip/wheels/3f/e3/ec/8a8336ff196023622fbcb36de0c5a5c218cbb24111d1d4c7f2
  Building wheel for wrapt (setup.py) ... done
  Created wheel for wrapt: filename=wrapt-1.12.1-cp37-cp37m-linux_armv7l.whl size=72200 sha256=e7331863b9a094e6ab7520c5157b321fc81739732dfc835b241a0f916a07c9ce
  Stored in directory: /root/.cache/pip/wheels/62/76/4c/aa25851149f3f6d9785f6c869387ad82b3fd37582fa8147ac6
  Building wheel for h5py (PEP 517) ... error
  Loading library to get build settings and version: libhdf5.so
（中略）
  running build_ext
  Loading library to get build settings and version: libhdf5.so
  error: Unable to load dependency HDF5, make sure HDF5 is installed properly
  error: libhdf5.so: cannot open shared object file: No such file or directory
  ----------------------------------------
  ERROR: Failed building wheel for h5py
```

### 解決策

libhdf5-devをインストールする（※）

```console
$ apt-get install libhdf5-dev
```

この後再度tensorflowのインストールを実行すると進む．

```console
$ python3 -m pip install tensorflow-2.0.0-cp37-none-linux_armv7l.whl
```

※はじめからDockerfileに記述しておいたほうが良いかも