t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Raspberry Pi 3B+にdockerを導入してRedmineサーバーを作成

今回はラズパイにDockerを導入してRedmineサーバーをコンテナとして構築してみた。

ラズパイならではのハマりどころがいくつかあったので記事として残しておこうと思う。

参考書籍

参考にしたのは次の書籍。

まさにRedmineを構築する事例が紹介されているので、そちらを使う算段である。

機材

必要な機材はRaspberry Pi 3B+とある程度速度が出るMicroSDカードである。

SDカードは、初めは10枚5000円くらいで買った激安品を使っていたが、redmineのコンテナを起動する際に頻繁にフリーズして使い物にならなかった。そこで1枚3000円くらいの普通のSDカードに切り替えたところうまくいった。

以下はうまくいかなかったカードとうまくいったカードのベンチマーク比較。

これで数時間ハマった。

OS

OSはRasbberry Pi OS Lite 64bit版を使用する。

理由として、Dockerは公開されているコンパイル済イメージをダウンロードする仕組みになっており、32bit版を選んでしまうと適合するイメージがあまり公開されていない為である。

これまた数時間ハマった。

64bitOSは、公式のSDカード書き込みツールだとOtherの中にある。

手順

OSのUpdateとdockerのインストール

sudo apt update
sudo apt upgrade
sudo reboot ←upgrade後に再起動
sudo apt install docker

Dockerファイルの準備

/home
└── pi
    └── docker
        └── mydatabase
            ├── mysql
            │   └── Dockerfile ←(1)
            ├── phpmyadmin
            │   └── Dockerfile ←(2)
            └── redmine
                └── Dockerfile ←(3)
(1) MySQLのDockerfile
FROM mysql/mysql-server

ENV MYSQL_ROOT_PASSWORD=ここにデータベースのrootユーザーパスワードを書く \
    MYSQL_ROOT_HOST="%"

CMD ["mysqld",\
"--character-set-server=utf8mb4","--collation-server=utf8mb4_unicode_ci",\
"--default-authentication-plugin=mysql_native_password"]

注意) ここで設定するパスワードはダブルクォートで囲ったりしないようで、私の場合は囲ってしまったのでダブルクォートごとパスワードになってしまった。。まぁアプリ同士が通信する用で、自分が普段使いするものではないのでそのまま運用する予定。

(2) PHP MyAdminのDockerfile
FROM phpmyadmin
ENV PMA_HOST=mysql-container \
    PMA_USER=root \
    PMA_PASSWORD=ここにMySQLで設定したのと同じrootユーザーパスワードを書く
(3) RedmineのDockerfile
FROM redmine

ENV REDMINE_DB_MYSQL=mysql-container \
    REDMINE_DB_USERNAME=root \
    REDMINE_DB_PASSWORD=ここにMySQLで設定したのと同じrootユーザーパスワードを書く

イメージ構築

Dockerコンテナ同士が通信するための内部ネットワーク作成
sudo docker network create mysql-nw
データの永続性を担保するためのデータボリュームとそれを保持するデータボリュームコンテナ作成
sudo docker volume create --name=db-volume
sudo docker run -v db-volume:/var/lib/mysql/ --name=db-container busybox
アプリケーションコンテナのビルドと起動

MySQLの起動

sudo docker build -t mysql-image ~/docker/mydatabase/mysql
sudo docker run --volumes-from=db-container --name=mysql-container --net=mysql-nw -d mysql-image

phpMyAdminの起動

sudo docker build -t pma-image ~/docker/mydatabase/phpmyadmin
sudo docker run --net=mysql-nw --name=pma-container -p 8080:80 -d pma-image

これでPCのブラウザからラズパイのIPの8080ポートにアクセスするとphpMyAdminが起動するのでredmineという名前の空のデータベースを作っておく。
ここまで終わったらphpMyAdminのコンテナは停止・破棄しても良い。

Redmineの起動

sudo docker build -t rm-image ~/docker/mydatabase/redmine
sudo docker run --net=mysql-nw --name=rm-container -p 80:3000 -d rm-image

設定が正しければこれでブラウザからラズパイにアクセスするとredmineが表示される。
ただ、コンテナ起動直後はアクセスがうまくいかず、初回ページを開こうとしたらアクセス拒否されたと表示された。
しばらく時間を置くとうまくいく。
※内部で何かIOアクセスをしているようで、ここがショボいSDカードだといつまでたってもアクセス拒否のままで進まなかった。

時間を置いても失敗する場合はhttp://もちゃんとつけると良い。SSLを導入していないのでブラウザがお節介でhttpsでアクセスしようとすると失敗する。

よし、動いた。

運用手順

電源OFF

Dockerはコンテナは使い捨てというコンセプトなので電源を切るときはアプリケーションコンテナは破棄する運用とした。
ただしデータボリュームコンテナを破棄すると面倒なのでそれは置いておく。

まずはdocker ps -aコマンドで破棄対象を確認する。

hom@raspberrypi:~ $ sudo docker ps -a
[sudo] password for thom:
CONTAINER ID   IMAGE         COMMAND                  CREATED             STATUS                       PORTS                       NAMES
4f6765d72a86   rm-image      "/docker-entrypoint.…"   About an hour ago   Up About an hour             0.0.0.0:80->3000/tcp        rm-container
4c73f0ae2f39   mysql-image   "/entrypoint.sh mysq…"   About an hour ago   Up About an hour (healthy)   3306/tcp, 33060-33061/tcp   mysql-container
76d78ea098ea   busybox       "sh"                     4 hours ago         Exited (0) 4 hours ago                                   db-container

次にコンテナIDの先頭数桁を指定してコンテナを止める。
他のIDと区別できれば良いので、上記の場合なら2桁目までで問題ない。

sudo docker stop 4f 4c

データボリュームコンテナ以外のコンテナを削除する

sudo docker rm 4f 4c

シャットダウンする

sudo systemctl poweroff

電源ON

作成したDockerネットワーク・データボリューム・データボリュームコンテナと、ビルドしたイメージはそのまま残っているので、電源を入れた際に対応するのはコンテナ作成のみ。

以下のように2つコンテナを起動させれば元通りである。

sudo docker run --volumes-from=db-container --name=mysql-container --net=mysql-nw -d mysql-image
sudo docker run --net=mysql-nw --name=rm-container -p 80:3000 -d rm-image

終わりに

何かひとつでも自宅環境でDockerを使った本番運用してみたいと思っていたので今回その目的が達成できた。

Dockerは誰かが構築してくれたインフラ+アプリに可搬性を持たせて簡単に環境構築できるようにしてくれる便利なツールである。
今回もMySQLやRedmineのパッケージインストールや依存関係との闘い、パラメーター設定等のややこしいことをせずに最低限のDockerfile記述だけで環境構築ができた。

しかもコンテナは使い捨てなので、運用中にもし何かおかしくなっても破棄してイメージから再作成すれば良い。
作成したイメージには可搬性があるのでもし本体のOSがおかしくなっても同じ64bit版のラズパイ宛であれば環境ごと移行することもできる。

もしDockerに興味がある方は私が購入したこちらの書籍がおススメ。

第6章くらいで書いてある通りに進められない箇所が出てくるけど、それを差し引いても入門書としてはコンパクトにまとまっていて、作業内容が明確なので、Linuxを触り慣れていてDockerは初心者という方が始めるにはちょうど良いと思う。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。