Loading...
Navigation
Table of Contents

Nextcloud搭建Tech

Tips

客户端

如果文件管理器中没有出现角标,在管理员PoewerShell中执行如下命令。

regsvr32 "C:\Program Files (x86)\Nextcloud\shellext\OCOverlays_x64.dll"

apache参考资料


一般部署

参考资料

环境是Ubuntu 18.04,步骤大致如下

零、在windows server 2019上开启wsl

下载ubuntu 18 wsl版本

https://aka.ms/wsl-ubuntu-1604

其余的看微软官方教程即可。

一、安装和配置LAMP Stack

安装LAMP Stack (linux、apache、mysql和php),其中要注意不要漏掉php7.2-fpm,此外如果要支持sqlite3,需要安装对应的php7.2-sqlite3

sudo apt update
sudo apt upgrade
sudo apt install apache2 mariadb-server libapache2-mod-php7.2
# 可能不同网站写的不一样,反正通通安装一遍
sudo apt install php7.2-gd php7.2-json php7.2-mysql php7.2-curl php7.2-mbstring
sudo apt install php7.2-intl php-imagick php7.2-xml php7.2-zip
sudo apt install php7.2 php7.2-fpm php7.2-mysql php-common php7.2-cli php7.2-common php7.2-json php7.2-opcache php7.2-readline php7.2-mbstring php7.2-xml php7.2-gd php7.2-curl

# 配置mysql
sudo service mysql start
sudo mysql_secure_installation  # 设置下root密码之类的
# 具体参考https://www.linuxbabe.com/ubuntu/install-lemp-stack-nginx-mariadb-php7-2-ubuntu-18-04-lts
sudo mariadb -u root
exit;
mariadb --version

# 启动apache和php
sudo service apache2 restart
sudo service php7.2-fpm start
php --version

手动给nextcloud配置mysql账户/密码(可选):

  • nextcloud需要一个database和user来存取数据,可以手动配置用户,之后在进入网页的设置向导(Installation wizard)里填写进去即可。
  • 也可以这里不手动配置。因为新版的nextcloud支持了自动配置database和user,在设置向导里填写root账户和密码,nextcloud会自动做这些事情(建一个以oc_开头的专用账户),并把账户/密码写入/var/www/nextcloud/config/config.php里,参考Database choice
sudo mariadb
create database nextcloud;  # 删除用create database xxx
# 注意把your-password改一下
create user nextclouduser@localhost identified by 'your-password';
grant all privileges on nextcloud.* to nextclouduser@localhost identified by 'your-password';
flush privileges;
exit;

二、安装nextcloud

官网以及各大网站教程都是将nextcloud放在/var/www或者/usr/share/nginx/中,其实可以放在任意目录,只需要在nginx的配置文件中指定root的值为该目录即可. 但注意

  • 一般将nextcloud和nextcloud数据放在不同的目录,这是为了安全和便于迁移(系统默认nextcloud数据是放在/path/to/nextcloud/data路径中的),注意之后nextcloud搭建好后进入设置向导时填写正确的nextcloud数据目录;
  • 需要将nextcloud的归属权赋予www-data用户,因为这是PHP运行所属的用户;此外为了能让其他用户可以读取,可以修改权限等级为755。
wget https://download.nextcloud.com/server/releases/nextcloud-***.zip
sudo apt install unzip
unzip nextcloud-***.zip -d /var/www/ # 解压nextcloud目录到/var/www
sudo chown www-data:www-data /var/www/nextcloud -R
mkdir /var/www/nextcloud-data
sudo chown www-data:www-data /var/www/nextcloud-data -R
sudo chmod -R 755 /var/www/nextcloud-data

三、配置apache

/etc/apache2/sites-available/nextcloud.conf目录中增加nextcloud配置文件,注意注释要单独一行,否则会报错。

<VirtualHost *:80>
  # 默认监听80端口,如果需要加其他端口,记得ports.conf里面添加一个listen
  #ServerName www.example.com  # 监听域名

  # 不用管
  ServerAdmin webmaster@localhost
  # 文件根目录
  DocumentRoot /var/www/nextcloud

  # 也可以通过Alias设置二级目录,访问/nextcloud时指向"/var/www/nextcloud/"
  # Alias /nextcloud "/var/www/nextcloud/"

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  # 用Directory来设置apache对目录的各种权限
  # 参考https://blog.csdn.net/dxcyber409/article/details/80942389
  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews
    <IfModule mod_dav.c>
      Dav off
    </IfModule>

    # 这一行是nextcloud官网推荐加的
    Satisfy Any  
  </Directory>

</VirtualHost>

有关apache conf,还可以参考这里

sudo a2dissite 000-default.conf
# 禁用默认conf,等价于rm /etc/apache2/sites-enabled/000-default.conf

sudo a2ensite nextcloud.conf
# 启用nextcloud.conf,等价于ln -s /etc/apache2/sites-available/nextcloud.conf /etc/apache2/sites-enabled/nextcloud.conf

sudo apache2ctl configtest # 测试配置是否正确

# 增加一些其他配置,参考https://docs.nextcloud.com/server/18/admin_manual/installation/source_installation.html#additional-apache-configurations
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod env
sudo a2enmod dir
sudo a2enmod mime

sudo service apache2 restart

四、设置向导(Installation wizard)

打开http://localhost进入nextcloud的设置向导,其中

  • 在wsl系统中http://localhost打不开的话,用http://127.0.0.1试试
  • 如果上面apache配置中用了Alias,那么打开http://localhost/nextcloud

数据库的用户密码,根据刚才配置mysql的情况填写,数据库端口,貌似新版nextcloud直接填localhost就可以了。(进入网页中的设置向导时,可以试试localhost:3306或者db,参见这里)

五、优化

不被信任的域名访问

简单粗暴的方式如下,或者参考这里

# sudo vim /var/www/nextcloud/config/config.php
<?php
$CONFIG = array (
  'trusted_domains' =>
  array (
    0 => '*.*.*.*',
  ),
);

php.ini和php-fpm配置

  • 根据官网要求,修改配置文件/etc/php/7.0/fpm/pool.d/www.conf,uncomment以下变量
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
  • 根据官网要求,为了增加php进程数,修改/etc/php/7.0/fpm/pool.d/www.conf如下配置
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
  • 为了实现大文件上传,修改/etc/php/7.0/fpm/php.ini如下变量,其中upload_max_filesize必须小于post_max_size值。
max_execution_time = 120
max_input_time = 80
memory_limit = 128m
file_uploads = on
upload_max_filesize = 2000m
post_max_size = 2001m

(max_execution_time太大也不好,nextcloud更新时候会卡住)

  • 根据官网说明,通过预编译的OPcache提高速度,修改/etc/php/7.0/fpm/php.ini如下变量
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1

然后运行sudo service php7.0-fpm restart重启php-fpm。

六、其他

all in one配置

<VirtualHost *:443>
  # 默认监听80端口,如果需要加其他端口,记得ports.conf里面添加一个listen
  ServerName test.example.com

  ServerAdmin webmaster@localhost
  # 不用管

  ProxyRequests Off
  ProxyPreserveHost On
  # 也可以通过Alias设置二级目录,访问/nextcloud时指向"/var/www/nextcloud/"
  
  # 不管用 https://community.bitnami.com/t/bad-request-error-when-enabling-ssl-and-http-redirection/62821
  #RewriteEngine On
  #RewriteCond %{HTTPS} off
  #RewriteCond %{HTTP_HOST} !^(localhost|127.0.0.1|test.example.com)
  #RewriteRule ^/(.*) htts://www.google.com [R,L]

  #<LocationMatch "^/$">
    # 返回 403 You don't have permission to access this resource.
  #  Order allow,deny
  #  Deny from all

  # https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirect
  #Redirect "http://localhost:2131"
  #</LocationMatch>

  # 不返回,不管用
  # https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxyremote 
  #ProxyPassMatch "^/$" "https://www.google.com"

  DocumentRoot /var/www/nextcloud
  #Alias "/file" "/var/www/nextcloud/"

  # https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html
  # https://httpd.apache.org/docs/2.4/howto/access.html
  #<Location "/">
  #    Require host test.example.com:123
  #</Location>
  
  # https://httpd.apache.org/docs/2.4/expr.html
  # 注意HTTP_HOST得加端口号
  <If "%{HTTP_HOST} != ' test.example.com:123' || %{HTTPS} != 'on'">
    Deny from all
    # Redirect "https://www.google.com"
  </If>

  # https://github.com/jellyfin/jellyfin-docs/blob/master/general/networking/index.md#base-url
  ProxyPass "/socket" "ws://127.0.0.1:888/socket"
  ProxyPassReverse "/socket" "ws://127.0.0.1:888/socket"
  
  ProxyPass "/embywebsocket" "ws://127.0.0.1:888/embywebsocket"
  ProxyPassReverse "/embywebsocket" "ws://127.0.0.1:888/embywebsocket"

  ProxyPass "/transmission" "http://127.0.0.1:9091/transmission"
  ProxyPassReverse "/transmission" "http://127.0.0.1:9091/transmission"
  
  ProxyPass "/video" "http://127.0.0.1:888/video"
  ProxyPassReverse "/video" "http://127.0.0.1:888/video"

  # 关闭,否则提示重定向的次数过多
  # Redirect permanent "/transmission/" "/transmission/web/"

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  # 用Directory来设置apache对目录的各种权限
  # 参考https://blog.csdn.net/dxcyber409/article/details/80942389
  <Directory /path/to/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews
    <IfModule mod_dav.c>
      Dav off
    </IfModule>

    Satisfy Any
    # 这一行是nextcloud官网推荐加的
  </Directory>

#  <Location "^/$">
#    Order allow,deny
#    Deny from all
#  </Location>

  # 腾讯云证书部署 https://cloud.tencent.com/document/product/400/35243
  SSLEngine on
  SSLCertificateFile /path/to/2_test.example.com.crt
  SSLCertificateKeyFile /path/to/3_test.example.com.key
  SSLCertificateChainFile /path/to/1_test.example.com.crt
  Protocols h2 http/1.1

</VirtualHost>

用nginx而不是apache (已废弃)

带有https的nginx配置如下,这里有如下几点需要注意:

  • 9000是tcp协议,sock是socket协议,查看/etc/php/7.0/fpm/php.ini来判断php开启了什么端口
  • client_max_body_size决定了上传文件的最大大小,还需要搭配PHP一起配置,才能上传大文件;上传大文件时,还可能出现超时的情况,其他nginx设置参考这里
upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/var/run/php/php7.0-fpm.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name abc.example.com;
    # enforce https
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name abc.example.com;

    # Use Mozilla's guidelines for SSL/TLS settings
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/
    # NOTE: some settings below might be redundant
    ssl_certificate /path/to/full_chain.pem;
    ssl_certificate_key /path/to/private.key;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    # add_header Strict-Transport-Security "max-age=15768000;
    # includeSubDomains; preload;";
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Path to the root of your installation
    root /path/to/nextcloud/;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
    # last;

    location = /.well-known/carddav {
      return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;
    }

    # set max upload size
    client_max_body_size 1024M;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;

    location / {
        rewrite ^ /index.php$request_uri;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }

    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        #Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri/ =404;
        index index.php;
    }

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~ \.(?:css|js|woff2?|svg|gif)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";
        # Add headers to serve security related headers (It is intended to
        # have those duplicated to the ones above)
        # Before enabling Strict-Transport-Security headers please read into
        # this topic first.
        # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        add_header Referrer-Policy no-referrer;

        # Optional: Don't log access to assets
        access_log off;
    }

    location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
        try_files $uri /index.php$request_uri;
        # Optional: Don't log access to other assets
        access_log off;
    }
}


Docker部署 | 不推荐

docker-apache是指用apache反向代理,docker-fpm是指用nginx做反向代理。之所以不用docker,是因为不清楚docker的nginx和系统的nginx是否都能监听80和443端口。

此外这里的user: 1001:1001是自行添加的字段,是为了让docker使用自己的账户而不是www-data账户,不过这样在部署docker-apache版本的时候好像是有问题的,apache会报错。

docker-apache

version: '2'

services:
  db:
    image: mariadb
    user: 1001:1001
    restart: always
    volumes:
      - /home/USERNAME/nextcloud/mysql:/var/lib/mysql
      - /home/USERNAME/nextcloud/etc:/etc
    environment:
      - MYSQL_ROOT_PASSWORD=nextcloud
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
  app:
    image: nextcloud
    user: 1001:1001
    ports:
      - 8080:80
    links:
      - db
    volumes:
      - /home/USERNAME/nextcloud/html:/var/www/html
    restart: always

docker-fpm

version: '2'
volumes:
  nextcloud:
  db:
services:
  db:
    image: mariadb
    user: 1001:1001
    restart: always
    volumes:
      - /home/USERNAME/nextcloud/mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=nextcloud
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
  app:
    image: nextcloud:fpm
    user: 1001:1001
    links:
      - db
    volumes:
      - /home/USERNAME/nextcloud/html:/var/www/html
    restart: always
  web:
    image: nginx
    ports:
      - 80:80
      - 443:443
    links:
      - app
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./full_chain.pem:/etc/nginx/full_chain.pem:ro
      - ./private.key:/etc/nginx/private.key:ro
    volumes_from:
      - app
    restart: always

Office扩展

Only Office扩展和Collabora Online扩展都需要额外的server来配合,配置比较复杂且容易出错,因此只能选择docker配置的方法。Only Office需要的是OnlyOffice Document Server,Collabora Online需要的是Collabora Online Server。相对于Collabora Online,Only Office界面美观,网页滑动更加流畅。

配置Office扩展需要两个子域名,即nextcloud的域名和office的二级域名不同,如a.example.comb.example.com。至于怎么用子目录,尚不明确。

Only Office

简书教程OnlyOffice官方中Running Document Server using HTTPS这一小节所述,先将证书文件放置好,使用docker运行https版本的onlyoffice

mkdir -p /home/USER/onlyoffice/data/certs
mkdir -p /home/USER/onlyoffice/log

然后把证书的pem文件和key个文件重命名为onlyoffice.crtonlyoffice.key,放置在certs目录下,注意名字一定要对的上,否则docker内部的程序识别不出来. 然后运行onlyoffice

docker pull onlyoffice/documentserver
docker run -i -t -d -p 9443:443 \
    -v /home/USER/onlyoffice/logs:/var/log/onlyoffice \
    -v /home/USER/onlyoffice/data:/var/www/onlyoffice/Data \
    --name onlyoffice onlyoffice/documentserver

这个时候,访问https://127.0.0.1:9443应该可以看得到页面,没有的话可以docker restart ID一下。

在外围的nginx(不是docker里面的nginx)做一下https转发,这个证书和刚才传给的docker证书是相同的。

server {
    listen       443 ssl;
    server_name  a.example.com;

    ssl on;
    ssl_certificate /path/to/onlyoffice.crt;
    ssl_certificate_key /path/to/onlyoffice.key;
    ssl_session_timeout 1d;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;        
    ssl_prefer_server_ciphers on;

    location / {
       proxy_redirect off;
        proxy_pass https://localhost:9443;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

此时应该可以通过https://a.example.com访问了,然后去nextcloud设置界面填写相关配置。

Collabora Online

参考简书官网,注意domain里面填写的是nextcloud的地址,并且.之前要加双斜杠。

docker pull collabora/code
docker run -t -d -p 127.0.0.1:9980:9980 \
    -e 'domain=nextcloud\\.example\\.com' \
    -e "username=admin" -e "password=123456" \
    --restart always --cap-add MKNOD collabora/code

这时候访问IP,登录刚才的用户和密码,应该可以进入后台页面。

https://127.0.0.1:9980/loleaflet/dist/admin/admin.html

然后在外围的nginx里面增加如下配置,即可使用域名访问

server {
    listen       443 ssl;
    server_name  a.example.com;

    ssl_certificate /path/to/collabora.crt;
    ssl_certificate_key /path/to/collabora.key;

    # static files
    location ^~ /loleaflet {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # WOPI discovery URL
    location ^~ /hosting/discovery {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # main websocket
    location ~ ^/lool/(.*)/ws$ {
        proxy_pass https://localhost:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }

    # download, presentation and image upload
    location ~ ^/lool {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # Admin Console websocket
    location ^~ /lool/adminws {
        proxy_pass https://localhost:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }
}

然后去nextcloud设置界面填写相关配置。

Last updated on Mar 12, 2020.