為何要自建云服務(wù)或者NAS不是本文的重點(diǎn),這里就不說明了。
本文重點(diǎn)在于提供一種價(jià)格低廉的自建云服務(wù)解決方案,并且易于學(xué)習(xí)和再現(xiàn)。
但是,講述如何使用Linux系統(tǒng)以及一些基礎(chǔ)的命令亦不是本文范圍。
所以,開始閱讀前,請先確認(rèn)
本文的適合對象
- 我假設(shè)你有使用過Linux操作系統(tǒng)的經(jīng)驗(yàn);假設(shè)你知道什么是sudo、ls、以及文件系統(tǒng)
- 我亦假設(shè)你知道什么是RAID、SSH、http/https服務(wù)
- 如果要安裝NextCloud,你還必須了解php、編譯、mysql的相關(guān)知識
寫在前面
自從打算著手自建云服務(wù)以來,一直在考慮實(shí)現(xiàn)方案。
成本是首要考慮的因素。畢竟如果自購硬件成本大于租用CVM,那為什么不去租一臺?其次,如果不考慮成本,也完全可以直接采購現(xiàn)成的解決方案,沒必要自己折騰了。
性能是其次的,畢竟是家用,不會有2位數(shù)的在線人數(shù)。
于是便有了這個(gè)方案。
采購準(zhǔn)備
在開始組建軟件前,你首先得準(zhǔn)備一些必須的硬件。這里有一個(gè)清單可以對照著看。
清單里的設(shè)備并不都是需要新購的,你完全可以利用現(xiàn)有的設(shè)備。
清單
- 一套 Raspberry Pi 3 Model B+(主板、外殼、電源)(約240元)
- 一根HDMI鏈接線(約10元)
- 一張16G或以上的Micro SD卡(約30元)
- Micro SD卡讀卡器
- 一臺支持HDMI的顯示器
- USB鼠標(biāo)
- 一臺用于遠(yuǎn)程連接Raspberry Pi的電腦,或者USB鍵盤
- 一個(gè)雙盤位硬盤盒
- 兩塊相同容量的硬盤
- 建議使用有線網(wǎng)線連接網(wǎng)絡(luò)(約10元)
Raspberry Pi
Raspberry Pi是一款使用ARM芯片的單片機(jī),3B+是他們現(xiàn)在最新的型號。
這是一臺完整的電腦,功能非常強(qiáng)大。3B+使用一款1.4GH的4核64位ARM CPU,1G內(nèi)存,4個(gè)USB 2.0接口,一個(gè)HDMI顯示接口,以及GPIO接口。
更重要的是,其功耗不到15瓦,售價(jià)約只有240元左右,作為一般家用的云服務(wù)主機(jī)簡直完美。
如果你想要更多信息,點(diǎn)擊這里訪問他們的官網(wǎng)
如果你只相信官方指定經(jīng)銷商,這里是一個(gè)官方列表
外殼看起來不是必須的,但建議一定要買,一個(gè)堅(jiān)固的外殼將給24小時(shí)運(yùn)行的主板提供最基礎(chǔ)的物理防護(hù)。
Micro SD卡
Raspberry Pi不含內(nèi)置硬盤,采用外插SD卡作為存儲。所以如果你沒有用剩下的SD卡,可能就需要購買一張。
官方也提供已經(jīng)預(yù)先錄入NOOBS的卡賣,但是這價(jià)格完全不值得——那其實(shí)就是從官網(wǎng)下載了NOOBS,然后直接復(fù)制到卡里而已。
如果你打算新購一張SD卡,建議買讀寫速度快的——越快越好,畢竟這是整個(gè)系統(tǒng)中速度最慢的組件。
Micro SD卡讀卡器
這當(dāng)然是為了讀寫SD卡準(zhǔn)備的,當(dāng)然你手頭很可能已經(jīng)有很多個(gè)了,又或者你的電腦本來就能直接讀取SD卡。即便新買一個(gè),價(jià)格也便宜到忽略不計(jì)。
顯示器
我相信看到本文的家里至少有一臺顯示器或者帶顯示器的筆記本,如果沒有,好吧,你可以檢查一下自己的電視機(jī)是否支持HDMI,支持的話也能拿來用,不然的話還是去買一臺吧。
USB鍵盤
如果打算之后用NOOBS方式安裝系統(tǒng),并且你有一臺筆記本或電腦用來遠(yuǎn)程連接Raspberry Pi,那么USB鍵盤就不是必須的,否則的話就去準(zhǔn)備一個(gè)。
USB鼠標(biāo)
事實(shí)上USB鼠標(biāo)也不是必須的,前提是你有一個(gè)USB鍵盤。
雙盤位硬盤座/硬盤柜
最后需要一個(gè)2盤位的硬盤盒用來接入大容量硬盤作為主要存儲。
建議2盤位是為了成本考慮,淘寶上看了一圈,4盤位的都在400元以上,雖然用3個(gè)盤組RAID5很誘人(速度優(yōu)于2塊硬盤的RAID1),但這不是必須的,2盤位的性能夠用,也位數(shù)據(jù)提供了堅(jiān)實(shí)的保障。
最終我購買了一款A(yù)casis的DS-P2U3C硬盤盒,這大約是我能找到的性價(jià)比最高的金屬外殼硬盤盒,大約130元。如果你不在乎金屬外殼,還有更便宜的選擇。但請仔細(xì)挑選硬盤盒,不要選用那些不帶外部供電的產(chǎn)品。
值得注意的是,Acasis還有一款雙硬盤自帶陣列的硬盤盒,價(jià)格非常誘人,但這是一筆沒有必要的開銷,而且不便以后擴(kuò)展。我們將以軟件實(shí)現(xiàn)陣列功能。
不得不說的是,硬盤柜是略優(yōu)于硬盤底座的一個(gè)選擇,原因當(dāng)然是硬盤柜的外殼提供了基礎(chǔ)的物理防護(hù)。之所以說略優(yōu),是因?yàn)橛脖P本身是有外殼的,并不像電路板那樣怕粉塵,但是如果你害怕自己的硬盤會受物理沖擊,還是選擇一款硬盤柜的好,當(dāng)然相比底座價(jià)格更貴。
硬盤
最后,硬盤可以使用老設(shè)備上淘汰下來的。我就拆了兩塊2.5寸移動硬盤,它們正好都是500G大小。如果沒有現(xiàn)成的硬盤,你就得去買兩塊,容量大小跟你的錢包商量。從目前市場行情看,3TB的3.5寸硬盤是最具性價(jià)比的。你也可以購買SSD硬盤,要提醒的是,速度超過網(wǎng)絡(luò)或者USB 2.0的硬盤在目前的方案上不會帶來任何性能提升。
[圖片上傳失敗...(image-8beea1-1557927673898)]
[圖片上傳失敗...(image-5a6c11-1557927673898)]
開始安裝
為樹莓派安裝操作系統(tǒng)
你的樹莓派已經(jīng)到手,外殼也組裝完畢,讓我們馬上為它安裝操作系統(tǒng)。
NOOBS或者NOOBS
針對這次的需求,如果你對Linux比較熟悉,可以從官網(wǎng)下載安裝Raspbian Stretch Lite。Lite版提供了最少的預(yù)裝軟件,并且不包含圖形界面;這讓你可以按需只安裝必要的軟件,減少空間浪費(fèi),提升服務(wù)器性能。
但是NOOBS方式安裝起來更方便易懂,這正是本文的目標(biāo)。所以我會提供NOOBS的安裝說明。
制作安裝盤
首先將你的SD卡格式化,注意使用FAT32格式,因?yàn)镻i在啟動時(shí)只能識別FAT32文件系統(tǒng)。
然后從官網(wǎng)下載NOOBS文件,如果你的網(wǎng)絡(luò)受限,也可以使用這個(gè)鏈接:百度網(wǎng)盤 提取碼: yawk
目前版本是3.0.1,這個(gè)鏈接會有效至下一個(gè)版本發(fā)布。
NOOBS下載下來是一個(gè)zip文件,你只需將內(nèi)容全部解壓到你的SD卡,安裝盤這就算準(zhǔn)備好了,沒錯(cuò),絲毫不用懷疑。
安裝系統(tǒng)
將制作好的SD卡插入樹莓派,順便接上鼠標(biāo),還有顯示器,然后開機(jī)。
你面臨的第一個(gè)選擇是安裝哪種系統(tǒng),請選擇Raspbian——官方系統(tǒng)。然后跟著向?qū)б徊讲竭x下去就能完成安裝過程,重新啟動后會進(jìn)入初始化設(shè)置。
設(shè)置界面中只有最后一步值得注意,系統(tǒng)會詢問是否需要更新軟件,如果你能夠接入wifi或者網(wǎng)線,就請更新,否則話就跳過,之后我們還是能通過控制臺更新。
系統(tǒng)設(shè)置
現(xiàn)在我們要為之后的作業(yè)做一些基本設(shè)置,包括打開遠(yuǎn)程SSH連接和系統(tǒng)優(yōu)化。
在開始設(shè)置前,如果你還沒有連上網(wǎng)絡(luò),或之前更新軟件失敗?,F(xiàn)在請立即更新。
打開終端——你能在屏幕最上方的任務(wù)欄上找到它,然后依次輸入以下命令:
sudo apt-get update
sudo apt-get upgrade
update命令更新軟件源索引,upgrade命令將更新所有需要升級的軟件。
過程中請留意控制臺輸出,如果有下載失敗可以多試幾次。
設(shè)置啟動到命令行
更新完畢后我們開始配置系統(tǒng)。
在控制臺輸入這條命令:
sudo raspi-config
然后在出現(xiàn)的界面中選擇:
3 Boot Options
然后在第二級菜單中選擇:
B1 Desktop / CLI
最后選擇:
B1 Console
這條設(shè)置樹莓派每次啟動后直接進(jìn)入命令行,而不是圖形桌面,之后的軟件安裝配置大多只能通過命令行進(jìn)行,所以我們用不上圖形桌面。
開啟SSH登錄
從一級菜單,選擇:
5 Interfacing Options
然后選擇
P2 SSH
打開了SSH后,下次啟動時(shí)我們就能通過SSH遠(yuǎn)程連接樹莓派了。
重新劃分系統(tǒng)內(nèi)存
從一級菜單中選
7 Advanced Options
然后
A3 Memory Split
樹莓派的顯卡是共享系統(tǒng)內(nèi)存,我們因?yàn)闊o需使用圖形界面,所以這里輸入8。只要分配8M給顯卡就足夠了,剩下的都能用于系統(tǒng)運(yùn)行。
必要的設(shè)置到此完畢,記得重啟生效。
組建磁盤陣列
對于需要長時(shí)間運(yùn)行的服務(wù),組建RAID1陣列我認(rèn)為是必須的。要注意消費(fèi)級硬盤的可靠性測試都不是基于24小時(shí)運(yùn)行而設(shè)計(jì)的,即便購買了企業(yè)級硬盤,也沒有廠商敢保證他們的硬盤可以抗打雷抗停電——事實(shí)上即便是企業(yè)內(nèi)部服務(wù)器購買了企業(yè)級硬盤,仍然會組建磁盤陣列來保持?jǐn)?shù)據(jù)的安全。說到底,這取決于硬盤里的數(shù)據(jù)對你到底有多重要。
安裝mdadm
警告
組建RAID1過程中,會將兩塊硬盤都格式化。所以在開始前,請確保兩塊硬盤中沒有任何有用的數(shù)據(jù)。
{: .notice--danger}
遠(yuǎn)程連接到你的樹莓派,執(zhí)行以下命令安裝mdadm:
sudo apt-get install mdadm
小貼士
試試
sudo apt-get install mdadm -y
這樣就不用回答『您希望繼續(xù)執(zhí)行嗎?』這樣的問題了。
{: .notice--info}
確認(rèn)兩塊硬盤的設(shè)備名稱
執(zhí)行l(wèi)sblk命令確認(rèn)硬盤設(shè)備名稱
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
...
sdb 8:16 0 465.8G 0 disk
...
mmcblk0 179:0 0 29.8G 0 disk
├─mmcblk0p1 179:1 0 1.8G 0 part
├─mmcblk0p2 179:2 0 1K 0 part
├─mmcblk0p5 179:5 0 32M 0 part
├─mmcblk0p6 179:6 0 66M 0 part /boot
└─mmcblk0p7 179:7 0 27.9G 0 part /
可以看到例子中存在3塊disk。
其中mmcblk0是Micro SD卡,sda與sdb則是兩塊硬盤。
創(chuàng)建陣列磁盤md0
使用sda與sdb兩塊硬盤創(chuàng)建新的RAID1硬盤md0
sudo mdadm --create /dev/md0 --level=mirror --raid-devices=2 /dev/sda /dev/sdb
--create /dev/md0 表示新建的設(shè)備名稱為/dev/md0
--level=mirror 表示RAID類型為RAID1,即『鏡像』
--raid-devices=2 表示新RAID盤包含兩個(gè)設(shè)備
最后跟上設(shè)備名稱就回車執(zhí)行。
然后控制臺會輸出以下內(nèi)容:
mdadm: Note: this array has metadata at the start and
may not be suitable as a boot device. If you plan to
store '/boot' on this device please ensure that
your boot-loader understands md/v1.x metadata, or use
--metadata=0.90
Continue creating array?
這個(gè)提示的大意是,正要?jiǎng)?chuàng)建的陣列不支持作為啟動分區(qū)使用,確認(rèn)是否繼續(xù);我們當(dāng)然要輸入y,并回車?yán)^續(xù)。
最后如果看到以下信息,就說明md0創(chuàng)建已經(jīng)成功:
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
然后確認(rèn)下新建的md0的運(yùn)行狀態(tài):
# pi @ raspberrypi in ~/tmp [11:45:20] C:2
$ sudo mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Thu May 9 15:14:20 2019
Raid Level : raid1
Array Size : 488255488 (465.64 GiB 499.97 GB)
Used Dev Size : 488255488 (465.64 GiB 499.97 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Intent Bitmap : Internal
Update Time : Wed May 15 02:04:02 2019
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Name : raspberrypi:0 (local to host raspberrypi)
UUID : 296a305d:809bf8cd:c259df5a:70488bf7
Events : 15549
Number Major Minor RaidDevice State
0 8 0 0 active sync /dev/sda
1 8 16 1 active sync /dev/sdb
沒有異常,很好,創(chuàng)建成功。
最后不要忘記將md0的信息更新到mdadm.cconf文件,這樣每次開機(jī)啟動時(shí)候mdadm都會自動登記md0設(shè)備。
sudo mdadm --detail --scan --verbose >> /etc/mdadm/mdadm.conf
這條命令會掃描系統(tǒng)上所有已經(jīng)創(chuàng)建的RAID設(shè)備,并將其信息輸出成mdadm.conf能夠識別的格式,最終保存到/etc/mdadm/mdadm.conf文件的末尾
mdadm的功能很強(qiáng)大,包括對raid盤的監(jiān)控、擴(kuò)展等等。
想要學(xué)習(xí)其更高級的使用方法的話,可以查看其man資料。
格式化
在這之前先格式化一下,為md0創(chuàng)建文件系統(tǒng):
sudo mkfs.ext4 /dev/md0
掛載
陣列磁盤已經(jīng)就緒,讓我們掛上它,立即開始使用!
先創(chuàng)建想要掛載的位置
sudo mkdir /mnt/data
然后掛載
sudo mount /dev/md0 /mnt/data
這個(gè)例子將md0盤掛到了/mnt/data目錄中,實(shí)際你可以掛載到自己喜歡的位置,例如:~/data,掛載前別忘了先創(chuàng)建該目錄就行。
好吧,現(xiàn)在開始終于可以通過/mnt/data目錄寫我們的RAID盤了。
但是,等下,別急,如果你不想每次重啟機(jī)器都自己手動掛載,那我們還有最后一步,那就是開機(jī)自動掛載。
開機(jī)自動掛載
linux的磁盤掛載信息都記錄在/etc/fstab文件里
使用你拿手的文本編輯器打開它,本文所有例子將使用nano。
sudo nano /etc/fstab
在文件的最后插入一行:
/dev/md0 /mnt/data ext4 defaults 0 0
如果樂意,你可以加上一行「#」開頭的注釋,這有助于你日后回憶。
Tips
nano中按ctrl+o保存,ctrl+x退出。請留意底部的快捷鍵功能提示
{: notice--info}
至此,一臺掛載了RAID1硬盤的服務(wù)器已經(jīng)準(zhǔn)備完畢。
即使不繼續(xù)安裝任何其他軟件,你也已經(jīng)可以將這臺機(jī)器當(dāng)做一臺可靠的重要數(shù)據(jù)備份機(jī)使用??晌覀儺?dāng)然不會滿足于此,對吧?
下一節(jié)開始將為樹莓派逐步安裝配置各類軟件來為我們更好的服務(wù)。
服務(wù) 服務(wù) 服務(wù)!
終于要開始安裝我們的云服務(wù),這才是我們真正的目標(biāo),之前的都是準(zhǔn)備工作。
但是到了云服務(wù)這塊,可選擇的內(nèi)容非常之多。接下來要做的內(nèi)容并不全都是必須的,可以根據(jù)自己的需要選擇性部署。
syncthing
syncthing是一個(gè)非常有意思的軟件,其主要用途是用來在各個(gè)計(jì)算機(jī)設(shè)備間進(jìn)行文件同步。這『計(jì)算機(jī)設(shè)備』包含很多不同的操作系統(tǒng)甚至是cpu架構(gòu)——同樣包括手機(jī)。
但是要注意syncthing目前并沒有ios版本
這意味著你不能通過蘋果手機(jī)與自己的服務(wù)器進(jìn)行同步。
如果你想用蘋果手機(jī)進(jìn)行云同步,那么可以跳過這一節(jié),試試之后的NextCloud。
syncthing的原理是通過類似電驢的p2p協(xié)議進(jìn)行通訊傳輸。這種協(xié)議不需要使用中央服務(wù)器來保存數(shù)據(jù)并負(fù)責(zé)分發(fā),而是由A機(jī)器直接路由到B機(jī)器來進(jìn)行通訊。
synthing并不需要知道需要通訊的機(jī)器都ip地址,它采用中介服務(wù)器方式,登記連上來的機(jī)器的網(wǎng)絡(luò)信息,負(fù)責(zé)為需要通訊的雙法尋找路由握手。所以synthing不需要通訊雙方都具備公網(wǎng)ip,只要他們能聯(lián)通到同一個(gè)網(wǎng)絡(luò),互相之間就能通訊。
當(dāng)然,假設(shè)AB兩臺機(jī)器都沒有公網(wǎng)ip,要讓他們之間能通訊,肯定是需要經(jīng)過至少一臺具備公網(wǎng)ip的機(jī)器的,這種在通訊雙方間作為橋梁性質(zhì)的機(jī)器稱作中介服務(wù)器,發(fā)揮著路由的作用。
所以你在兩臺機(jī)器間同步數(shù)據(jù)的時(shí)候,你的數(shù)據(jù)可能會經(jīng)過1臺或者多臺中介,最終保存到你指定的計(jì)算機(jī)上。
但是不用擔(dān)心數(shù)據(jù)安全的問題,中介服務(wù)器實(shí)際并不知道自己接收到的數(shù)據(jù)將要傳輸?shù)淖罱K目的地是哪里,下一個(gè)接手的可能是目的地,更多可能是另一臺中介。另外syncthing的數(shù)據(jù)在傳輸時(shí)都使用了TLS進(jìn)行加密。
綜上,syncthing是用來作為同步和備份網(wǎng)盤的極好方案。
想要了解syncthing更多,點(diǎn)擊這里訪問syncthing官網(wǎng)。
Raspberry Pi上的安裝
在Raspberry Pi上安裝syncthing的一個(gè)比較簡單的方式是——直接下載。
你可以從官網(wǎng)找到ARM版的安裝包。
如果你的網(wǎng)絡(luò)受到神秘力量的干擾而無法訪問官網(wǎng),可以轉(zhuǎn)為訪問項(xiàng)目組的github release主頁。
這兩個(gè)地方哪里下載都是一樣的。
要注意的是,為了服務(wù)器穩(wěn)定,請下載最新的release版本,而不是rc候選版本。并且能夠在Raspberry Pi上運(yùn)行的是arm版,而不是arm64.
在Raspberry Pi上可以使用wget命令進(jìn)行文件下載:
wget https://github.com/syncthing/syncthing/releases/download/v1.1.3/syncthing-linux-arm-v1.1.3.tar.gz
下載到你喜歡的地方,然后解壓:
tar -xzvf syncthing-linux-arm-v1.1.3.tar.gz
然后直接執(zhí)行syncthing:
syncthing-linux-arm-v1.1.3/syncthing
注意控制臺的輸出信息,待啟動徹底完成后按下鍵盤的Ctrl+C以中指syncthing。
這是因?yàn)閟yncthing第一次啟動默認(rèn)配置的web管理地址只能從本機(jī)(樹莓派)上訪問,而本機(jī)現(xiàn)在只是一個(gè)控制臺。
開啟遠(yuǎn)程訪問
接著找到syncthing的配置文件,我們要修改它能在局域網(wǎng)其他地方也能訪問。
syncthing的配置文件默認(rèn)放在 ~/.config/syncthing目錄下。
使用nano打開配置文件:
nano ~/.config/syncthing/config.xml
找到這段內(nèi)容:
<gui enabled="true" tls="false" debugging="false">
<address>127.0.0.1:8384</address>
將127.0.0.1改成0.0.0.0
改完后看起來這樣:
<gui enabled="true" tls="false" debugging="false">
<address>0.0.0.0:8384</address>
保存后再次啟動syncthing,啟動成功后你就可以通過https://ip:8384/ 來訪問你的syncthing管理頁面了。
其中ip是Raspberry Pi的ip地址。
你可以通過ifconfig命令來查看:
sudo ifconfig -a
或者從你的路由器管理頁面上找到。
同步文件夾設(shè)置
事實(shí)上syncthing的官方文檔維護(hù)的不錯(cuò),如果你的網(wǎng)絡(luò)不受神秘力量影響,可以直接查看官方文檔進(jìn)行你的同步文件夾設(shè)置。
如果不幸你訪問不了官方文檔,那么還有個(gè)好消息是syncthing的全中文界面異常完整,設(shè)置非常簡單。
強(qiáng)烈建議你先點(diǎn)擊『添加文件夾』按鈕試試。
[圖片上傳失敗...(image-a75aa5-1557927673898)]
[圖片上傳失敗...(image-8639ed-1557927673898)]
[圖片上傳失敗...(image-475aac-1557927673898)]
在高級選項(xiàng)卡里可以設(shè)置文件類型——發(fā)送與接收、僅發(fā)送、僅接收。
這是非常有用的一個(gè)功能,這意味著你不僅可以建同步目錄,也可以建備份目錄。
Android手機(jī)安裝syncthing
如果前面你仔細(xì)看了,當(dāng)然知道syncthing沒有ios版本。
但壞消息不止這一個(gè)——syncthing的安卓下載放在注明的Google Play商店里。這是個(gè)沒有些特殊手段永遠(yuǎn)都到達(dá)不了地方,是嗎?(笑)
如果你有自己的神通,那是時(shí)候顯現(xiàn)了。
如果你沒有神通,我提供一個(gè)百度網(wǎng)盤 提取碼: x4jj。
這個(gè)是由F-Droid編譯并簽名,且保證與開源源碼一致的版本。
連接里當(dāng)然也提供了F-Droid的簽名,請自行驗(yàn)證。
安卓版syncthing的界面與服務(wù)器幾乎一致(請使用網(wǎng)頁管理頁面,原生界面設(shè)置功能比網(wǎng)頁管理頁面少)
手機(jī)上唯一要多做一步的就是添加設(shè)備,把你的Raspberry Pi上的syncthing添加進(jìn)來,它們舊能同步了。
打開Raspberry Pi上的syncthing的管理頁面,點(diǎn)擊顯示設(shè)備ID,會出現(xiàn)一個(gè)二維碼;然后在手機(jī)上用相機(jī)掃一下二維碼,將得到的ID復(fù)制下來;然后在安卓syncthing上點(diǎn)擊添加設(shè)備,將復(fù)制下來的ID粘貼進(jìn)去,就能方便的設(shè)置成功。
然后你就可以在安卓上設(shè)置需要同步的文件夾推送給Raspberry Pi,或者接收Raspberry Pi要推送給安卓的文件夾。
關(guān)于公網(wǎng)IP
接著會介紹一些web服務(wù)的自建方法。這些web服務(wù),如果你想在外網(wǎng)也能隨時(shí)隨地訪問的話,至少需要一個(gè)公網(wǎng)IP,哪怕是動態(tài)的。
如果不幸你跟我一樣處在可以上外網(wǎng)卻沒有公網(wǎng)IP的情況(ISP劫持了DNS,隱藏了真實(shí)的外網(wǎng)IP,并封鎖所有端口),那么也不要太過氣餒,我至少還有兩個(gè)辦法可以讓你穿透出去。
花生殼
花生殼是國內(nèi)的老牌內(nèi)網(wǎng)穿透服務(wù)商了。
官網(wǎng)連接。
現(xiàn)在買花生棒還送每月2G流量的服務(wù)。
我并不是要在這里推銷花生棒或者花生殼。相反,他們的服務(wù)非常不具性價(jià)比。
首先,所謂的花生棒就是一臺裝了內(nèi)網(wǎng)端口映射工具的低性能單片機(jī),而內(nèi)網(wǎng)端口映射實(shí)際上只要裝一個(gè)軟件就行,所以這100來塊錢實(shí)際就是用來買每月1G流量的(它們的免費(fèi)軟件賬號有1G流量)。
其次,每月2G流量是什么概念?用來傳文件不太合適,記記筆記是夠用的。
最危險(xiǎn)的,免費(fèi)賬號只支持80端口,這是什么概念?意思是你的所有連接只能從http進(jìn)出,而不是https,這等于所有數(shù)據(jù)都裸露在通訊路徑上,不僅未授權(quán)的人可以隨便截取,花生殼的員工也只要簡單的把文件保存下來直接就能看。
那還不如百度網(wǎng)盤?這是肯定的。
花生殼的確有https服務(wù),但是,但是,SSL加密證書得買它們的,價(jià)格呢?都夠我去租一臺CVM了。
Sunny
Sunny ngrok
這并不是ngrok的官網(wǎng),而是用ngrok的1.x開源軟件改造后面向國內(nèi)運(yùn)營的網(wǎng)站。10元/月/端口,限速5M帶寬,對于私用是很實(shí)惠的。
要注意的是,一定要選擇使用https協(xié)議,只有這個(gè)才是加密的。
安裝nginx
上節(jié)介紹的syncthing是本文中唯一一個(gè)不需要公網(wǎng)ip的服務(wù)。
說到底,syncthing通過中介服務(wù)器進(jìn)行數(shù)據(jù)交換,而不是基于web服務(wù)。
在接下來的內(nèi)容中要配置的幾乎都是web服務(wù),我打算把它們都架設(shè)在nginx上。
非常幸運(yùn)的是,apt-get源里提供了nginx的安裝包,這意味著你只要執(zhí)行apt-get就能完成安裝:
sudo apt-get install nginx-full -y
然后通過systemctl配置nginx服務(wù)作為系統(tǒng)服務(wù)開機(jī)自啟:
sudo systemctl enable nginx
如果沒有什么出錯(cuò)信息,那么nginx就算裝成功了。
nginx的配置不在本節(jié)內(nèi)講,這是根據(jù)你需要運(yùn)行什么服務(wù)決定如何添加配置,如果不需要安裝任何web服務(wù),nginx都不需要安裝。
NextCloud
官網(wǎng)在這里。
NextCloud算是老牌的開源云盤了,它并不是一個(gè)同步工具,而是類似DropBox的云盤。雖然也支持文件夾自動上傳,但是對比syncthing就弱了太多。
好消息是,NextCloud支持所有手機(jī)端。
[圖片上傳失敗...(image-f399cb-1557927673898)]
安卓版官網(wǎng)直接能夠下載!
點(diǎn)『App Store』下面那個(gè)『...direct AAPK download...』就行。
Raspberry Pi安裝NextCloud服務(wù)器端
壞消息是,NextCloud對于缺少Linux服務(wù)器經(jīng)驗(yàn)的人來說過于復(fù)雜了。
因?yàn)镹extCloud是用PHP開發(fā)的,所以除了nginx,還需要安裝PHP。
然后NextCloud需要使用數(shù)據(jù)庫,好吧,我推薦安裝MySQL。
一步步來。
安裝PHP7.3
更壞的消息是,NextCloud 16.0需要運(yùn)行在PHP 7.1以上,而apt-get官方源的版本是7.0
所以我們只能自己編譯安裝PHP7.3。
好消息是你看到了本文,按照步驟一步步做下去就能成功。
先為編譯安裝一些必要的依賴包:
sudo apt-get install autoconf build-essential curl libtool \
libssl-dev libcurl4-openssl-dev libxml2-dev libreadline7 \
libreadline-dev libzip-dev libzip4 nginx openssl \
pkg-config zlib1g-dev
準(zhǔn)備好編譯輸出目錄:
mkdir -p ~/bin/php7-latest/
從官網(wǎng)下載php-7.3.5.tar.gz源碼包:
wget https://www.php.net/distributions/php-7.3.5.tar.gz
解壓:
tar -xzvf php-7.3.5.tar.gz
配置編譯參數(shù):
./configure --prefix=$HOME/bin/php-latest \
--enable-mysqlnd \
--with-pdo-mysql \
--with-pdo-mysql=mysqlnd \
--enable-bcmath \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \
--enable-mbstring \
--enable-shmop \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-zip \
--with-zlib \
--with-curl \
--with-pear \
--with-openssl \
--enable-pcntl \
--with-readline \
--with-gd
注意控制臺輸出,沒有出錯(cuò)信息才算成功。
編譯:
make
注意控制臺輸出,沒有出錯(cuò)信息才算成功。
安裝:
make install
如果一切順利,所有可執(zhí)行文件都會編譯到~/bin/php7-latest/ 目錄下。
然后將php的執(zhí)行目錄加入系統(tǒng)PATH環(huán)境變量。
如果用的是bash,請編輯/.bashrc;如果是zsh,編輯/.zshrc,在文件最后加入這句:
export PATH=$HOME/bin/php-latest/bin:$HOME/bin/php-latest/sbin:$PATH
用source命令使剛才的更改生效:
source ~/.bashrc
或者
source ~/.zshrc
配置php-fpm作為系統(tǒng)服務(wù)。
這一步有很多做法,可以寫initd腳本,也可以寫systemd配置,也可以使用supervisor進(jìn)行管理。
這里提供一個(gè)可以運(yùn)行的initd腳本:
#! /bin/sh
### BEGIN INIT INFO
# Provides: php-fpm
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts php-fpm
# Description: starts the PHP FastCGI Process Manager daemon
### END INIT INFO
prefix=/home/pi/bin/php-latest
exec_prefix=${prefix}
php_fpm_BIN=${exec_prefix}/sbin/php-fpm
php_fpm_CONF=${prefix}/etc/php-fpm.conf
php_fpm_PID=${prefix}/var/run/php-fpm.pid
php_opts="--fpm-config $php_fpm_CONF --pid $php_fpm_PID"
wait_for_pid () {
try=0
while test $try -lt 35 ; do
case "$1" in
'created')
if [ -f "$2" ] ; then
try=''
break
fi
;;
'removed')
if [ ! -f "$2" ] ; then
try=''
break
fi
;;
esac
echo -n .
try=`expr $try + 1`
sleep 1
done
}
case "$1" in
start)
echo -n "Starting php-fpm "
$php_fpm_BIN --daemonize $php_opts
if [ "$?" != 0 ] ; then
echo " failed"
exit 1
fi
wait_for_pid created $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed"
exit 1
else
echo " done"
fi
;;
stop)
echo -n "Gracefully shutting down php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -QUIT `cat $php_fpm_PID`
wait_for_pid removed $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed. Use force-quit"
exit 1
else
echo " done"
fi
;;
status)
if [ ! -r $php_fpm_PID ] ; then
echo "php-fpm is stopped"
exit 0
fi
PID=`cat $php_fpm_PID`
if ps -p $PID | grep -q $PID; then
echo "php-fpm (pid $PID) is running..."
else
echo "php-fpm dead but pid file exists"
fi
;;
force-quit)
echo -n "Terminating php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -TERM `cat $php_fpm_PID`
wait_for_pid removed $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed"
exit 1
else
echo " done"
fi
;;
restart)
$0 stop
$0 start
;;
reload)
echo -n "Reload service php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -USR2 `cat $php_fpm_PID`
echo " done"
;;
configtest)
$php_fpm_BIN -t
;;
*)
echo "Usage: $0 {start|stop|force-quit|restart|reload|status|configtest}"
exit 1
;;
esac
將上面這段腳本保存為/etc/init.d/php-fpm這個(gè)文件即可。
接著運(yùn)行:
sudo systemctl enable php-fpm
安裝MySQL
先更新一下源索引,保證安裝到的是最新版:
sudo apt-get update
安裝MySQL Server:
sudo apt-get install mysql-server
開啟服務(wù)
sudo systemctl enable mysql
登入數(shù)據(jù)庫:
mysql -u root -p
修改root用戶密碼以及允許遠(yuǎn)程登入:
use mysql;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的root賬號密碼' WITH GRANT OPTION;
flush privileges;
然后就可以在別的機(jī)器上用圖形化客戶端接入這個(gè)MySQL了。
下載并安裝NextCloud Server
本文使用的是NextCloud Server 16.0.0.0
從官網(wǎng)下載壓縮包并解壓到/var/www/nextcloud 目錄下。
改一下目錄所有者,因?yàn)閚ginx默認(rèn)使用www-data用戶啟動:
sudo chown -R www-data:www-data /var/www/nextcloud/
根據(jù)官方文檔說明,使用occ命令安裝:
$ cd /var/www/nextcloud/
$ sudo -u www-data php occ maintenance:install --database
"mysql" --database-name "nextcloud" --database-user "root" --database-pass
"password" --admin-user "admin" --admin-pass "password"
Nextcloud is not installed - only a limited number of commands are available
Nextcloud was successfully installed
注意控制臺輸出,如果發(fā)現(xiàn)自己什么參數(shù)錯(cuò)了的話,建議整個(gè)目錄刪掉重新來一遍。
配置nginx使用php解析nextcloud
終于到這一步。
先刪除nginx的站點(diǎn)默認(rèn)配置:
sudo rm /etc/nginx/sites-enabled/default
然后新建一個(gè)nextcloud文件。
文件名其實(shí)隨便都可以,nginx啟動時(shí)會讀取這個(gè)目錄下的所有文件。
nextcloud配置內(nèi)容如下:
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 cloud.example.com;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.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 /etc/ssl/nginx/cloud.example.com.crt;
ssl_certificate_key /etc/ssl/nginx/cloud.example.com.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;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/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;
# 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/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
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\/.+|oc[ms]-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|oc[ms]-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;
}
}
這個(gè)配置模板是從官方文檔復(fù)制過來的,連接見本節(jié)最后。
注意將cloud.example.com替換成自己的域名或者ip地址。
ssl_certificate /etc/ssl/nginx/cloud.example.com.crt;
ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key;
這兩句指定了SSL證書存放的位置,有證書的話請自行放置并修改。
接著記得重啟下nginx:
sudo systemctl restart nginx
現(xiàn)在你應(yīng)該能從 https://ip 或者域名打開nextcloud的網(wǎng)頁版。
這個(gè)地址也是你的手機(jī)客戶端連接服務(wù)器時(shí)的地址。
更多信息請參考官網(wǎng)文檔,上面還有一個(gè)將nextcloud配置到子路徑下的模板
安裝安卓版nextcloud
這根本不值得寫,只要從官網(wǎng)下載了apk裝上就行。
啟動后選擇自建服務(wù)器,輸入之前部署在Raspberry Pi上的url地址,根據(jù)向?qū)б宦废乱徊骄托小?/p>
至此,自建NextCloud云盤終于煉成。
寫在最后
是時(shí)候來計(jì)算下運(yùn)營成本。
Raspberry Pi的功率為 5V x 2.5A = 12.5W
硬盤底座的功率為 12V x 3A = 36W
總計(jì) 48.5W
每天能耗 48.5W x 24H = 1164WH = 1.164千瓦時(shí)
如果每個(gè)字平均按0.5元算,一天電費(fèi)0.582元,一個(gè)月不到18元。
事實(shí)上實(shí)際使用起來還要低一些,畢竟不是一直滿功率運(yùn)行——事實(shí)上大多時(shí)候可能都是在空轉(zhuǎn)。
開始掌控自己的數(shù)據(jù)吧。




