今回はラズパイにDockerを導入して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は初心者という方が始めるにはちょうど良いと思う。