chakokuのブログ(rev4)

日々のごった煮ブログです

RPi4にdockerを入れる、コンテナ上でNode-REDとflaskを動かす

講習会ではアプリを同一条件で統一するため、dockerを入れてその上に構築することにする。多分素で入れるより、imageを配布する方が早いだろうと予測(生徒用のRPi(何十台)で各々ビルドしていると全く早くない。教師環境でimageをビルドして配布するようにすると早いかも)。借りるRPiの環境を極力変えてしまわないようにするというのもある。まぁまたRaspbianをSDに焼いてもらったクリーンにはなるのだが。
自分の家のRPi4はUbuntuなのだが、Raspbianに同じ手順で入れられるかは要確認

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.1 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

インストール手順(docker 公式ページより)

sudo apt-get remove docker docker-engine docker.io containerd runc

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg


echo "deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list 

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

パッケージ入れただけだとサービスが起動していないので使えない

$ docker ps
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

docker をサービスとして起動

# systemctl start docker

確認するが、一般権限では接続できず、root権限が必要。グループに追加等が必要なんだろう

$ docker ps
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
$ sudo docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

root権限でないと接続できないが、hello-worldが動いたのでインストールはOK

$ sudo docker run hello-world
                           *略*
$ sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
a2416d7c6d40   hello-world   "/hello"   12 seconds ago   Exited (0) 10 seconds ago             xenodochial_nash

先日試した、Node-REDをDocker上に入れる

cd ~/lesson2109/node-red
mkdir  data
sudo chown 1000 data                      #  owner を 1000 に変更(UID問題回避)
sudo docker run -it -p 1880:1880 -v data:/data --name nodered_lesson nodered/node-red

期待したマウントになっているのを確認
(別のパラメータで起動したのでマウントのパスはちょっと違っていますが、まぁホストPCの所定の場所にマウントされている)

$ sodo docker inspect nodered_lesson

        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/XXXX/lang/node-red/data_for_nodered",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

RPiでdocker-composeを動かすのが妥当か、、ちょっと分かりませんが、とりあえず入れてみる

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

ARM用のdocker-composeがリリースされていないようで、上記手順だと入らない。ビルドが必要らしい。
以下でビルドする

git clone https://github.com/docker/compose.git
cd compose
git checkout 1.25.0
./script/build/linux
cp dist/docker-compose-Linux-aarch64  /usr/local/bin/docker-compose

(情報はtkyonezu氏の記事より)

flaskをセットアップする
以下のファイル一式により、flaskの入ったimageをビルドしてコンテナを立ち上げ。imageはwebapi_on_flask(命名規則分かっておらず)としており、一度ビルドしてimageが作られると次回からはimageを優先して使う。

---------------------------
file: docker-compose.yml
---------------------------
version: '3'
services:
   web:
     build: .
     image: webapi_on_flask
     container_name: "echonet_lite_web_api"
     ports:
        - "8020:5000"
     volumes:
        - /home/staff/docker/flask/app:/usr/src/app
---------------------------

---------------------------
file: Dockerfile
---------------------------
FROM python:3.8-buster
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
CMD [ "python" , "app.py" ]
---------------------------

---------------------------
file: requirements.txt
---------------------------
flask
---------------------------

---------------------------
file:  ../app/app.py
---------------------------
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!(v2)'

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)
---------------------------
sudo docker-compose up -d

コンテナの停止と開始は以下(imageのビルド、コンテナ作成は行わない)

sudo docker-compose start
sudo docker-compose stop

Raspberry Pi用docker-composeの構築 (1.25.0以降) - Qiita