今更ながらDockerです。Raspberry Pi Zero系でもDockerが動いている情報を読んで、トライしてみました。スペック的にどうなんだろうと興味があったからです。
Zero系の利点の1つにモバイルバッテリーで稼働させられることが挙げられます。持ち運びを前提とした使い方をしたい。
Raspberry Piにローカルサーバーを構築するのは主に3つの方法があります。
- DockerのWordpressコンテナを使う方法
- DockerでLAMP環境を構築してWordpressをインストールする方法
- Dockerを使わずに直接LAMP環境を構築する方法
結果としてはできたけれど、Zero系はarm32v6だったのがネックでした。エラーや警告がたくさん出ます。(Raspberry Pi 4はarm32v7とarm64v8)
Docker+LAMPでは、WordpressのDB接続エラーがなかなか解消しません。再トライ中。
今回は2番目のDocker+LAMPで試した方法のご紹介です。複数のWordpressサイトをイジるならこれが最適です。1つだけなら、WordpressのDockerコンテナが最も簡単でした。
今回の環境
- Raspberry Pi Zero W
- Raspberry Pi OS (デスクトップ環境ありの通常版)
- Dockerコンテナ Nginx
- Dockerコンテナ PHP8.0
- Dockerコンテナ MySQL 5.7(hypriot/rpi-mysql)
- Dockerコンテナ phpmyadmin
Raspberry Pi OSがLiteではないのは、多くのライブラリがインストールされているためで、デスクトップ環境を利用したわけではありません。ちなみに、デスクトップでの操作は、ZeroWではメモリーが足りなく、Docker側でメモリー調整しないとマウス操作やキーボード操作は激重でした。
MySQLにhypriot/rpi-mysqlというイメージを選択したのは、Zero Wでは公式のMySQLがpullできなかったためです。
Dockerのインストール
ネットで検索すると、Dockerも更新頻度が多いのか、情報がたくさんあって迷いました。
細かい例外は省いて、Raspberry Pi OS(デスクトップ環境)で導入した方法です。他のOSでは必要なライブラリやアプリケーションはまだあります。
いつもの手順。最新に更新。
sudo apt update
sudo apt full-upgrade
dockerをダウンロードしてインストールスクリプトの実行。
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
ユーザーpiで実行できるようにグループに追加する。これでDockerではsudoが必要ありません。
sudo usermod -aG docker pi
複数のコンテナを定義して実行するツールの「docker-compose」も入れます。
sudo pip3 install docker-compose
ここで一旦、再起動します。
sudo shutdown -r now
Raspberry Pi OSだと最初からpipもPythonもインストールされていて便利です。
動作テスト
再起動後、dockerの動作確認として、infoとversionで情報を見ました。続いてhello worldのイメージをpullして実行させます。
docker info
docker version
docker run hello-world
エラーが無ければ、とりあえずOKです。
事前準備
フォルダの構成から整えます。ホームフォルダにHTMLなどをまとめておくhtdocs、WebサーバーのNginx、PHPの3つと、docker-composeの設定ファイルである.ymlファイルを置きます。

この辺りは、ご自分の環境に合わせてください。
用意するファイル内容
参考サイトから設定しました。
server {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ .php$ {
fastcgi_split_path_info ^(.+.php)(.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
FROM php:8.0-fpm
COPY ./php.ini /usr/local/etc/php/
RUN apt-get update \
&& apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libonig-dev \
&& docker-php-ext-install pdo_mysql mysqli gd iconv exif
date.timezone = Asia/Tokyo
mbstring.language = Japanese
mbstring.detect_order = ASCII,ISO-2022-JP,UTF-8,eucJP-win,SJIS-win
mbstring.substitute_character = none
mbstring.func_overload = 0
Docker-compose設定ファイルは.yml
今回、LAMP環境を構築するのでYAML(ヤメル)に記述します。
sudo nano docker-compose.yml
msqlのイメージは、Raspberry Pi Zero Wでは、mysqlもMariaDBもダメだったので、探して動作していたhypriot/rpi-mysqlのイメージにしました。
ERROR: no matching manifest for linux/arm/v6 in the manifest list entries
Raspberry Pi 3以上であれば、arm32v7ですから、mysql:5.7などで大丈夫です。
タグ
Tagの取り扱いに:latest
は無くても自動的に付きます。敢えてバージョンを指定するか、何も付けない方が良いようになっていると判断しました。(:5.7
など)
このタグは後々も指定していくことになります。意外とコンテナ名、サービス名とタグ名って重要です。ややこしいことこの上ない。
docker-composeの設定内容
docker-composeの設定ファイルを作成します。docker-compose.ymlとdockerfileはテキストファイルです。Raspberry Piであればnanoで新規作成して記述していくことになります。
sudo nano docker-compose.yml
docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx
ports:
- 8082:80
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
- ./htdocs:/var/www/html
depends_on:
- php
restart: always
php:
build: ./php
volumes:
- ./htdocs:/var/www/html
depends_on:
- mysql
restart: always
mysql:
image: hypriot/rpi-mysql
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: 'password'
restart: always
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
ports:
- 8080:80
depends_on:
- mysql
restart: always
volumes:
db-data:
正しくは、docker-compose up --buildでbuildしてから起動させたり、makeテストしてからとは思いますが、dockerっていっぺんにやってくれる。
docker-compose -f docker-compose.yml up -d
調べると、-fオプションはymlが同フォルダでなくても実行してくれて、-dはバックグラウンドで起動します。
ERROR
このとき、いきなり以下のエラーが出た場合は、インデント(字下げ)かTABとスペースの混在などが原因です。Pythonと一緒ですね。
ERROR: yaml.parser.ParserError: while parsing a block mapping
in "./docker-compose.yml", line 1, column 1
buildされます。Raspberry Pi Zero Wの場合は余計に時間が掛かります。いくつかエラーが出て終わらないことがあったので、Ctrl +C で中断させ、エラーに対応して何度か試みました。
書式のバージョン
docker-composeで最初に記載する書式バージョンがDocker初心者としてはハテナでした。このバージョン指定によって使える記法が変わるからです。この時点で最新のバージョンを指定しています。
nginxのポート番号
ちなみにnginxのポート番号は、Raspberry PiのApache2と被ってエラーが出たので、8082ポートへ変更の設定をしています。(docker-compose.yml)
ports:
- 8082:80
WARNING情報
Raspberry Pi Zero Wのスペックが低いせいか、infoコマンド情報で警告が出ていました。
WARNING: No memory limit support WARNING: No swap limit support WARNING: No kernel memory TCP limit support WARNING: No oom kill disable support WARNING: No cpuset support WARNING: No blkio throttle.read_bps_device support WARNING: No blkio throttle.write_bps_device support WARNING: No blkio throttle.read_iops_device support WARNING: No blkio throttle.write_iops_device support
これがERRORだと動作しません。WARNINGだけなら対処するか、そのままでも大丈夫な場合がありました。
確認する作業
何度もコンテナのチェックなどはしました。起動しているのか(UP)、ポート番号と変換、サービス名やコンテナ名を確認するためです。
イメージファイルの確認
Dockerのイメージファイルができたのか確認するコマンド。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
raspida_php latest dd471d5cdfbe 44 minutes ago 351MB
php 8.0-fpm 95e8903e5921 12 days ago 327MB
nginx latest 0566240800d0 2 weeks ago 117MB
hello-world latest 65a05aec0e4d 4 weeks ago 8.95kB
phpmyadmin/phpmyadmin latest 2e5141bbcbfb 2 months ago 474MB
hypriot/rpi-mysql latest 4f3cbdbc3bdb 3 years ago 209MB
コンテナをチェック
一番多く叩いたコマンドかも知れません。
docker ps -a
よりも現在はdocker container ls
が推奨されていました。
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81619df3c023 nginx:latest "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8082->80/tcp, :::8082->80/tcp raspida_nginx_1
3720ac3f1ac6 raspida_php "docker-php-entrypoi…" 30 minutes ago Up 29 minutes 9000/tcp raspida_php_1
6aea733a7d44 phpmyadmin/phpmyadmin:latest "/docker-entrypoint.…" 30 minutes ago Restarting (1) About a minute ago raspida_phpmyadmin_1
327d9fa9efb5 hypriot/rpi-mysql "/entrypoint.sh mysq…" 30 minutes ago Up 30 minutes 3306/tcp raspida_mysql_1
5873e878db0c hello-world "/hello" 3 hours ago Exited (0) 3 hours ago determined_northcutt
HTMLの表示確認
予めhtdocsフォルダに置いたHTMLの通り、Hello World!!が表示されればOKです。(index.html)
http://rpizerow.local:8082/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>
<p>Hello World!!</p>
</body>
</html>
PHPの動作確認
これもhtdocsフォルダにphpを置いて確認します。(phpinfo.php)
http://rpizerow.local:8082/phpinfo.php
<?php
phpinfo();
?>

LAMP環境ができた
ここまでで、ザックリとLAMP環境を構築できました。Dockerなので、ネイティブでインストールしたLAMP環境との違いがあります。
1つは、ポート番号。Dockerを入れたマシンのローカル環境か、ssh接続などでの遠隔操作かによっても対応する部分があります。
もう1つは、データベースとの連携です。Dockerの場合、localhostは通りません。コンテナ名で指定することも出てきます。
あくまでもDockerは仮想環境なので、それを念頭に名前やアドレスなどを指定していくことになります。
どうせ一気に削除できるコンテナなので、Dockerは地道にトライアンドエラーで試すのに向いています。
WordPressの導入
DockerでLAMP環境が構築できたら、レンタルサーバーでの設置と同様にWordpressをダウンロードして指定の場所へ展開します。
mysqlとのデータベース連携など、ここでは触れていません。
もう少し簡単なDockerコンテナ2つでできるWordpressテストサーバー
ヒント・備忘録
hypriot/rpi-mysqlを元に、コンテナ名wordpressで、wp_dbを作成しながら、コンテナの起動。
docker run --name wordpress -e MYSQL_ROOT_PASSWORD=ymlで指定したルートのパスワード -e MYSQL_DATABASE=wp_db -d hypriot/rpi-mysql
コンテナ名wordpressのwp_dbにrootでログインして接続する。
docker run -it --link wp_db:wordpress --rm hypriot/rpi-mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
視覚的に設定できるphpmyadminのコンテナをmyadminの名前で起動
docker run --name myadmin -d --link wp_db:mysql -p 8080:80 phpmyadmin/phpmyadmin
実際に試したコマンドなどの設定方法は、別の記事でご紹介します。
dockerとdocker-composeのコマンド
dockerやdocker-composeのコマンドの中で、起動、終了、再起動、コンテナの停止や削除といったやり直しのコマンドも覚えておきましょう。
Dockerの利点の1つに、すべて最初からという場合もコンテナの削除でアッサリ済む点があります。新たにコンテナを追加する場合も含め、お手軽に環境やサービスを使うためにDockerにしてるからです。
たくさんあるので、よく使うであろうコマンドを載せておきます。
起動
基本的に起動は短い以下のコマンドとオプションでOKです。
docker-compose up -d
終了(サービス停止)
docker-compose stop
続けてdocker container ls
で表示されたNAME(コンテナ名)を指定することもできます。他のコマンドも同じです。
サービスは停止してもコンテナは生きています。
開始・再開
停止しているコンテナを開始したり再開させます。
docker-compose start
docker-compose restart
サービスとコンテナも停止
こちらはコンテナも停止します。(全部のコンテナ)
docker-compose down
コンテナの削除
停止させてからコンテナは削除できます。
docker rm コンテナ名(スペースで複数指定可能)
停止しているコンテナをすべて削除
必要なコンテナは停止させずに、要らないコンテナを先に停止させてから実行すると便利でした。
docker container prune
コンテナが使っていないイメージを削除
docker image prune
タグ名がないイメージをすべて削除
buildに失敗したイメージなどは、docker images
で表示されたTAG欄に<none:none>と表示されます。それらを削除できます。
docker rmi $(docker images -f 'dangling=true' -q)
一括削除
これは停止しているコンテナ、コンテナから使われていないイメージ、そしてボリューム(Volume)をすべて一括に削除できます。
docker system prune
ちょっとやり直すというときに重宝します。
滅びの言葉バルスみたい。
エラーまとめ
Build時のエラーに対応しました。
[Warning] The requested image's platform (linux/arm/v7) does not match the detected host platform (linux/arm/v6) and no specific platform was requested
Raspberry Pi Zero Wで実行したので、古いCPUアーキテクチャに対応していない。とりあえず無視。
debconf: delaying package configuration, since apt-utils is not installed
これは無視してもOKのようです。
PHP: syntax error, unexpected END_OF_LINE, expecting '=' in /usr/local/etc/php/php.ini on line 4
PHP8.0から定義方法が変わったみたい。予め作成したphp.iniを修正。
mbstring.internal_encoding =
→ mbstring.detect_order =
WordPressだけならコンテナも
LAMPサーバーとして必要なく、Wordpressを動作させるだけならば、Dockerのコンテナの方が簡単です。
そちらは別の記事でご紹介しています。
主な参考サイト:CodeAid-Lab | Docker ドキュメント日本語化プロジェクト | docker初心者が、docker-compose.ymlの書き方をまとめる