Preface
Actually, I have always wanted to write a tutorial on building the Docker version of Nextcloud. The reason is that every time I redeploy it, I have to spend a lot of time troubleshooting, and there are too many details to remember. However, because it is indeed too troublesome and requires writing a lot, I really didn't have the mood or motivation to actively do it. But this opportunity finally came. Just yesterday, thinking that Nextcloud hadn't been upgraded for a long time, I directly ran `docker pull linuxserver/nextcloud` and then rebuilt it, and then, as expected:

Well, this is not the first time. Upgrading the linuxserver/nextcloud version is prone to various issues if it spans major versions, so I might as well take this opportunity to move nextcloud from the macmini to the inter mini host, and that's how this article came to be.
Note: Actually, deploying Nextcloud using Docker Compose is simpler. However, based on the reasons I mentioned before, in order to reuse existing containers (MariaDB, Redis), I prefer to use the `docker run` method. If you prefer simplicity, the Docker Compose method is highly recommended.
Create and initialize MariaDB database
Nextcloud requires a database. The options are SQLite, MariaDB, and PostgreSQL. You can choose according to your own usage habits. I use MariaDB more for my other applications, so since I have an existing one, I chose MariaDB directly (MySQL is also fine, but when there is a choice, always prioritize MariaDB).
Since I am deploying using the `docker run` method, I need to manually create the MariaDB database and perform initial configuration (if you have an existing MariaDB, just initialize it directly). The recommended process for creating a new MariaDB database is as follows:
Create a new public-net bridge (optional)
docker network create public-net
**Item 9:**
This step is not mandatory, but because both the MariaDB container (and the subsequent Redis container) and the Nextcloud container need to reference this non-default bridge `public-net` so that Nextcloud can directly access MariaDB using the container name, it needs to be created in advance (if you have other existing non-default bridges, you can also reuse them).
Actually, using the `--link` parameter in Nextcloud to directly link MariaDB can achieve the same purpose. However, for easier management and maintenance in the future when there are more containers (for example, creating different bridges to connect containers in different zones), try not to use the `--link` parameter. Because when there are many containers, linking them everywhere might confuse you and make maintenance difficult, so it is best to develop a good habit of using the `--net` parameter from the very beginning.
Create a new MariaDB database (optional)
If there is no MariaDB database container in the environment or you do not want to reuse an existing one, you need to create a new one.
Create the directory on the host machine that needs to be mounted into the MariaDB container
mkdir -p /docker/mariadb/db
Create the MariaDB container
The command to set up the MariaDB database in `docker run` format is as follows:
docker run --name=mariadb01 -d --restart=always \
--net=public-net \ #指定mariadb容器使用public-net bridge,需要和后面的nextcloud一样
-p 3306:3306 \ #映射宿主机的3306端口到容器的3306端口
-v /docker/mariadb/db:/var/lib/mysql \ # 挂载前面创建的宿主机目录到容器内部指定目录
-e MARIADB_ROOT_PASSWORD=123 \ #指定数据库root用户对应的密码,这个大家自行修改
mariadb:10.11
Initialize MariaDB database
For details, please refer to my other article:Tips and Tricks Series: Creating a New Empty Database and Granting Permissions to Corresponding Users, in the following text, it is assumed that the database name, corresponding username, and password after initialization are all ”nextcloud”.
Deploy Nextcloud
Pre-deploy Nextcloud
First, use the simplest command to create Nextcloud:
docker run --name=nextcloud -d linuxserver/nextcloud
Then copy the three directories config, app, and data inside the container to the /docker/nextcloud/ directory on the host:
docker cp nextcloud:/config /docker/nextcloud
docker cp nextcloud:/app /docker/nextcloud
docker cp nextcloud:/data /docker/nextcloud
The purpose of doing this is to copy out the contents of these folders required for the normal deployment of Nextcloud first, because if you directly use the -v parameter to mount empty folders on the host to the inside of the container, the container will not start at all.
Delete the container:
docker stop nextcloud
docker rm nextcloud
Formally deploy Nextcloud
The Docker format command is as follows:
docker run --name=nextcloud -d --restart=always \
--net=public-net \ #和mariadb容器连接在同一个bridge
-p 9010:80 \ #映射宿主机9010端口到容器的http 80端口,大家根据自己实际环境修改端口
-e TZ=Asia/chongqing \ #设置容器时区
-v /docker/nextcloud/app:/app \ #将前面3个从容器内部复制到宿主机的文件夹分别映射到容器内部的指定文件夹
-v /docker/nextcloud/data:/data \
-v /docker/nextcloud/config:/config \
linuxserver/nextcloud
Note: There are also two parameters-e PUID=xxx和-e PGID=xxxare optional parameters. If permission issues are caused by-vparameters, you can consider using them (if there are no permission issues, do not use them; for example, in my case, it was fine without them, but after using them, the container became directly inaccessible). The specific PUID and PGID values are obtained byid usernamecommand, as follows:

Configure Nextcloud
Initialize Nextcloud
Usehttp://宿主机IP:9010Access Nextcloud:

Note: To properly install the recommended apps later, you need a VPN or proxy environment, otherwise you can only install them manually later.
Initialization successful:

Change default language


Done:

Allow access via domain name
Like WordPress, Nextcloud also locks the access address used during initialization. For example, in the previous section, we usedhttp://宿主机ip:9010to initialize, then when we want to use it through a reverse proxynextcloud.example.comto access via domain name, the following situation will occur:

It will tell us that we are accessing using an untrusted domain name. The solution is to modify the config/config.php file.
Edit the host file /docker/nextcloud/config/www/nextcloud/config/config.php:
vim /docker/nextcloud/config/www/nextcloud/config/config.php
By default, it looks like this in the red box:

At this point, there are two formats for modification:
Format 1
'trusted_domains' =>
array (
0 => '192.168.1.10:9010',
1 => 'nextcloud.example.com',
),
Format 2
'trusted_domains' =>
[
'192.168.1.10:9010',
'nextcloud.example.com'
],
Note: Format 2'nextcloud.example.com‘does not have a ',' after it,,while Format 1 does.
After modification, save config.php and restart the nextcloud container, then you can log in using the domain name.
Note: For the specific configuration of the reverse proxy, please refer to my other two articles:Docker Series: Building Your Own Reverse Proxy Based on NPM Using Docker和Linux Panel Series: Configuring Reverse Proxy and Publishing Using Non-443 Ports。
Optimize Nextcloud performance using Redis
Actually, up to this point, nextcloud is already usable. However, we can optimize the performance of nextcloud and improve the user experience through some subsequent operations.
Deploy the redis container:
docker run --name redis -d --restart=always --net=public-net -p 6379:6379 redis
Edit the config.php file and find the following content:

Change the
APCuin the red box toRedisand add the redis cache server:
'memcache.locking' => '\\OC\\Memcache\\Redis', #将文件锁改为redis缓存文件锁
'redis' => #指定redis缓存服务器的地址和端口
array (
'host' => 'redis',
'port' => 6379,
),
As shown in the figure below:

Save the changes and restart the nextcloud container.
Security and optimization warnings
In the overview of administration settings, there will be some security warnings:

These warnings do not affect usage (actually, if you have deployed nextcloud using source code before, you would know that these warnings are really nothing...), but as a perfectionist, it really feels uncomfortable to look at them, so let's try to resolve them as much as possible.
1、

These two can be resolved by adding the following configuration to the config.php file:
'default_phone_region' => 'CN',
'mail_smtpmode' => 'smtp',
'mail_smtphost' => 'smtp.163.com',
'mail_sendmailmode' => 'smtp',
'mail_smtpport' => '587',
'mail_smtpsecure' => 'ssl',
'mail_from_address' => 'abcd', #假设邮箱地址为[email protected]
'mail_domain' => '163.com',
'mail_smtpauth' => 1,
'mail_smtpname' => 'abcd',
'mail_smtppassword' => 'xxxxxxxxxxxxxxxx', #163邮箱授权码,不是邮箱登录密码
Note: The email section can also be configured in ”Basic settings” - “Email server”:

2、

This is because we mapped the HTTP port 80 of the nextcloud container, but we are accessing nextcloud using HTTPS through a reverse proxy, which causes nextcloud to be confused. We need to tell nextcloud to add the reverse proxy address to the trusted proxies list. This can be resolved by adding the following configuration to the config.php file:
'trusted_proxies' =>
array ( 0 => '192.168.1.1', #假设192.168.1.1是反向代理的IP地址
),
3、

If nextcloud is deployed from source code, resolving this error requires modifying the configuration file in the deployed web server. However, since we deployed it using Docker, there is no need to worry about it, we can just disable the check directly. This can be resolved by adding the following configuration to the config.php file:
'check_for_working_wellknown_setup' => false,
4、

Modify the config.php file and add the following configuration:
'maintenance_window_start' => 1,
5、

If nextcloud is deployed from source code using Nginx and SSL decryption is performed on Nginx, to resolve this issue you only need to add the following content to the Nginx configuration file:
add_header Strict-Transport-Security "max-age=15552000";
If a CDN is used, such as Cloudflare or other domestic CDN providers, HSTS needs to be enabled and the expiration time set to at least
6 monthsor15552000 seconds。
Cloudflare:

Tencent Cloud CDN:

Note: Once HSTS is enabled and the expiration time is set, during this period, the browser will only access using HTTPS. If the website is changed back to HTTP, it will become inaccessible.
6、

This is said to be a bug. If it must be resolved, the previous solution was to run the apt command in the container to install it:
docker exec --user root -it nextcloud /bin/bash -c 'apt update && apt install -y libmagickcore-6.q16-6-extra'
However, in the latest version of nextcloud (I am currently on 28.0.3), even the apt command is gone... I just have to bear with it, this is all I can do for now, unfortunately leaving one loose end.
Restart nextcloud, and the final result is as follows:

P.S.: Since HSTS is enabled, we definitely need to test the grade. Here is the URL to test the website's SSL security level. Interested friends can do a test for fun:
https://www.ssllabs.com/ssltest/
About linuxserver/nextcloud upgrade
Below is the translation of the official statement on nextcloud upgrades on linuxserver (original link is as follows:https://docs.linuxserver.io/images/docker-nextcloud/):
“The method to update Nextcloud is to pull the new image and recreate the container with it.
Only one major version can be upgraded at a time. For example, if you want to upgrade from version 14 to version 16, you must first upgrade from version 14 to version 15, and then from version 15 to version 16.
Since all data is stored in the /config and /data volumes, no data will be lost. The startup script checks the version in the volume and the installed docker version. If a mismatch is found, it will automatically start the upgrade process.”
But in reality, I don't upgrade the nextcloud version very often. By the time I suddenly remember to do so, it has usually been at least one major version apart. At this point, if you use the usual container upgrade method: pull the image first, then rebuild, the probability of failure is very high (just like why I had to reinstall nextcloud this time~~~), so it is best to upgrade inside the container:

But if you ask me why I don't use the official nextcloud image instead of the linuxserver/nextcloud version, I've almost forgotten the reason. My impression is that at the time, I felt the file organization of the linuxserver/nextcloud version was better, and the explanation of command parameters on Docker Hub suited my taste more. The official nextcloud one gave me a headache. Later, once I got used to it, I was too lazy to change... You can also try using the official image directly, but if you use the linuxserver/nextcloud version, you must be careful when you want to upgrade.
Client settings
Another powerful feature of nextcloud is its support for multi-platform clients:

However, the prerequisite for using multi-platform clients normally is that nextcloud has a public domain name, such as the previously mentioned ”nextcloud.example.com”. Below, taking the setup process of the Mac version of the nextcloud client as an example, we will demonstrate how to add a nextcloud server with an existing public domain name. Just follow the steps below:





Success:

The setup methods for clients on other platforms are similar, so I won't go into details one by one.
In the future, as long as you drop the files that need to be synchronized across multiple platforms into the local nextcloud folder, such as my Obsidian working directory, you will see the same content when you open Obsidian on any other platform.
If you want to write on a Mac and also open it on an iPad or iOS, you need to route it through iCloud. For example, periodically sync the Obsidian folder in the local nextcloud to iCloud, and then set the Obsidian working directory on iOS and iPad to the folder in iCloud.
Afterword
Actually, the above are just the most basic functions of nextcloud. There are many fun things to play with in nextcloud, which are all implemented through its apps (requires VPN or proxy, otherwise you can only find a way to download offline packages and install them yourself):

For example, you can turn it directly into an online music player by installing a music player and scanning lossless music on external storage; you can achieve online multi-format document editing by installing the onlyoffice plugin and pairing it with the onlyoffice container (see:Docker Series: Deploying OnlyOffice Container for Nextcloud); it can support multiple users and turn nextcloud into a small portal where administrators can send announcements to other users and implement workflow management; it can be integrated with many commonly used software in the world; it can allow users to register by email on their own, etc. For specific nextcloud applications, you can search online, there are really too many to cover.
P.S.: Finally caught up with the tutorial on setting up the Docker version of nextcloud, it was so hard to write.
I deployed this nextcloud, and it is incredibly laggy. It can't be used smoothly at all, my experience is terrible. I don't know how to optimize the access speed. Waiting for updates.
What method did you use to deploy it? Docker?
Boss, how do I change the Chinese font for avatar display in the linuxserver version of nextcloud? I know how to set it in the official version, but I don't know where it is in the linuxserver version.
The official version is:
Upload the font to /AppData/nextcloud/config/www/nextcloud/core/fonts/SourceHanSerifSC-Bold.otf
Modify the file /AppData/nextcloud/config/www/nextcloud/lib/private/Avatar/Avatar.php
I really haven't studied the linuxserver version of nextcloud...