最近上海封控在家,正好鼓捣下nextcloud,安装视频教程网上很多,但实际使用的视频不多。记录一下备忘,也方便参考的人。

目录

安装nextcloud的docker-compose.yml

运行在X86的CPU上,如需要ARM架构需要替换容器为arm架构的镜像。

需要的自取,可以直接安装,目前运行良好(宿主debian11,omv6),.yml里面的密码请自行调整。

如果希望反向代理(更安全些),则把app的外接端口去掉,用proxy设置代理app的内网IP加80端口即可。如果是局域网内的nextcloud的,直接运行,然后在WAN口用nginx反代即可。

其他compose可参考 https://github.com/nextcloud/docker/tree/master/.examples

version: '3'

volumes:
  nextcloud:
  db:
  redis:
services:
  db:
    image: mariadb
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=rootpwd
      - MYSQL_PASSWORD=userpwd
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud


  redis:
    image: redis
    restart: always
    command: redis-server --requirepass someredispassword
    volumes:
      - redis:/var/lib/redis
  app:
    image: nextcloud:apache
    restart: always
    ports:
      # Public HTTP Port:
      - '8080:80'
    links:
      - db
      - redis
    volumes:
      - nextcloud:/var/www/html
    environment:
      - MYSQL_PASSWORD=userpwd
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db
      - REDIS_HOST=redis
      - REDIS_HOST_PASSWORD=someredispassword
      - HOSTNAME=nextcloud_nextcloudhost
    depends_on:
      - proxy
      - db
      - redis

  proxy:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      # Public HTTP Port:
      # - '80:80'
      # Public HTTPS Port:
      # - '443:443'
      # Admin Web Port:
      - '81:81'
      # environment:
      # These are the settings to access your db
      #DB_MYSQL_HOST: "db1"
      #DB_MYSQL_PORT: 3306
      #DB_MYSQL_USER: "npm"
      #DB_MYSQL_PASSWORD: "npm"
      #DB_MYSQL_NAME: "npm"
      # If you would rather use Sqlite uncomment this
      # and remove all DB_MYSQL_* lines above
      # DB_SQLITE_FILE: "/data/database.sqlite"
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:                                              
      - ./npm_data:/data                                      
      - ./letsencrypt:/etc/letsencrypt

  cron:
    image: nextcloud:apache
    restart: always
    volumes:
      - nextcloud:/var/www/html
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis

天气插件显示是℉不是摄氏度

用户-个人信息本地地区设置成使用摄氏度的区域即可。

备份、迁徙数据,或者扩容或变更系统盘地址(踩坑记录)

nextcloud可以看作是私人网盘,实际使用中你可以在网盘里新建文件夹,新建文件,上传照片。从隐私角度,这必然比各种网盘都要优秀。

在网上的网盘我们不需要关心磁盘的问题,可自己的磁盘那必然意味着磁盘的损坏可能带来问题,所以就需要对nextcloud的数据进行备份。

官方指引: https://docs.docker.com/storage/volumes/#restore-volume-from-backup

nextcloud上传的文件在哪里?

docker volume ls
docker volume inspect nextcloud_nextcloud
[
    {
        "CreatedAt": "2022-04-20T21:02:55+08:00",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "nextcloud",
            "com.docker.compose.version": "1.28.4",
            "com.docker.compose.volume": "nextcloud"
        },
        "Mountpoint": "/var/lib/docker/volumes/nextcloud_nextcloud/_data",
        "Name": "nextcloud",
        "Options": null,
        "Scope": "local"
    }
]

"/var/lib/docker/volumes/nextcloud/_data"就是数据的问题了,打开文件夹,找到里面的data文件夹,沿着用户名,你就会看到该用户的数据了。

备份nextcloud卷数据

复制粘贴涉及到权限问题,故建议使用命令行。DD命令虽然好用,但无法拷贝文件夹。

  • 同一局域网内:
  • 1.挂载需要备份的卷

假定卷的宿主地址是/var/lib/docker/volumes/nextcloud_nextcloud/_data,对应容器内的地址是/ncbackup。新建容器的名称是container_for_ncbackup,镜像是ubuntu。

命令如下:

docker run -v /var/lib/docker/volumes/nextcloud_nextcloud/_data:/ncbackup --name container_for_ncbackup ubuntu /bin/bash
docker run --rm --volumes-from container_for_ncbackup -v $(pwd):/backup ubuntu tar czvf /backup/backup.tar /ncbackup

然后会在当前运行目录下看到backup.tar的文件。

docker run -v /home/nextcloudtest:/ncbackup –name container_for_ncbackup ubuntu /bin/bash

【失败】迁徙及还原nextcloud数据

挂载需要还原的卷的地址。

假设你想要放的大容量盘符挂载在/srv/dev-disk-by-uuid-9999/nextcloud

docker run -v /srv/dev-disk-by-uuid-9999/nextcloud:/dbdata --name dbstore2 ubuntu /bin/bash

记得运行下述命令时,到backup.tar文件所在的目录下运行。

docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

问题

然后遇到:

Internal Server Error

The server encountered an internal error and was unable to complete your request.
Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.
More details can be found in the server log.

怀疑是权限问题,试着把数据卷挂回原来的路径,发现可以用,但在移除了“数据库的卷”之后,显示为安装而非直接使用,安装进去发现没有了原来上传的文件。说明单纯备份nextcloud数据不备份数据库不行。

  1. 在宿主试了chown -R www-data:www-data /home/nextcloudtest,问题依旧。

  2. 在容器的config.php中添加'allow_local_remote_servers' => true,,依然错误。

  3. 把容器内新建的config覆盖安装到解压的config中,可以成功安装。可能问题在于数据库没有备份还原的原因。

【失败】备份nextcloud卷数据库

docker run -v nextcloud_db:/ncbackup --name container_for_ncbackup_db ubuntu /bin/bash
docker run --rm --volumes-from container_for_ncbackup_db -v $(pwd):/backup ubuntu tar czvf /backup/backup_db.tar /ncbackup

【失败】还原数据库和nextcloud卷

【失败】还原nextcloud卷

docker run -v /home/nc/nextcloud:/dbdata --name dbstore2 ubuntu /bin/bash
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

【失败】还原nextcloud数据库卷

docker run -v /home/nc/db:/dbdata --name dbstore3 ubuntu /bin/bash
docker run --rm --volumes-from dbstore3 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

依然不行。

查了下资料。大概类似于重装系统,nextcloud的HASH值不一样导致。解决方法:

https://help.nextcloud.com/t/docker-compose-restore-from-backup-of-db-and-data-results-in-errors/89961

具体步骤:

  1. 查看config/config.php文件的版本号,确定nextcloud的版本。比如:

'version' => '23.0.4.1',

  1. 设置docker-compose.yml文件的版本号对应第一项的版本号。并拉取镜像。

  2. 删除容器和卷(在已备份的前提下)

  3. 在新宿主上新建一个全新的nextcloud(同源备份版本),并新建和源备份的nextcloud同样账号密码的管理账号。

  4. 复制新的config/config.php的下述文件,替换原备份文件中的这四项,把修改后的原备份config.php保存为config.tmp.php.

    'instanceid' => 'oc8gypxk9ajl', 
    'passwordsalt' => 'MRdyRu0614Tl2pBf/A4oXqr7OslGJw', 
    'secret' => 'yhFd2HS0Dot6Ibw3AKEX8r33S9/hA3HcVOl2MeY9wgeY8eO+',
    'dbpassword' => 'userpwd',
    
  5. 还原备份卷并覆盖。

  6. 用config.tmp.php覆盖config.php.

  7. 修改config.php的文件所有权及权限。

    # 进入nextcloud的config文件夹。
    chown www-data config.php
    

    然后改成0640权限,我只会用winscp改,😄。

  8. docker-compose up -d

虽然能登录,但原来上传的文件依然没有在列表中显示。

数据都在,也可以登录,在各应用中不显示相关文件。失败。

appdata_oc4bgnbtl072

appdata_oc6wz15xw9n3

appdata_oc8gypxk9ajl

备份:跟随nextcloud官方指引尝试(PLAN A)。

跟随:

https://docs.nextcloud.com/server/23/admin_manual/maintenance/backup.html

  1. 打开/关闭维护模式。(打开后进行备份)

docker exec -u www-data nextcloud_app_1 php occ maintenance:mode –on

docker exec -u www-data nextcloud_app_1 php occ maintenance:mode –off

  1. 备份文件夹。(如果用卷则指向卷的目录,如果挂载,则指向挂载的目录),以下假设容器内的/var/www/html挂载在/home/nc/nextcloud

    rsync -Aavx /home/nc/nextcloud/ nextcloud-dirbkp_`date +"%Y%m%d"`/
    
    root@OMV:/home/ncsh# ls
    nextcloud-dirbkp_20220501
    
    会看到备份的镜像内容。
    
    1. 备份数据库。

    https://github.com/docker-library/docs/blob/master/mariadb/README.md#creating-database-dumps

    docker exec some-mariadb sh -c ‘exec mysqldump –all-databases -uroot -p"$MARIADB_ROOT_PASSWORD"’ > /some/path/on/your/host/all-databases.sql

mysqldump –single-transaction -h [server] -u [username] -p[password] [db_name] > nextcloud-sqlbkp_date +"%Y%m%d".bak

假设数据库的容器名称是nextcloud_db_1

docker exec nextcloud_db_1 sh -c ‘exec mysqldump –single-transaction -h [server] -u [username] -p[password] [db_name] > nextcloud-sqlbkp_date +"%Y%m%d".bak

打开docker-compose.yml查看数据库内容如下:

  - MYSQL_ROOT_PASSWORD=rootpwd
  - MYSQL_PASSWORD=userpwd
  - MYSQL_DATABASE=nextcloud
  - MYSQL_USER=nextcloud

查询docker exec nextcloud_db_1 env,可以知道host``[server]的名称。

root@OMV:/# docker exec nextcloud_db_1  env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0b009457f52f
MYSQL_ROOT_PASSWORD=rootpwd
MYSQL_PASSWORD=userpwd
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
GOSU_VERSION=1.14
MARIADB_MAJOR=10.7
MARIADB_VERSION=1:10.7.3+maria~focal
HOME=/root

单数据库

docker exec nextcloud_db_1 sh -c 'exec mysqldump --single-transaction --databases 0b009457f52f -uroot -p"rootpwd"' > nextcloud-sqlbkp_`date +"%Y%m%d"`.bak

所有数据库备份。

docker exec nextcloud_db_1 sh -c 'exec mysqldump --single-transaction --all-databases -uroot -p"rootpwd"' > nextcloud-sqlbkp_`date +"%Y%m%d"`.bak

备份:压缩docker数据卷模式(planB)

发现官方说明,还原后需要 maintenance:data-fingerprint,所以再试试。

docker exec -u www-data nextcloud_app_1 php occ maintenance:data-fingerprint

tar备份文件夹:

docker run -v /home/nc/nextcloud:/ncbackup --name container_for_ncbackup ubuntu /bin/bash

docker run --rm --volumes-from container_for_ncbackup -v $(pwd):/backup ubuntu tar czvf /backup/backup.tar /ncbackup

tar备份数据卷

docker run -v /home/nc/db:/ncbackup --name container_for_ncbackup_db ubuntu /bin/bash

docker run --rm --volumes-from container_for_ncbackup_db -v $(pwd):/backup ubuntu tar czvf /backup/backup_db.tar /ncbackup

还原:万事俱备最终成功解决方案(PLAN A)

docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --off

创建nextcloud,在建立管理账号前,发现db数据库已经有nextcloud的数据库。毕竟已经自动建库了。

  1. 官方指引表示要删掉所有数据并新建数据库。
mysql -h [server] -u [username] -p[password] -e "DROP DATABASE nextcloud"
mysql -h [server] -u [username] -p[password] -e "CREATE DATABASE nextcloud"
  • 查看新生成的容器[server]的名称。
    docker exec nextcloud_db_1 env
    假设HOSTNAME=dbhost,但实际docker的[server]是以CONTAINER ID为准。只是在没有设置hostname的环境变量时候两者一致。
  • 进入容器内输入:
#查询数据库基础信息
docker exec nextcloud_db_1  env

docker exec -it nextcloud_db_1 bash

mysql -h 0b009457f52f -u nextcloud -puserpwd -e "DROP DATABASE nextcloud"
#上述命令会删除nextcloud的数据库。
mysql -h 0b009457f52f -u nextcloud -puserpwd -e "CREATE DATABASE nextcloud"
#新建数据库。
exit
  • 或者宿主环境执行:
docker exec nextcloud_db_1 sh -c 'exec mysql -h 0b009457f52f -u nextcloud -puserpwd -e "DROP DATABASE nextcloud"'
docker exec nextcloud_db_1 sh -c 'exec mysql -h 0b009457f52f -u nextcloud -puserpwd -e "CREATE DATABASE nextcloud"'
  1. 还原数据库(planA)。

    mysql -h [server] -u [username] -p[password] [db_name] < nextcloud-sqlbkp.bak
    
docker exec -i nextcloud_db_1 sh -c 'exec mysql -h 0b009457f52f -uroot -p"rootpwd" nextcloud' < /home/ncsh/nextcloud-sqlbkp_20220501.bak
  1. 还原文件夹。
rsync -Aax nextcloud-dirbkp/ nextcloud/

假设备份文件在/home/ncsh/nextcloud-dirbkp_20220501/,容器卷的文件夹在/home/nc1/nextcloud/,输入以下命令:

rsync -Aax /home/ncsh/nextcloud-dirbkp_20220501/ /home/nc1/nextcloud/
  1. 指纹校验。
docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --off

docker exec -u www-data nextcloud_app_1 php occ maintenance:data-fingerprint
  1. 登录,成功撒花。

把踩坑记录下来,方便大家DEBUG。对于私有云最重要的应该还是在私密性的情况下考虑数据的安全性。可以看出还原成功的关键是数据库的清空后覆盖以及指纹校验。

还原:PLAN B(也成功)

由于B计划是压缩包,跨数据盘转移权限可能更不容易出错(非专业想法)。所以继续测试下B计划。

  1. 新建后,先按PLANA的”1“删掉数据库。

  2. 还原数据库(PLANB)

  • 挂载宿主的/home/nc/db到容器dbstore3,挂载容器内目录为dbdata
docker run -v /home/nc/db:/dbdata --name dbstore3 ubuntu /bin/bash
  • 还原压缩的数据卷

    假设现在登录在压缩包所在目录下,且压缩包名称为backup_db.tar

设置卷为dbstore3为当前宿主路径中backup路径,解压缩当前宿主路径下的backup_db.tar。

docker run --rm --volumes-from dbstore3 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup_db.tar --strip 1"
  1. 还原文件夹。
docker run -v /home/nc/nextcloud:/dbdata --name dbstore2 ubuntu /bin/bash

docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
  1. docker exec -u www-data nextcloud_app_1 php occ maintenance:data-fingerprint
  2. 提示大量错误。。。
  3. 尝试解决成功方法如下:
  • 删除nextcloud文件夹(在docker运行的情况下)rm -rf
  • 关闭并删除容器。docker-compose down
  • 执行步骤三还原文件夹。
  • docker-compose up -d
  • docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --off
  • docker exec -u www-data nextcloud_app_1 php occ maintenance:data-fingerprint
  • 登录,成功撒花(数据,用户、主题均在)。

修改用户的用量配额。

管理员进入选择右上角下拉的“用户”打开,然后左下角“设置”,选择配额,填写容量。
然后就可以编辑各用户的配额了。

安装外部存储??

如果你按照我的docker-compose.yml搭建,或者官方的,那么nextcloud的系统内部空间就是系统盘的空间大小。
如果是OMV的系统,则系统盘建议大小是16-32G,这更是捉襟见肘。
nextcloud是直接安装在docker的文件夹下的。如果docker本身卷在系统盘下,而系统盘往往不是很大,则需要扩容。毕竟百度云盘都1TB了,自己安装了云盘结果只有系统盘大小那不是贻笑大方嘛。

  • 外部存储实际是指不在本宿主安装地址的物理磁盘以外的地址。

是否可以将nextcloud安装到其他盘符,用于扩容?

  • 答案:如果在不改变docker的安装路径在主系统盘的情况下,也是可以的。具体结合备份迁徙的内容可以知晓答案。
    只要把容器内的/var/www/html指向其他磁盘的路径就可以。(磁盘挂载在系统的路径)。
    然后在nextcloud中,容量就是新磁盘的容量。

安装外部存储。

管理员右上角点击“应用”,搜索“External storage support”,安装即可。

挂载本地磁盘,需要先在docker中挂载目录,然后在外部存储中设置“本地”,挂载容器内的目录地址即可。

如果是在一个系统非网线直连的磁盘都是“本地”。只要在volume中挂载宿主磁盘路径就可以作为’本地’使用。

最后更新:2022/05/02。