搭建 Nextcloud个人云盘

搭建Nextcloud个人云盘

前置条件 Docker/Nginx/MySQL/Redis/PHP

1. 创建docker桥接网络划分网络范围

172.0.0.0/24的 IP范围: 172.0.0.1 ~ 172.0.0.255

docker network create --driver bridge \
        --subnet=172.0.0.0/24 \
        --gateway=172.0.0.1 nextcloud-net

如果报错: Error response from daemon: Pool overlaps with other one on this address space
请更换 172.0.0.0/24和172.0.0.1 为其他IP地址

2. 创建MySQL容器

  1. 创建数据目录

    mkdir -p /data/nextcloud/mysql/data/
  2. 运行容器

    docker run --network nextcloud-net --ip 172.0.0.2 \
        -v /data/nextcloud/mysql/data/:/var/lib/mysql \
        -e MYSQL_ROOT_PASSWORD='123456' \
        -e MYSQL_DATABASE='nextcloud' \
        --restart=always \
        --name nextcloud-mysql \
        -d mysql:5.7

3. 创建Redis容器

  1. 创建Redis配置/数据目录

    mkdir -p /data/nextcloud/redis/config
    mkdir -p /data/nextcloud/redis/data
  2. 创建Redis配置文件redis.conf移动到配置目录下

    daemonize no
    pidfile /data/redis.pid
    port 6379
    timeout 300
    loglevel notice
    logfile stdout
    databases 16
    save 60 10
    rdbcompression yes
    dbfilename dump.rdb
    dir /data/
    # 密码
    requirepass 123456
    maxclients 128
    appendonly no
    appendfilename appendonly.aof
    appendfsync everysec
    mv redis.conf /data/nextcloud/redis/config
  3. 运行容器

    docker run --network nextcloud-net --ip 172.0.0.3 \
        -v /data/nextcloud/redis/data/:/data/ \
        -v /data/nextcloud/redis/config/:/config/ \
        --restart=always \
        --name nextcloud-redis \
        -d redis:alpine redis-server /config/redis.conf --appendonly yes

4. 创建NextCloud

  1. 创建NextCloud配置/数据目录

    mkdir -p /data/nextcloud/app/
  2. 运行容器

    docker run --network nextcloud-net --ip 172.0.0.4 \
        -v /data/nextcloud/app/:/var/www/html \
        -e MYSQL_HOST=nextcloud-mysql \
        -e MYSQL_DATABASE=nextcloud \
        -e MYSQL_USER=root \
        -e MYSQL_PASSWORD=123456 \
        -e REDIS_HOST=nextcloud-redis \
        -e REDIS_HOST_PORT=6379 \
        -e REDIS_HOST_PASSWORD=123456 \
        -e NEXTCLOUD_TRUSTED_DOMAINS='172.0.0.5' \
        --restart=always \
        --name nextcloud-app \
        -d nextcloud:20-fpm-alpine

5. 创建Nginx容器

  1. 创建Nginx配置/数据目录

    mkdir -p /data/nextcloud/nginx/config
  2. 创建Nginx配置文件nextcloud.conf移动至/data/nextcloud/nginx/config/

    upstream php-handler {
        server nextcloud-app:9000;
    }
    
    server {
        listen 80;
        server_name localhost 172.0.0.5;
        add_header Referrer-Policy "no-referrer" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Download-Options "noopen" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        add_header X-Robots-Tag "none" always;
        add_header X-XSS-Protection "1; mode=block" always;
    
        fastcgi_hide_header X-Powered-By;
    
        root /var/www/html;
    
        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;
    
        # The following rule is only needed for the Social app.
        # Uncomment it if you're planning to use this app.
        #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
    
        location = /.well-known/carddav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
    
        location = /.well-known/caldav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
    
        # set max upload size
        client_max_body_size 10G;
        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;
        }
    
        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\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
            fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
            set $path_info $fastcgi_path_info;
            try_files $fastcgi_script_name =404;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $path_info;
            # fastcgi_param HTTPS on;
    
            # Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
    
            # Enable pretty urls
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;
    
        }
    
        location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
            try_files $uri/ =404;
            index index.php;
        }
    
        # Adding the cache control header for js, css and map files
        # Make sure it is BELOW the PHP block
        location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
            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;" always;
            #
            # 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 Referrer-Policy "no-referrer" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-Download-Options "noopen" always;
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Permitted-Cross-Domain-Policies "none" always;
            add_header X-Robots-Tag "none" always;
            add_header X-XSS-Protection "1; mode=block" always;
    
            # Optional: Don't log access to assets
            access_log off;
        }
    
        location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
            try_files $uri /index.php$request_uri;
            # Optional: Don't log access to other assets
            access_log off;
        }
    }
  3. 运行容器

    docker run --network nextcloud-net --ip 172.0.0.5 \
        -v /data/nextcloud/nginx/config/:/etc/nginx/conf.d/ \
        -v /data/nextcloud/app/:/var/www/html \
        --restart=always \
        --name nextcloud-nginx \
        -d nginx:alpine

6 访问安装

访问172.0.0.5填写用户名密码 点击安装

7 安装插件

遇到app访问空白或者启用插件失败请求的情况
访问 https://apps.nextcloud.com/ 搜索插件 按照版本下载插件
将压缩包解压到nextcloud-app安装目录的apps目录下

8 性能优化

  1. 定时任务优化 cron替代后台ajax刷新执行定时任务
    进入nextcloud-app容器命令行执行以下命令:
    echo '*/5 * * * * www-data php /var/www/html/cron.php' >> /etc/crontab
  2. 文件锁优化 使用redis锁代替文件锁。
    编辑nextcloud的配置文件
    'filelocking.enabled' => true,
    'memcache.locking' => '\OC\Memcache\Redis',
  3. 数据库优化 进入nextcloud-mysql容器命令行 编辑 /etc/mysql/conf.d/mysql.cnf文件 加入以下行:
    [mysqld]
    innodb_buffer_pool_size=256m
    innodb_io_capacity=4000
  4. 配置php-fpm。编辑/etc/php/7.3/fpm/pool.d/www.conf文件,设置动态进程数量
    pm.max_children = 50
    pm.start_servers = 3
    pm.min_spare_servers = 3
    pm.max_spare_servers = 10
  5. 启用opcache。安装opcache模块,在/etc/php/7.3/fpm/php.ini编辑opcache设置:
    opcache.enable=1
    opcache.interned_strings_buffer=8
    opcache.max_accelerated_files=10000
    opcache.memory_consumption=128
    opcache.save_comments=1
    opcache.revalidate_freq=30
  6. 启用大文件上传。编辑/etc/php/7.3/fpm/php.ini,更改文件限制
    upload_max_filesize=16G
    post_max_size=16G
    max_input_time = 3600
    max_execute_time = 3600
    memory_limit = 512M
    接着编辑/etc/nginx/nginx.conf,在http块中修改上传限制:
    client_max_body_size 16G;
    fastcgi_read_timeout 360S;

资料参考