nextcloudをRaspberry Pi 4のnginx+php-fpmでdocker-compose

Docker



以前↓の記事で、ラズパイ4にてnextcloudを1つのDockerコンテナで動かせるようにしました。
apache/modphpの構成です。



その後、

apache/modphpよりもnginx/php-fpmの方が速くていいぞ!

という情報をネットで見かけたので、やってみました。
せっかくなので、docker-composeを勉強しながら。

誰かが公開してくれているレシピを使えば余裕だろ

と思っていたのですが、思いのほか苦労してしまったので、語りながら記事にしていきます。

苦労話はどうでもよくて、サクッとやり方だけ知りたい方はこちら

システム構成

こんな感じで構築したいなあ、と考えました。
まあありがちな構成ですよね。

docker-composeのインストール

こちらの記事を参照させていただきました。
サクッと入れられます。

ラズパイ4にdocker,docker-composeをインストール - Qiita
Docker # dockerをインストールする $ curl -sSL | sh # pi,dockerユーザに docker コマンドが使えるように権限を与える $ sudo ...

うまくいかなかったやつ

公式のdocker-compose.ymlを使ってみた

ここにnextcloud公式(だと思う)によるdocker-compose.ymlなどのファイル一式があります。

docker/.examples/docker-compose/with-nginx-proxy/mariadb/fpm at master · nextcloud/docker
⛴ Docker image of Nextcloud. Contribute to nextcloud/docker development by creating an account on GitHub.



こんな感じでdocker-compose-ymlを作りました。
 ↑のサンプルそのまんま…
 ほかにもnginx.confなどもほぼそのまま流用。

version: '3.1'

services:

  nginx:
    image: nginx
    restart: always
    ports: 
     - 80:80
    volumes:
     - ./nginx/nginx.conf:/etc/nginx/nginx.conf
     - ./nginx/conf.d:/etc/nginx/conf.d
     - ./nginx/log:/var/log/nginx
     - ./nextcloud:/var/www/html
    depends_on:
     - nextcloud

  nextcloud:
    image: nextcloud:stable-fpm
    restart: always
    environment:
      MYSQL_HOST: db
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: nextcloud
      MYSQL_DATABASE: nextcloud
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: admin
      NEXTCLOUD_TRUSTED_DOMAINS: yasufumi-yokoyama.ml
    volumes:
      - ./nextcloud:/var/www/html
    depends_on:
      - db

  db:
    image: linuxserver/mariadb:latest
    restart: always
    ports:
      - 127.0.0.1:3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: nextcloud
      MYSQL_DATABASE: nextcloud
    volumes:
      - ./databases:/config/databases



さっそく

sudo docker-compose up -d

でやってみたのですが、うまく動きませんでした。

まず天気情報が取れないとエラーになりました。



また、表示言語を日本語→英語から切り替えようとしても、日本語のままで変わりませんでした。

最初にmariadbがうまく動いていないのか、と疑いましたが

mariadbの中身を見てみたら、データベースやテーブルはできていた
sqlite3にしても同じ問題が発生した

ということで、mariadbが問題ではなさそうでした。

また、nextcloudの画面自体は表示されていたので、nginxの問題とも考えにくいです。
 nginxの問題であれば表示自体されない可能性が高い。

手がかりはnextcloudのログ画面で表示された以下のエラーログ。
trashManagerということで、ゴミ箱関係っぽいです。



他にあったのはこのエラーログ。
IVersionManagerはバージョン管理っぽいですが、先ほどのtrashManagerとは関係なさそうで。



両方ともSimpleContainer->resolve()が正常動作していないことはわかるので、これを手がかりにnextcloudのPHPにログを入れるなどして数日デバッグしてみましたが、どうにもわからず。

原因を解明するのは諦めました。

ただ、php-fpm/nextcloudに問題があることは確度が高そうでしたので、自分でphp-fpm/nextcloud環境を作ることで対応することにしました。

うまくいったやつ

ということで、自分でphp-fpm/nextcloud部分を作り直したものがこちらになります。
nginx周りも設定ファイルで合わせこみをしています。

GitHub - kurofuku/nextcloud-container-fpm
Contribute to kurofuku/nextcloud-container-fpm development by creating an account on GitHub.



以下のようにして動かせるようになっています。

git clone https://github.com/kurofuku/nextcloud-container-fpm.git
cd nextcloud-container-fpm
sudo docker-compose up -d



2021/08/01時点では、データベースにsqlite3を使っています。
また、HTTPSにも非対応です。
 まず一通り動くものを作りたかったため。
このあたりはおいおいやっていきます。

2021/08/05追記
mariadbへの対応をしました!

php-fpm上でnextcloudが動くコンテナを作った

まずDockerfile。

FROM		debian:latest

ARG		NGINX_USER
ARG		NGINX_GROUP
ARG		NGINX_ROOT
ARG		NGINX_SERVER_NAME
ARG		PHP_VER
ARG		PHP_SESSION_DIR
ARG		NEXTCLOUD_VER

ADD 		. /php-fpm

RUN		\
		# Move Neccessary files for run
		mv /php-fpm/entrypoint.sh / && \
		chmod 775 /entrypoint.sh && \
		mv /php-fpm/config.php.template / && \
		# Update to latest
		apt -y update && \
		apt -y upgrade && \
		# Install neccessary packages
		apt -y install wget php-fpm unzip php-zip php-xml php-mbstring php-gd php-curl php-sqlite3 gettext-base && \
		# Setup php-fpm
		cp /php-fpm/php-fpm.conf.template /etc/php/${PHP_VER}/fpm/php-fpm.conf.template && \
		mkdir -p /etc/php/${PHP_VER}/fpm/pool.d/ && \
		cp /php-fpm/pool.d/www.conf.template /etc/php/${PHP_VER}/fpm/pool.d/www.conf.template && \
		rm -rf /php-fpm && \
		# Download nextcloud
		wget -q https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VER}.zip -O /nextcloud-${NEXTCLOUD_VER}.zip && \
		# Prepare PHP session directory
		mkdir -p ${PHP_SESSION_DIR} && \
		chown ${NGINX_USER}:${NGINX_USER} ${PHP_SESSION_DIR} && \
		chmod 770 ${PHP_SESSION_DIR} && \
		# Prepare directory for pid file
		mkdir -p /run/php && \
		# Done
		echo "Build complete." 

ENTRYPOINT	sh /entrypoint.sh



ビルド時の大きな流れは以下の通りです。

apt update/upgrade
apt installで必要なパッケージを入れる(php-fpmとか)
php-fpm用設定ファイルであるphp-fpm.conf, www.confをイメージ内にコピー
nextcloudを公式サイトからダウンロード
PHPセッションディレクトリを準備



コンテナ動作時はentrypoint.shを動かします。
以下のコードを動かします。

#!/bin/sh
if [ ! -f ${NGINX_ROOT}/index.php ]; then
    cd  /;
    unzip -q /nextcloud-${NEXTCLOUD_VER}.zip;
    mv /nextcloud/* ${NGINX_ROOT};
    envsubst '$$NGINX_SERVER_NAME' < /config.php.template > ${NGINX_ROOT}/config/config.php;
    chown -R ${NGINX_USER}:${NGINX_GROUP} ${NGINX_ROOT};
    rm -rf /nextcloud;
    rm /nextcloud-${NEXTCLOUD_VER}.zip;
    rm /config.php.template;
fi
# Replace environment variables to real value
envsubst '$$PHP_VER' < /etc/php/${PHP_VER}/fpm/php-fpm.conf.template > /etc/php/${PHP_VER}/fpm/php-fpm.conf
envsubst '$$PHP_VER$$NGINX_USER$$NGINX_GROUP$$PHP_SESSION_DIR' < /etc/php/${PHP_VER}/fpm/pool.d/www.conf.template > /etc/php/${PHP_VER}/fpm/pool.d/www.conf
# Run php-fpm
/usr/sbin/php-fpm${PHP_VER} --nodaemonize --fpm-config /etc/php/${PHP_VER}/fpm/php-fpm.conf



大まかな流れとしては以下の通りです。

nextcloudのindex.phpがなければ、初回起動と判断し、以下を実行
 nextcloudのzipファイルを展開、配置
 config.php.templateを実際のサーバー名に置換しつつconfig.phpとして配置
php-fpm用の設定ファイルを実際の値に置換しつつ配置
php-fpm起動



php-fpmはTCPソケットとUnix Domain Socket、両方での通信ができるようになっています。
今回は速度的に有利だと思われるUnix Domain Socketで設定しています。

具体的には以下。
 ./php-fpm/pool.d/www.conf.template

listen = /var/run/php${PHP_VER}-fpm.sock



PHP_VERは.envにて定義しています。
2021/08/01時点で入れられるphp-fpmは7.3系でしたが、Ver.upで変わる可能性があります。
そのため、環境変数で定義しておくことにしました。

.envは以下の通りとしています。
NGINX_SERVER_NAMEはご自身の環境に合わせて変えてください。

NGINX_USER=www-data
NGINX_GROUP=www-data
NGINX_ROOT=/var/www/html
NGINX_SERVER_NAME=yasufumi-yokoyama.ml
PHP_VER=7.3
PHP_SESSION_DIR=/var/lib/php/sessions/
NEXTCLOUD_VER=21.0.3

nginx/php-fpmとの連携

前記の通り、php-fpmはUnix Domain Socketで受けられるようにしています。
そのため、nginxもPHP処理はUnix Domain Socketでphp-fpmに渡す必要があります。

具体的には以下で設定しています。
 ./nginx/conf.d/default.conf.template
php-fpmで設定したファイルパスと同じにします。

fastcgi_pass unix:/var/run/php${PHP_VER}-fpm.sock;



また、nginxとphp-fpmとでこのsockファイルを共有するため、ボリュームを定義しています。
docker-compose.ymlの関係する部分のみを抜き出すと以下の通り。
こうすることで、/var/run/以下はnginxとnextcloud、両方のコンテナで同じディレクトリを参照することができます。

version: '3.1'

services:

  nginx:
    volumes:
     - php_socket:/var/run

  nextcloud:
    volumes:
     - php_socket:/var/run

volumes:
  php_socket:

課題

この構成でだいたいうまく動いています。

一点、解決しきれていない課題があります。
初回起動時に管理者アカウントの情報を入れてセットアップを完了させると、通常は推奨アプリのインストールが始まります。
 トークとか。

そのときのURLは http://yasufumi-yokoyama.ml/index.php/core/apps/recommended/ といった文字列なのですが、 http:///index.php/core/apps/recommended/ になってしまいます。
 yasufumi-yokoyama.ml が抜けている。

Chromeのデベロッパーツールで見たときの画面がこれ。
 LocationヘッダーにあるURLで、http: の後に /// と、’/’が3つあります。



これはまだ解決できていません。

暫定策として、
http:///index.php/core/apps/recommended/ に飛んだ後、 http://yasufumi-yokoyama.ml/index.php/core/apps/recommended/ といったように正しいURLを直接入力すれば、推奨アプリのインストール自体は行なえます。

ですので、致命的ではないと判断し、今後適宜対応を取ることにします。

終わりに

いかがでしたか。

速度ベンチマークなどはまだ取れていませんので、今後折を見て検証してみます!

さらっと解説したので、詳説を知りたい方はSNSやコメントなどでメッセージください!

Comments

タイトルとURLをコピーしました