How to establish nextcloud which consists of docker-compose of nginx/php-fpm?

Container

Before I explained how to establish nextcloud server on one container environment which is consists of apache/modphp.



Later I found below rumor.

nginx/php-fpm is much faster than apache/modphp!

Then I challenged to establish with nginx/php-fpm.
And it is good chance to learn docker-compose!

yatch
yatch

It will be piece of cake if I use someone’s docker-compose.yml😇

I thought it, but it took more workload than expected.
Let me share some blocking points I managed to overcome.

If you are only interested in success case, not blocking points, please go here.

System structure

My idea is below which is usual.

Installing docker-compose

It can be done by referring below article.

How To Install Docker and Docker-Compose On Raspberry Pi
RaspberryPi ARMed with Docker and Docker-Compose

Failure case

Using official docker-compose.yml

Below URL navigates you to official nextcloud docker-compose.yml and other files.

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.



I created docker-compose.yml referring above URL.

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



I started containers by below command but didn’t work.

sudo docker-compose up -d

Weather info cannot be obtained.
– Below Japanese message says “Error happened during obtaining weather information.”



And I coundn’t change language setting from Japanese to English.
– Actually I operated to change, but language didn’t change.

Firstly I doubt of mariadb but,

Databases/Tables exist when I checked with mysql command.
The same problem happened with sqlite3 instead of mariadb.

So mariadb is not cause of problem.

Also nginx should not be cause of problem because nextcloud page is shown.
– If nginx has problem nextcloud page doesn’t show.

I found some info from error log of nextcloud.
trashManager seems to be relevant with trashbox.



I also found this item in error log.
IVersionManager seems to be version management and isn’t relevant with trashManager.



For both SimpleContainer->resolve() is key.
So I tried to find root cause for a few days but I coundn’t.

I gave up to find root cause…

However php-fpm/nextcloud should have some problems because nginx and mariadb don’t have.
Then I decided to create my own php-fpm/nextcloud environment.

Success case

Below URL you can find my own php-fpm/nextcloud parts.
I also configured nginx to align them.

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



You can start by below commands set.

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



At 08/01/2021, HTTPS is not supported, I will do on upcoming days.
Firstly I used sqlite3 to easily work, then switch to mariadb.
– Using mariadb is explained by below article.

Container which nextcloud runs on php-fpm

This is 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



The summary of build is follows.

apt update/upgrade
Neccessary packages (like php-fpm) are installed by apt install
php-fpm.conf/www.conf which are configuration of php-fpm are copied into image
Zip file of nextcloud is downloaded
PHP session directory is prepared



Below entrypoint.sh runs when container starts.

#!/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



The summary of workflow is,

Do below block if index.php of nextcloud doesn't exist.
 - Extract nextcloud zip file and deploy to document root of nginx
 - Replace the contents of config.php with real server name
Replace some environment variables to real values and deploy configuration file of php-fpm
Start php-fpm



php-fpm supports both TCP socket and Unix Domain Socket.
I configured to use Unix Domain Socket because I assume it will be faster.

This is the point.
 ./php-fpm/pool.d/www.conf.template

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



PHP_VER is defined in .env file.
At 08/01/2021 php-fpm is 7.3.x and it has possibility to update to 7.4.x or more.
To define by PHP_VER it will be easy to update php-fpm.



Below is the contents of .env.
NGINX_SERVER_NAME should be replaced to your 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

Collaboration between nginx and php-fpm

php-fpm is configured Unix Domain Socket to receive request from frondend, nginx in this case.
So nginx should be also configured to use Unix Domain Socket.

This is point.
 ./nginx/conf.d/default.conf.template
The same file path which is used in configuration of php-fpm.

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



And I defined volume to share the same object between nginx container and php-fpm container.
Below is point of docker-compose.yml.

version: '3.1'

services:

  nginx:
    volumes:
     - php_socket:/var/run

  nextcloud:
    volumes:
     - php_socket:/var/run

volumes:
  php_socket:

Remaining issue

I have one issue.
When setup is done nextcloud usually starts installing recommended application like talk.

URL to be redirected should be http://yasufumi-yokoyama.ml/index.php/core/apps/recommended/ or something like that, but it is http:///index.php/core/apps/recommended/ .
– yasufumi-yokoyama.ml is not there.

This is screen shot of Chrome developer tool.
– You may notice 3 ‘/’ continues after http: in Location header.



As workaround of this issue, when you are redirected to http:///index.php/core/apps/recommended/ (and of course your browser shows error), you can enter correct URL like http://yasufumi-yokoyama.ml/index.php/core/apps/recommended/.
Then installation of application will automatically starts as usual.

So this is not fatal error. I will fix this problem if I have time😇

Conclusion

How was it?

I didn’t compare both result between apache/modphp and nginx/php-fpm using ab or other benchmark utility.

I rushed explaining and didn’t dive deep.
If you are interested in and want more detail, please comment or DM by SNS!

Comments

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