Build your own personal cloud drive using Docker based on Nextcloud
This article was last updated 287 days ago. The information within may have evolved or changed; if anything is outdated or broken, please feel free to leave a message in the comments section.
Article Abstract
This article revolves around the practical process of deploying a Nextcloud personal cloud drive using Docker, focusing on solving key issues in containerized deployment such as database configuration, network bridging, permission management, and performance optimization. By manually creating a MariaDB container and mounting host directories to achieve data persistence, combined with Redis caching to improve response speed, it also addresses common deployment difficulties such as reverse proxy domain binding and security warnings. Ultimately, a private cloud storage environment supporting multi-platform synchronization and scalable applications is built, and the feasibility and flexibility of deploying Nextcloud via Docker are verified through practical operations, leaving expansion space for subsequent integration of plugins like OnlyOffice and music players.
Qwen3-14B · 2026-06-18

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:

image.png

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:

image.png

Configure Nextcloud

Initialize Nextcloud

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

image.png

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:
image.png

Change default language

image.png

image.png

Done:
image.png

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:

image.png

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:

image.png

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:

image.png

Change theAPCuin 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:

image.png

Save the changes and restart the nextcloud container.

Security and optimization warnings

In the overview of administration settings, there will be some security warnings:

image.png

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、

image.png

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”:

image.png

2、
image.png

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、

image.png

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、

image.png

Modify the config.php file and add the following configuration:

'maintenance_window_start' => 1,

5、

image.png

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:

image.png

Tencent Cloud CDN:
image.png

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、

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

image.png

image.png

image.png

image.png

Success:
image.png

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):

image.png

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.

View Related Categories · 3 Matches
📌 Content Structure Prompt:
This content is part of the following knowledge map, where you can view the complete content path: Blog Knowledge Map。
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.

Comments

  1. lincol29
    Windows Chrome 127.0.0.0
    2 years ago
    2024-8-09 14:04:34

    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.

    • Owner
      lincol29
      Macintosh Chrome 127.0.0.0
      2 years ago
      2024-8-15 10:11:35

      What method did you use to deploy it? Docker?

  2. ~~
    Windows Edge 127.0.0.0
    2 years ago
    2024-8-01 4:23:46

    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

    • Owner
      ~~
      Macintosh Chrome 127.0.0.0
      2 years ago
      2024-8-02 21:44:26

      I really haven't studied the linuxserver version of nextcloud...

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews