Raspberry Pi4で始めるDocker入門

テクノロジー

前置き

Raspberry Piとは

 教育向けとして開発されたボードであり、初めの発売されたRaspberryPi Model Aは35ドルと低価格のためやOSのインストール、GPIOの操作が容易などもあり、大ヒットした商品であります。なお、最新(2020/06/11時点)のモデルでは、Raspberry Pi4 8GBであり75ドルで入手できます。

 Raspberry PiのCPUは、ARMと呼ばれているCPUプロセッサを使用しており、一般家電量販店で購入できるPCのCPUプロセッサの種類が異なります、このARMプロセッサの特徴として省電力であるため、スマートフォンなどに乗っているCPUもARMのCPUが搭載されています。そのように幅広く使用されていることもあり、ソフト開発用のライブラリや開発情報などが豊富にあります。

Dockerとは

 コンテナ仮想化技術を用いて、開発や配置、実行を行うツールです。ビルド&スクラップが容易であり使い方を覚えると開発の速度を加速できるツールです。

RaspberryPiを動かす

OSのインストール

Raspberry Pi OS (previously called Raspbian)のページからRaspberry Pi OS (32-bit) with desktop and recommended softwareをダウンロードして、解凍してください。解凍してできたimgファイルをmicroSDカードにツールを使用して書き込んでください。

 書き込み完了後、bootという名前のディスク内にsshという空ファイルを作ります。また、同じようにwpa_supplicant.confというファイルを作り、無線のSSIDが”test”、パスフレーズが”abcd1234”の時は以下のように入力します。

country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="test"
    psk="abcd1234"
}

電源投入

 書き込んだmicroSDカード立ち上げ後、ほかPCから、ping raspberrypi.local -4を実行してください。RaspberryPiに接続するためのIPアドレスがわかりますのでそのIPアドレスで、ssh pi@192.168.0.12でアクセスして、パスワードにraspberryを入力してください以上で立ち上げを確認できます。

SSH接続後

起動後セットアップ

以下のコマンドを実行して、raspi-configを起動する

sudo raspi-config

raspi-configを実行後「updata」を実行

「Advanced Options」→「 A1 Expand Filesystem Ensures」を選択してmicroSDカードの使える容量を増やす

実行後

sudo rpi-update

64bit動作を有効にするには以下のコマンドを実行

sudo echo “arm_64bit=1 >>  /boot/config.txt
sudo apt update && sudo apt upgrade -y

Dockerのインストール

以下のコマンドを実行すればインストールができます

curl -sSL https://get.docker.com | sh

インストール後は以下のコマンドを確認してください

sudo docker ps

以下のコマンドを入力して再起動をすれば、piユーザで「docker ps」を行ってもエラーが発生なくなります

sudo usermod $USER -aG docker

Dockerを動かす

コンテナを動かす前に

まず、Raspberry PiのCPUはARMアーキテクチャであることを認識してください。WindowsやMac、Linuxなどの一般的なPC環境下のCPUアーキテクチャと異なるため、DockerのコンテナもARM用のコンテナをベースにしないと動作しません。そのことより、多くのWebサイトのDocerfileに書かれた内容をそのまま移植しても動作しません。

Dockerコンテナ動作

以下の手順で、Dockerの操作方法を試してみます。

  1. コンテナイメージを動かす
  2. コンテナ上でツールインストールして動かす
  3. 新しいコンテナを作り動かす。
  4. ローカル上のコンテナを削除する
  5. コンテナ上で、Webサーバを作成して動かす
  6. 手順5の作業を自動化する

作業事項

  1. コンテナイメージを動かす

 今回はmultiarch/ubuntu-core:armhf-bionicというベースになりやすいイメージを動かし、最終的にgoで作成したHTMLサーバを動かしてみましょう。

まずは、以下のコマンドを実行して、ベースイメージを動かしてみてくい。

docker run -rm -it multiarch/ubuntu-core:armhf-bionic /bin/bash
  1. コンテナ上でツールインストールして動かす

 今回は、pingコマンドをインストールします。「apt install iputils-ping net-tools」でインストールを行うことができますが、起動した直後ではこのコマンドは実行できませんので、以下の手順のコマンドを実行してインストールを行います。

apt update && apt upgrade -y
apt install -y iputils-ping net-tools

インストール以下のコマンドと実行結果が取得することができます。

ping -c 3 container.sios.jp
PING container.sios.jp (133.242.249.93) 56(84) bytes of data.
64 bytes from www4183.sakura.ne.jp (133.242.249.93): icmp_seq=1 ttl=48 time=57.3 ms
64 bytes from www4183.sakura.ne.jp (133.242.249.93): icmp_seq=2 ttl=48 time=50.8 ms
64 bytes from www4183.sakura.ne.jp (133.242.249.93): icmp_seq=3 ttl=48 time=59.4 ms
--- container.sios.jp ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 50.801/55.857/59.468/3.693 ms
  1. ツールがインストールしたコンテナを作る。

以下のファイル、フォルダ構成でファイルを作成します。

./
└── Dockerfile

Dockerfileの中身を以下のように入力します。

FROM multiarch/ubuntu-core:armhf-bionic
RUN apt update && apt upgrade -y
RUN apt install -y iputils-ping net-tools

今回はコンテナイメージ名は「pingtest」としてDockerコンテナを作成しますので、以下のコマンドを入力してください

docker build -t 

以下のコマンドを入力しますと、「pingtest」という名前のファイルが追加されていることがわかります。

docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
pingtest                latest              25b628c4f34a        13 seconds ago      96.6MB
multiarch/ubuntu-core   armhf-bionic        ca9649539262        2 days ago          49.7MB

以下のコマンドを入力して作成したコンテナに入り、pingコマンドを実行してみてください。

docker run --rm -it pingtest /bin/bash
  1. ローカル上のコンテナを削除する

 コンテナイメージ作成を何度もやっているとディスクの容量を多く圧迫していきます。そのため、使わなくなったdockerコンテナイメージやキャッシュは削除する必要があります。今回は、先ほど作成した「pingtest」というコンテナイメージを削除します。

まず、「docker images」コマンドでIMAGE IDを調べてください。今回は、「pingtest」のIMAGE IDは「25b628c4f34a」のため削除するためには以下のコマンドを実行してください。

docker rmi -f 25b628c4f34a 
  1. コンテナ上で、Webサーバを作成して動かす

以下のフォルダ構成でファイル・フォルダを作成する

/home/pi/dockergo/
└── golang
    ├── html
    │   └── index.html
    └── main.go

各ファイルは以下のように入力する。

index.html

<html>
<head>
<title>test</title>
</head>
<body>
It's Work
</body>

main.go

package main
import (
  "net/http"
  "fmt"
)
func main(){
  http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("./html"))))
  fmt.Println("web server start :8080")
  http.ListenAndServe(":8080",nil)
}

以下のコマンドを実行して、golangフォルダをコンテナ内の/appにマウントさせる

docker run --rm -it -v /home/pi/dockergo/golang:/app -p 8080:8080 multiarch/ubuntu-core:armhf-bionic /bin/bash

コンテナに入った後で、以下のコマンドを上から入力することで、goで作成したwebサーバを起動させる。

apt update && apt upgrade -y
apt install -y curl gcc
curl -OL https://dl.google.com/go/go1.14.4.linux-armv6l.tar.gz
tar -C /usr/local -xzf go1.14.4.linux-armv6l.tar.gz
rm -rf go1.14.4.linux-armv6l.tar.gz
export PATH=$PATH:/usr/local/go/bin
cd /app
go build .
./app

上記コマンド入力後、http://192.168.0.12:8080または、http://raspberrypi:8080にWebブラウザにアクセスすれば、It’s Workと表示される画面が見える。

ブラウザの確認を終えたら、Ctrl+Cでサーバを停止し、rm -rf appでビルドして出来上がったappファイルを削除してから、コンテナを停止してください。

  1. 手順5の作業を自動化する
FROM multiarch/ubuntu-core:armhf-bionic As builder
RUN apt update && apt upgrade -y
RUN apt install -y curl gcc
RUN  curl -OL https://dl.google.com/go/go1.14.4.linux-armv6l.tar.gz
RUN tar -C /usr/local -xzf go1.14.4.linux-armv6l.tar.gz
RUN rm -rf go1.14.4.linux-armv6l.tar.gz
ENV PATH $PATH:/usr/local/go/bin
WORKDIR /app
ADD ./golang/main.go ./
RUN go build .
FROM multiarch/ubuntu-core:armhf-bionic
WORKDIR /app
RUN mkdir html
ADD ./golang/html ./html
COPY --from=builder /app/app /app
CMD ["./app"]

以下にコマンドでコンテナをビルドして

docker build -t goweb .

コンテナをデーモンで起動させます。

docker run -d -p 8080:8080 goweb:latest

Docker-Composeのインストール

Docker-Composeとは

Docker-Composeとは複数のコンテナを定義し実行するツールです。

このツールを使用しなくても、dockerコマンドで同じように再現できますが、オプションの指定の指定など呪文のように見えていたコマンドオプション指定が、意味がある言葉に置き換えたり、複数のコマンド実行を一つに集約できる利点があります。

Docker-Composeのインストール

以下のコマンドを実行してください。

sudo apt install -y docker-compose

以上で、インストールは終わりです。

Docker-Composeを動かす

以下のフォルダ構成を行う。

/home/pi/docogo/
├── docker-compose.yaml
└── services
    └── app
        ├── Dockerfile
        └── golang
            ├── html
            │   └── index.html
            └── main.go

ファイルの中身は以下のようになります。

./docker-compose.yaml

version: '3'
services:
  app:
    build: services/app
    container_name: goweb
    ports:
    - 8080:8080
    volumes:
    -  ./services/app/golang/html:/app/html

services/app/Dockerfile

FROM multiarch/ubuntu-core:armhf-bionic As builder
RUN apt update && apt upgrade -y
RUN apt install -y curl gcc
RUN  curl -OL https://dl.google.com/go/go1.14.4.linux-armv6l.tar.gz
RUN tar -C /usr/local -xzf go1.14.4.linux-armv6l.tar.gz
RUN rm -rf go1.14.4.linux-armv6l.tar.gz
ENV PATH $PATH:/usr/local/go/bin
WORKDIR /app
ADD ./golang/main.go ./
RUN go build .
FROM multiarch/ubuntu-core:armhf-bionic
WORKDIR /app
RUN mkdir html
ADD ./golang/html ./html
COPY --from=builder /app/app /app
CMD ["./app"]

services/app/golang/main.go

package main
import (
  "net/http"
  "fmt"
)
func main(){
  http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("./html"))))
  fmt.Println("web server start :8080")
  http.ListenAndServe(":8080",nil)
}

services/app/golang/html/index.html

<html>
<head>
<title>test</title>
</head>
<body>
It's Work
</body>

以下のコマンドを実行すれば、docker-composeを実行できます。

docker-compose build
docker-compose up

実行後、http://192.168.0.12:8080または、http://raspberrypi:8080にWebブラウザにアクセスすれば、It’s Workと表示される画面が見える。

また、 services/app/golang/html/index.htmlのファイルを変更すれば、適応されます。