最近有很多小伙伴問(wèn)壹哥,大規(guī)模的文件存儲(chǔ)該怎么做? 這個(gè)感覺(jué)很難實(shí)現(xiàn)呢。其實(shí)這個(gè)需求,并沒(méi)有大家想的那么難以實(shí)現(xiàn)。今天壹哥就帶著各位,用10分鐘的時(shí)間來(lái)搞定這個(gè)需求。不信?那你就跟著壹哥一步步來(lái),10分鐘絕對(duì)帶你學(xué)會(huì)。
FastDFS是一個(gè)開(kāi)源的輕量級(jí)分布式文件系統(tǒng),它特別適合海量的文件存儲(chǔ),具有文件上傳、下載、文件同步和刪除等功能。還可以存儲(chǔ)各種類型文件,例如文本文件、聲音文件、視頻文件、圖片文件等,可以用來(lái)做相冊(cè)網(wǎng)站,還可以在電商網(wǎng)站中保存商品圖片,在貼吧網(wǎng)站保存文章中的插圖等。
FastDFS 特點(diǎn):
支持高并發(fā)存儲(chǔ),對(duì)高并發(fā)文件存儲(chǔ)有負(fù)載均衡的功能; 同時(shí)支持存儲(chǔ)容量的水平擴(kuò)展,可以無(wú)限擴(kuò)展增大存儲(chǔ)容量; 支持容災(zāi)功能,因?yàn)閮?nèi)部有冗余備份功能,防止文件丟失; 高可用,管理端和存儲(chǔ)端都有心跳檢測(cè)功能。
不要驚訝 , 它就是這么強(qiáng)大 ?。。?/strong>
接下來(lái)壹哥就給大家解讀FastDFS流程圖中展示的執(zhí)行流程和原理 :
FastDFS分為客戶端client(我們的項(xiàng)目),tracker管理端(管理存儲(chǔ)端服務(wù)器的,不存儲(chǔ)文件),storage存儲(chǔ)端(存儲(chǔ)文件) 共三部分。 首先管理端tracker不存儲(chǔ)具體的文件,它用來(lái)管理storage存儲(chǔ)端集群服務(wù)器。tracker可以是一主多從,備機(jī)每隔一段時(shí)間ping主機(jī),主機(jī)返回pong命令,具有心跳檢測(cè)機(jī)制。如果主機(jī)宕機(jī),不返回pong命令,那么備機(jī)會(huì)替代主機(jī)工作。請(qǐng)求進(jìn)入靠tracker管理端分配,具體將文件存儲(chǔ)到哪一個(gè)storage存儲(chǔ)端服務(wù)器,具有負(fù)載均衡功能。 storage存儲(chǔ)端服務(wù)器,是兩臺(tái)為一組,一臺(tái)主機(jī)和一臺(tái)備機(jī)。存儲(chǔ)時(shí)向主機(jī)從存儲(chǔ),然后主機(jī)將文件同步到備機(jī)保存一份,冗余存儲(chǔ)防止文件丟失。主機(jī)和備機(jī)之間也有心跳檢測(cè)機(jī)制,防止主機(jī)宕機(jī),高可用。存儲(chǔ)端服務(wù)器可以水平無(wú)限擴(kuò)展,這樣理論上fastDFS分布式文件系統(tǒng)可以存儲(chǔ)的文件大小是無(wú)限大。 客戶端如果想要存儲(chǔ),發(fā)送請(qǐng)求到tracker管理端,管理端會(huì)返回給客戶端一個(gè)存儲(chǔ)端服務(wù)器的ip和端口,然后客戶端向具體的存儲(chǔ)端服務(wù)器中存儲(chǔ),存儲(chǔ)后返回一個(gè)存儲(chǔ)后的路徑,并且文件會(huì)被自動(dòng)重命名,防止文件重名。
壹哥在這里使用Docker容器化來(lái)搭建FastDFS。
docker pull morunchang/fastdfs
復(fù)制代碼
創(chuàng)建FastDFS管理端tracker容器。
docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh
復(fù)制代碼
創(chuàng)建FastDFS存儲(chǔ)端storage容器。
# 命令語(yǔ)法
docker run -d --name storage --net=host -e TRACKER_IP=<your tracker server address>:22122 -e GROUP_NAME=<group name> morunchang/fastdfs sh storage.sh
# 創(chuàng)建storage容器例子:
docker run -d --name storage --net=host -e TRACKER_IP=192.168.200.128:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh
復(fù)制代碼
使用的網(wǎng)絡(luò)模式是–net=host; 其中 位置替換為你機(jī)器的ip地址即可; 其中 是組名,即storage的組,例如: group1、group2、group3等; 如果想要增加新的storage服務(wù)器,再次運(yùn)行該命令,注意更換新組名即可。
進(jìn)入storage的容器內(nèi)部,修改nginx.conf。
# 進(jìn)入到storage容器內(nèi)部 docker exec -it storage /bin/bash
復(fù)制代碼
進(jìn)入到容器內(nèi)部后。
#1. 通過(guò)命令來(lái)查詢Nginx的安裝位置:
root@iZ8vb6w2xyjemtqcxtmaj4Z:/# whereis nginx
#顯示如下:
nginx: /etc/nginx
#2. 查看當(dāng)前Nginx的進(jìn)程
root@iZ8vb6w2xyjemtqcxtmaj4Z:/# ps aux | grep nginx
#顯示如下:
root 16 0.0 0.0 32480 1480 ? Ss 13:18 0:00 nginx: master process /etc/nginx/sbin/nginx
nobody 100 0.0 0.0 33036 2116 ? S 14:15 0:00 nginx: worker process
root 118 0.0 0.0 11272 728 pts/1 S+ 14:54 0:00 grep --color=auto nginx
復(fù)制代碼
在storage存儲(chǔ)端容器的nginx中添加以下內(nèi)容:
#3. 修改Nginx的配置文件
vi /etc/nginx/conf/nginx.conf
#4. 修改Nginx配置內(nèi)容
server {
listen 80;
server_name localhost;
location ~ /M00 {
# storage 實(shí)際存儲(chǔ)圖片的位置
root /data/fast_data/data;
ngx_fastdfs_module;
}
}
#5. 進(jìn)入到Nginx sbin目錄從新加載Nginx配置文件
cd /etc/nginx/sbin
#6. 重新加載配置文件, 讓nginx配置生效
./nginx -s reload
復(fù)制代碼
修改后:
storage存儲(chǔ)的位置/data/fast_data/data。
docker update --restart=always tracker docker update --restart=always storage
復(fù)制代碼
創(chuàng)建文件管理微服務(wù)fastdfsDemo,該工程主要用于實(shí)現(xiàn)文件上傳以及文件刪除等功能。創(chuàng)建微服務(wù)時(shí),項(xiàng)目為Maven項(xiàng)目,不要選擇骨架。
<!-- 繼承Spring boot工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<properties>
<!-- 項(xiàng)目源碼及編譯輸出的編碼 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 項(xiàng)目編譯JDK版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 依賴包版本管理 -->
<spring.boot.version>2.1.5.RELEASE</spring.boot.version>
<fastdfs.client.version>1.27.0.0</fastdfs.client.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>${fastdfs.client.version}</version>
</dependency>
</dependencies>
復(fù)制代碼
在resources文件夾下創(chuàng)建fasfDFS的配置文件fdfs_client.conf。
connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 80
tracker_server = 192.168.200.128:22122
復(fù)制代碼
connect_timeout:連接超時(shí)時(shí)間,單位為秒; network_timeout:通信超時(shí)時(shí)間,單位為秒。發(fā)送或接收數(shù)據(jù)時(shí)。假設(shè)在超時(shí)時(shí)間后還不能發(fā)送或接收數(shù)據(jù),則本次網(wǎng)絡(luò)通信失?。?charset: 字符集; http.tracker_http_port :.tracker的http端口; tracker_server:tracker服務(wù)器IP和端口設(shè)置。
在resources文件夾下創(chuàng)建application.yml。
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
application:
name: fastdfs-demo
server:
port: 9001
復(fù)制代碼
max-file-size是單個(gè)文件大小,max-request-size是設(shè)置總上傳的數(shù)據(jù)大小。
創(chuàng)建啟動(dòng)類
創(chuàng)建com.qianfeng包,創(chuàng)建啟動(dòng)類FastDFSApplication。
package com.qianfeng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 項(xiàng)目啟動(dòng)類
* @Author 千鋒壹哥
*/
@SpringBootApplication
public class FastDFSApplication {
public static void main(String[] args) {
SpringApplication.run(FastDFSApplication.class, args);
}
}
復(fù)制代碼
文件上傳一般都有文件的名字、文件的內(nèi)容、文件的擴(kuò)展名、文件的md5值、文件的作者等相關(guān)屬性,我們可以創(chuàng)建一個(gè)對(duì)象封裝這些屬性。我們先創(chuàng)建com.qianfeng.pojo.FastDFSFile文件,代碼如下:
package com.qianfeng.pojo;
/**
* 自定義封裝, 文件實(shí)體類
* @Author 千鋒壹哥
*/
public class FastDFSFile {
//文件名字
private String name;
//文件內(nèi)容
private byte[] content;
//文件擴(kuò)展名
private String ext;
//文件MD5摘要值
private String md5;
//文件創(chuàng)建作者
private String author;
public FastDFSFile(String name, byte[] content, String ext, String height, String width, String author) {
super();
this.name = name;
this.content = content;
this.ext = ext;
this.author = author;
}
public FastDFSFile(String name, byte[] content, String ext) {
super();
this.name = name;
this.content = content;
this.ext = ext;
}
// getter and setter ...
}
復(fù)制代碼
創(chuàng)建FastDFSClient類,存放在com.qianfeng.util下,在該類中實(shí)現(xiàn)FastDFS信息獲取以及文件的相關(guān)操作,代碼如下:
package com.qianfeng.util;
import com.qianfeng.pojo.FastDFSFile;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 上傳下載等文件操作工具類
* @Author 千鋒壹哥
*/
public class FastDFSClient {
private static org.slf4j.Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
/***
* 初始化加載FastDFS的TrackerServer配置
*/
static {
try {
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
ClientGlobal.init(filePath);
} catch (Exception e) {
logger.error("FastDFS Client Init Fail!",e);
}
}
/***
* 文件上傳
* @param file
* @return
*/
public static String[] upload(FastDFSFile file) {
//獲取文件的作者
NameValuePair[] meta_list = new NameValuePair[1];
meta_list[0] = new NameValuePair("author", file.getAuthor());
//接收返回?cái)?shù)據(jù)
String[] uploadResults = null;
StorageClient storageClient=null;
try {
//創(chuàng)建StorageClient客戶端對(duì)象
storageClient = getTrackerClient();
/***
* 文件上傳
* 1)文件字節(jié)數(shù)組
* 2)文件擴(kuò)展名
* 3)文件作者
*/
uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
} catch (Exception e) {
logger.error("Exception when uploadind the file:" + file.getName(), e);
}
if (uploadResults == null && storageClient!=null) {
logger.error("upload file fail, error code:" + storageClient.getErrorCode());
}
//獲取組名
String groupName = uploadResults[0];
//獲取文件存儲(chǔ)路徑
String remoteFileName = uploadResults[1];
return uploadResults;
}
/***
* 獲取文件信息
* @param groupName:組名
* @param remoteFileName:文件存儲(chǔ)完整名
* @return
*/
public static FileInfo getFile(String groupName, String remoteFileName) {
try {
StorageClient storageClient = getTrackerClient();
return storageClient.get_file_info(groupName, remoteFileName);
} catch (Exception e) {
logger.error("Exception: Get File from Fast DFS failed", e);
}
return null;
}
/***
* 文件下載
* @param groupName
* @param remoteFileName
* @return
*/
public static InputStream downFile(String groupName, String remoteFileName) {
try {
//創(chuàng)建StorageClient
StorageClient storageClient = getTrackerClient();
//下載文件
byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
InputStream ins = new ByteArrayInputStream(fileByte);
return ins;
} catch (Exception e) {
logger.error("Exception: Get File from Fast DFS failed", e);
}
return null;
}
/***
* 文件刪除
* @param groupName
* @param remoteFileName
* @throws Exception
*/
public static void deleteFile(String groupName, String remoteFileName)
throws Exception {
//創(chuàng)建StorageClient
StorageClient storageClient = getTrackerClient();
//刪除文件
int i = storageClient.delete_file(groupName, remoteFileName);
}
/***
* 獲取Storage組
* @param groupName
* @return
* @throws IOException
*/
public static StorageServer[] getStoreStorages(String groupName)
throws IOException {
//創(chuàng)建TrackerClient
TrackerClient trackerClient = new TrackerClient();
//獲取TrackerServer
TrackerServer trackerServer = trackerClient.getConnection();
//獲取Storage組
return trackerClient.getStoreStorages(trackerServer, groupName);
}
/***
* 獲取Storage信息,IP和端口
* @param groupName
* @param remoteFileName
* @return
* @throws IOException
*/
public static ServerInfo[] getFetchStorages(String groupName,
String remoteFileName) throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
}
/***
* 獲取Tracker服務(wù)地址
* @return
* @throws IOException
*/
public static String getTrackerUrl() throws IOException {
return "http://"+getTrackerServer().getInetSocketAddress().getHostString()+":"+ ClientGlobal.getG_tracker_http_port()+"/";
}
/***
* 獲取Storage客戶端
* @return
* @throws IOException
*/
private static StorageClient getTrackerClient() throws IOException {
TrackerServer trackerServer = getTrackerServer();
StorageClient storageClient = new StorageClient(trackerServer, null);
return storageClient;
}
/***
* 獲取Tracker
* @return
* @throws IOException
*/
private static TrackerServer getTrackerServer() throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
return trackerServer;
}
}
創(chuàng)建一個(gè)FileController,在該控制器中實(shí)現(xiàn)文件上傳操作,代碼如下:
package com.qianfeng.controller;
import com.qianfeng.pojo.FastDFSFile;
import com.qianfeng.util.FastDFSClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 文件操作controller接口
* @Author 千鋒壹哥
*/
@RestController
@CrossOrigin
@RequestMapping("/file")
public class FileController {
/**
* 上傳接口
* @param file 接收文件參數(shù), 參數(shù)名必須叫做file
* @Author 千鋒壹哥
*/
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
String path ="";
try {
path=saveFile(file);
System.out.println(path);
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
/**
* 上傳文件到FastDFS分布式文件系統(tǒng)
* @param multipartFile
* @Author 千鋒壹哥
*/
public String saveFile(MultipartFile multipartFile) throws IOException {
//1. 獲取文件名
String fileName = multipartFile.getOriginalFilename();
//2. 獲取文件內(nèi)容
byte[] content = multipartFile.getBytes();
//3. 獲取文件擴(kuò)展名
String ext = "";
if (fileName != null && !"".equals(fileName)) {
ext = fileName.substring(fileName.lastIndexOf("."));
}
//4. 創(chuàng)建文件實(shí)體類對(duì)象
FastDFSFile fastDFSFile = new FastDFSFile(fileName, content, ext);
//5. 上傳
String[] uploadResults = FastDFSClient.upload(fastDFSFile);
//6. 拼接上傳后的文件的完整路徑和名字, uploadResults[0]為組名, uploadResults[1]為文件名稱和路徑
String path = FastDFSClient.getTrackerUrl() + uploadResults[0] + "/" + uploadResults[1];
//7. 返回
return path;
}
}
復(fù)制代碼
測(cè)試步驟:
選擇post請(qǐng)求方式,輸入請(qǐng)求地址 http://localhost:9001/file/upload 填寫(xiě)Headers
Key:Content-Type Value:multipart/form-data
填寫(xiě)body。選擇form-data 然后選擇文件file 點(diǎn)擊添加文件,最后發(fā)送即可。
postman填寫(xiě)信息填寫(xiě)如下步驟所示。
注意Headers請(qǐng)求頭中內(nèi)容:
注意body請(qǐng)求體中內(nèi)容:
上傳結(jié)果后,就可以通過(guò)瀏覽器訪問(wèn)顯示如下效果
至此,各位小伙伴是否都已經(jīng)跟著壹哥學(xué)會(huì)了FastDFS的使用了呢?
現(xiàn)在挺多企業(yè)都是購(gòu)買(mǎi)阿里云或者華為云等云服務(wù)器,然后在這些云服務(wù)器上再手動(dòng)部署FastDFS,這樣比直接購(gòu)買(mǎi)使用阿里的OSS對(duì)象存儲(chǔ)服務(wù)更節(jié)省經(jīng)費(fèi),這也就是FastDFS的魅力所在。
云盤(pán)的出現(xiàn)滿足了人們對(duì)數(shù)據(jù)存儲(chǔ)、備份、訪問(wèn)和共享的多種需求,提供了方便、靈活和安全的解決方案。這些服務(wù)已成為個(gè)人和企業(yè)日常生活中不可或缺的一部分。
ownCloud 是一款用于數(shù)據(jù)同步和文件共享的開(kāi)源服務(wù)器軟件,它提供了易用的瀏覽器端,可以很方便的搭建個(gè)人和企業(yè)云盤(pán)。ownCloud 可以安裝在 Linux 或 Windows 服務(wù)器上,配置簡(jiǎn)單并提供完備的文檔。除瀏覽器端外,它還支持 Windows、MacOS、Linux、Android 和 iOS 客戶端。 本文將詳細(xì)描述如何在 CentOS 7 服務(wù)器上安裝和配置 ownCloud 10.13,展示如何使用 Nginx 和 PHP 7(FPM)以及 MySQL 來(lái)配置 ownCloud。
核心特性:
運(yùn)行 ownCloud 的內(nèi)存要求很低,但官方要求至少 128MB 內(nèi)存,建議 512MB 內(nèi)存。由于我們搭建的私人云盤(pán),512MB 內(nèi)存能支持 10 用戶并發(fā),已足夠我們使用。
首先,下載 MySQL rpm 包,使用本地安裝方式下載安裝包及依賴包:
yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
然后,安裝 mysql-community-server 軟件包,啟動(dòng) MySQL 并找到隨機(jī)密碼:
# 安裝 MySQL
yum install mysql-community-server
# 啟動(dòng) MySQL
systemctl start mysqld
# 查找安裝時(shí)生成的隨機(jī)密碼
[root@ownCloud ~]# grep -i password /var/log/mysqld.log
2023-09-03T07:04:16.666834Z 1 [Note] A temporary password is generated for root@localhost: aiwfrtTl7-=2
接著,我們使用隨機(jī)密碼登錄 MySQL,創(chuàng)建 ownCloud 庫(kù)和 ownCloud 用戶并做好授權(quán):
# 創(chuàng)建 ownCloud 庫(kù)
mysql> CREATE DATABASE owncloud DEFAULT CHARACTER SET utf8mb4;
# 新建 ownCloud 用戶
mysql> CREATE USER owncloud@'%' IDENTIFIED BY 'owncloud';
# 授權(quán)
mysql> grant all privileges on owncloud.* to owncloud@'%' identified by 'owncloud';
# 刷新授權(quán)
mysql> flush privileges;
網(wǎng)上有很多 PHP7 庫(kù),我們這里使用 webtatic 庫(kù):
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
接著我們安裝 php7-fpm 和一些用于 ownCloud 安裝的依賴軟件包:
yum -y install php php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mcrypt php-mbstring php-curl php-xml php-pear php-bcmath php-json php-intl php-pecl-zip
若提示 “失敗的軟件包是:mysql-community-libs-compat-5.7.43-1.el7.x86_64”,請(qǐng)使用rpm --import [https://repo.mysql.com/RPM-GPG-KEY-mysql-2022](https://repo.mysql.com/RPM-GPG-KEY-mysql-2022)命令解決。
檢查 PHP 版本確保安裝成功:
[root@owncloud tmp]# php -v
PHP 7.4.33 (cli) (built: Aug 1 2023 09:00:17) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
我們將配置 php-fpm 與 nginx 一塊運(yùn)行。php7-fpm 將在 nginx 用戶下運(yùn)行,并監(jiān)聽(tīng) 9000 端口。 使用 vim 編輯默認(rèn)的 php7-fpm 配置:
vim /etc/php-fpm.d/www.conf
在第 24 行和第 26 行中,將 user 和 group 更改為 nginx。
user = nginx
group = nginx
查看第 38 行,確保 php-fpm 在 9000 端口運(yùn)行。
listen = 127.0.0.1:9000
取消第 396-400 行的注釋,開(kāi)啟 php-fpm 系統(tǒng)環(huán)境變量。
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
保存文件并退出編輯器。接下來(lái),在 /var/lib/ 目錄中為 session 創(chuàng)建一個(gè)新目錄,并將目錄所有者更改為 nginx 用戶。
mkdir -p /var/lib/php/session
chown nginx:nginx -R /var/lib/php/session/
啟動(dòng) php-fpm,然后將其添加到開(kāi)機(jī)自啟動(dòng)。
systemctl start php-fpm
systemctl enable php-fpm
至此,php7-fpm 配置已完成。
添加 Nginx 官方 yum 源 /etc/yum.repos.d/nginx.repo 文件中添加以下內(nèi)容,設(shè)置 nginx yum 源:
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
yum install -y nginx
systemctl start nginx
systemctl enable nginx
我們使用 wget 命令下載 ownCloud,因此需要先安裝 wget 包。另外,我們還需要安裝 unzip 包用于解壓縮 zip 文件。
yum -y install wget unzip
進(jìn)入 /tmp 目錄并使用 wget 從 ownCloud 站點(diǎn)下載最新穩(wěn)定的 ownCloud 10.13 壓縮包:
cd /tmp
wget --no-check-certificate https://download.owncloud.com/server/stable/owncloud-10.13.0.zip
解壓 owncloud-10.13.0.zip 文件并將其移動(dòng)到 /usr/share/nginx/html/ 目錄:
unzip owncloud-10.13.0.zip
mv owncloud/ /usr/share/nginx/html/
接下來(lái),轉(zhuǎn)到 nginx Web 根目錄并為 owncloud 創(chuàng)建一個(gè)新的 data 目錄。
cd /usr/share/nginx/html/
mkdir -p owncloud/data/
將 owncloud 目錄的所有者更改為 nginx 用戶和組。
chown nginx:nginx -R owncloud/
1). 生成自簽名 SSL 證書(shū)
我們將在的 https 連接下運(yùn)行 owncloud。您可以使用免費(fèi)的 SSL 證書(shū),例如 let's encrypt。在本文中,我將使用 OpenSSL 命令創(chuàng)建我自己的 SSL 證書(shū)文件。為 SSL 文件創(chuàng)建一個(gè)新目錄:
mkdir -p /etc/nginx/cert/
然后使用下面的 OpenSSL 命令生成新的 SSL 證書(shū)文件:
openssl req -new -x509 -days 365 -nodes -out /etc/nginx/cert/owncloud.crt -keyout /etc/nginx/cert/owncloud.key
按照 OpenSSL 命令的要求輸入 SSL 證書(shū)的詳細(xì)信息。然后用 chmod 命令將所有證書(shū)文件的權(quán)限改為 600。
chmod 600 /etc/nginx/cert/*
2). 在 Nginx 中配置 ownCloud 虛擬主機(jī)
在1.下載 ownCloud 步驟中,我們下載了 ownCloud 源代碼并將其配置為在 Nginx Web 服務(wù)器下運(yùn)行。但我們?nèi)匀恍枰獮?ownCloud 配置虛擬主機(jī)。 在 /etc/nginx/conf.d/ 目錄中創(chuàng)建一個(gè)新的虛擬主機(jī)配置文件 owncloud.conf:
cd /etc/nginx/conf.d/
vim owncloud.conf
添加以下虛擬主機(jī)配置:
upstream php-handler {
server 127.0.0.1:9000;
#server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name data.owncloud.co;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name data.owncloud.co;
ssl_certificate /etc/nginx/cert/owncloud.crt;
ssl_certificate_key /etc/nginx/cert/owncloud.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=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
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;
# Path to the root of your installation
root /usr/share/nginx/html/owncloud/;
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;
}
location /.well-known/acme-challenge { }
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Disable gzip to avoid the removal of the ETag header
gzip off;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
return 404;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
return 404;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.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;
fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
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 $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)$ {
try_files $uri /index.php$uri$is_args$args;
add_header Cache-Control "public, max-age=7200";
# 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=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
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;
# Optional: Don't log access to assets
access_log off;
}
location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
# Optional: Don't log access to other assets
access_log off;
}
}
保存文件并退出編輯器。
最后,測(cè)試 nginx 配置無(wú)誤,然后重新啟動(dòng) nginx。
# 驗(yàn)證 nginx 配置是否有誤
nginx -t
# 重新啟動(dòng) nginx
systemctl restart nginx
我們將使 SELinux 保持在強(qiáng)制模式下,因此我們需要 SELinux 管理工具包來(lái)配置它。使用 yum 命令安裝 SELinux 管理工具:
yum -y install policycoreutils-python
然后以 root 身份執(zhí)行以下命令,以允許 ownCloud 在 SELinux 下運(yùn)行。請(qǐng)記住更改 ownCloud 目錄,以防您使用不同的目錄進(jìn)行 ownCloud 安裝:
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/data(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/config(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/apps(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/assets(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/.htaccess'
semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/owncloud/.user.ini'
restorecon -Rv '/usr/share/nginx/html/owncloud/'
接下來(lái),啟動(dòng) firewalld 服務(wù)并打開(kāi) owncloud 的 HTTP 和 HTTPS 端口。
# 啟動(dòng) firewalld 服務(wù)
systemctl start firewalld
# 開(kāi)啟 firewalld 服務(wù)自啟動(dòng)
systemctl enable firewalld
使用 firewall-cmd 命令打開(kāi) HTTP 和 HTTPS 端口,然后重新加載防火墻使之立即生效。
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
至此,服務(wù)器配置部分已完成。
現(xiàn)在,打開(kāi)瀏覽器并輸入 ownCloud 公網(wǎng)IP,我的IP是:xxx.xxx.xxx.xxx,您將被重定向到安全的 HTTPS 連接。設(shè)置管理員的用戶名和密碼,然后輸入數(shù)據(jù)庫(kù)信息并單擊完成設(shè)置,等待 OwnCloud 安裝完成。
至此,Owncloud 已在 CentOS 7 服務(wù)器上成功安裝 Nginx、php7-fpm 和 MySQL。
若提示 php zip 模塊沒(méi)有安裝或者 intl 模塊沒(méi)有安裝,請(qǐng)運(yùn)行 yum -y install php-intl php-pecl-zip 命令安裝