新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

ラズベリーパイでDockerを使うのをやめた話

ラズベリーパイ単体でDockerを使う分にはいいのですが、ラズベリーパイをミニサーバー代わりにして、そこでDockerを使うのは使い勝手が良くないなぁという話です。

きっかけ

定期的にクロールを実行するサーバーを、デスクトップPCで動かしていました。

追々専用サーバーを用意するつもりだったので、サーバー移行しやすいようDockerを使用しました。

コンテナ構成は下記のとおりで、docker-composeで構成し、docker-machineでWindowsにHyper-VのDockerマシンを作成して、そのマシンにdocker-composeをアップしていました。

+-------+     +---------+     +-------------+     +---------------------+
| Nginx | --> | Jenkins | --> | Linux + SSH | --> | Node.js + puppeteer |
+-------+     +---------+     +-------------+     +---------------------+

なので、サーバー移行は、新しいサーバーをDockerマシンとして追加して、

% docker-machine 新しいマシン名
% docker-compose up

で済みます。

ラズベリーパイに興味があってさわってみたかったので、ラズベリーパイをミニサーバー代わりにして、そこにdocker-composeをアップしてみることにしました。

手順

ラズベリーパイでDockerを動くようにして、Dockerマシンにするのはこちらの記事を参考にしました。

Dokcerマシンには、既存のPCをDockerマシンにする「generic」ドライバーというものがあり、それを利用してラズベリーパイをDockerマシンにしています。

問題発生

後はDockerマシンをラズベリーパイに切り替えて、docker-compose upすれば終わりかと思ったのですが、全然ダメでした。

Dockerイメージに互換性がない

PCのCPUは「x86」。一方ラズベリーパイのCPUは「ARM」なので、Dockerイメージに互換性がありません。

Docker Hubから取ってくるイメージも「ARM」専用のものでないと動かず、結果として「ARM」用に別途Dockerfileを作成する必要があります。

「PCで動作検証したものを、そのままラズベリーパイにアップして終わり」とはならず、動作検証後、ラズベリーパイ用に修正してラズベリーパイにアップして、更にラズベリーパイで動作検証する必要があります。

Dockerfileが違うので構成が微妙に異なっていたりして、PCではうまく動いているのにラズベリーパイに持っていくとエラーなることが多々あり、かつ、環境が異なるので原因究明が手間でした。

イメージ作成に時間がかかりすぎる

それでも何とか動作するようにはなったのですが、Dockerイメージの作成はラズベリーパイ上で行うので、そのイメージ作成時間が長かったです。

クローラーに「puppeteer」を使っていたため、「xlib付きLinux+Node.js+Chronium+日本語フォント」のイメージ作成に30分程かかります。

上記は極端な例ですが、元々「x86」から「ARM」に変更時点でもエラーが発生しやすく、その上イメージ作成に時間がかかるので、ちょっとした修正も億劫になってしまいました。

結論

Dockerのメリットは、開発環境で作成したものを、そのままサーバーに載せられるポータビリティーだと思うのですが、ラズベリーパイをミニサーバーとした場合、そこが完全に切れてしまいます。

つまり、PCで開発していても、別途ラズベリーパイ専用に開発し直す必要があり、2回開発している気分になります。

それがかなり手間だったのと、そもそもDockerにした意図って何だっけと振り返ると、ラズベリーパイをミニサーバー代わりにして、そこでDockerを使うのは何か違うなぁとやめました。…というお話でした。


巷にはラズベリーパイを使ったKubernetesクラスター作成の記事があり、当初は、最終的にはdocker-composeからKubernetesにすることも妄想していたのですが、よくよく考えると、Kubernetesにしてもラズベリーパイ用のDockerイメージを作成するラズベリーパイが必要なことは変わらず、やはり何だかなぁという結論になります。

それらの記事はネタでやっているのだとは思うのですが、実際にそれを使っているの?と思ってしまいます。

ただ、今回は、PCの代用としてラズベリーパイを使用しようとした所に問題があったのですが、ラズベリーパイに特化したものを作るのであれば、Dockerを使うのは問題ないと思います。

おまけ

内容古くなっているかも知れませんが、使用していたラズベリーパイ用Dockerfielを記載します。

ラズベリーパイでDockerを使おうとして、Dockerfileを探している人がいましたら、参考にして頂けると幸いです。

Nginx Dockerfile

FROM tobi312/rpi-nginx

COPY copy/etc/nginx/conf.d/default.conf /etc/nginx/conf.d/
COPY copy/etc/nginx/server.key /etc/nginx/
COPY copy/etc/nginx/server.crt /etc/nginx/

Jenkins Dockerfile

FROM djdefi/rpi-jenkins

RUN apt-get install -y tzdata
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN echo "Asia/Tokyo" > /etc/timezone

Linux+SSH Dockerfile

FROM resin/rpi-raspbian:latest

USER root
RUN mkdir /var/run/sshd

RUN apt-get update
RUN apt-get install -y openssh-server
RUN echo 'root:xxxx' | chpasswd
RUN sed -i 's/PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN cat /etc/ssh/sshd_config
RUN sed -i 's/root:\/bin\/ash/root:\/bin\/bash/' /etc/passwd
RUN ssh-keygen -A
EXPOSE 22

RUN apt-get install -y tzdata
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

CMD    ["/usr/sbin/sshd", "-D"]

Node.js + puppeteer Dockerfile

FROM hypriot/rpi-node

RUN apt-get update \
 && apt-get install -y \
zip \
unzip \
gconf-service \
libasound2 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgcc1 \
libgconf-2-4 \
libgdk-pixbuf2.0-0 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
ca-certificates \
fonts-liberation \
libappindicator1 \
libnss3 \
lsb-release \
xdg-utils \
wget

RUN ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# Japanese font
RUN mkdir /noto
COPY ./app/font/NotoSansCJKjp-hinted.zip /noto
WORKDIR /noto
RUN unzip NotoSansCJKjp-hinted.zip && \
    mkdir -p /usr/share/fonts/noto && \
    cp *.otf /usr/share/fonts/noto && \
    /usr/bin/fc-cache -fv
WORKDIR /
RUN rm -rf /noto

WORKDIR /usr/src/app
COPY ./app/package.json .
COPY ./app/build ./build
COPY ./app/views ./views

RUN npm install

COPY ./app/chromium/chromium-codecs-ffmpeg_65.0.3325.181-0ubuntu0.14.04.1_armhf.deb .
RUN sudo dpkg -i chromium-codecs-ffmpeg_65.0.3325.181-0ubuntu0.14.04.1_armhf.deb

COPY ./app/chromium/chromium-browser_65.0.3325.181-0ubuntu0.14.04.1_armhf.deb .
RUN sudo dpkg -i chromium-browser_65.0.3325.181-0ubuntu0.14.04.1_armhf.deb

EXPOSE XXXX

CMD [ "npm", "start" ]