前言
本來(lái)之前一直在簡(jiǎn)書平臺(tái)上記錄心得辱挥,但好友給我看了自己搭的Ghost博客舔箭,著實(shí)漂亮熊痴,恰逢計(jì)網(wǎng)附加作業(yè)是搭建一個(gè)個(gè)人網(wǎng)站,就有了趁這次機(jī)會(huì)搭一個(gè)博客并把部分文章遷移過(guò)去的想法
選擇Ghost咪橙,一是因?yàn)樽约褐按罱?維護(hù)的網(wǎng)頁(yè)基本都是php夕膀,后來(lái)又接觸了python的網(wǎng)絡(luò)編程,想試試新東西——Ghost博客是基于node.js的框架美侦,正好如我所愿产舞;二是因?yàn)檎娴耐ζ痢?/p>
而選擇Docker搭建的原因則比較現(xiàn)實(shí)了:我的學(xué)生服務(wù)器上還維護(hù)著幾個(gè)其他項(xiàng)目,擔(dān)心亂搞會(huì)搞崩原本的環(huán)境菠剩。雖然Ghost官方提供了現(xiàn)成的鏡像可以一鍵部署易猫,但是抱著學(xué)習(xí)的心態(tài),還是選擇了自己開一個(gè)ubuntu16.04的容器手動(dòng)搭建具壮。官方文檔其實(shí)已經(jīng)有非常詳細(xì)的步驟准颓,但是自己作死踩了不少坑,故作此記錄
準(zhǔn)備
下面是官方文檔中提出的要求事實(shí)上看到第五項(xiàng)我就應(yīng)該反應(yīng)過(guò)來(lái)預(yù)想中的搭建方式肯定會(huì)出問(wèn)題
- Ubuntu 16.04 or Ubuntu 18.04
- NGINX (minimum of 1.9.5 for SSL)
- A supported version of Node.js
- MySQL 5.5, 5.6, or 5.7 (not >= 8.0)
- Systemd
- A server with at least 1GB memory
- A registered domain name
環(huán)境搭建
-
容器啟動(dòng)
為了日后維護(hù)方便用-p選項(xiàng)開了三個(gè)端口棺妓,其中2368是Ghost默認(rèn)的端口攘已。這里其實(shí)沒有必要對(duì)此進(jìn)行映射,映射后搭建完成后還是得開個(gè)反向代理監(jiān)聽2368怜跑,否則博客里許多地方都是默認(rèn)跳轉(zhuǎn)到localhost:2368的orz
-it則是啟動(dòng)交互模式样勃, -v設(shè)置共享文件夾docker run -it -v /docker:/docker -p 8168:2368 -p 8122:22 -p 8100:80 --privileged=true --name=m_ghost daocloud.io/library/ubuntu:latest /bin/bash
-
初步環(huán)境配置
由于容器是輕量化的虛擬技術(shù),原本的設(shè)計(jì)意圖是一個(gè)容器只運(yùn)行一個(gè)應(yīng)用,我們將其作為輕量虛擬機(jī)使用時(shí)需要手動(dòng)安裝很多ubuntu發(fā)行版已經(jīng)自帶的功能
其中要提一下ssh峡眶,安裝好后需要apt-get update apt-get upgrade apt-get install sudo apt-get install vim apt-get install openssh-server #安裝ssh
sudo vim /etc/sshd_config
打開配置文件剧防,并將PermitRootLogin
一項(xiàng)前的注釋去掉,把后面的參數(shù)改為yes
辫樱,再service sshd start
啟動(dòng)服務(wù) -
創(chuàng)建新用戶
Ghost博客出于安全考慮诵姜,不允許使用root用戶安裝,故此步是必需的adduser eva #eva是我設(shè)置的用戶名搏熄,可在命名規(guī)則內(nèi)隨意更換 usermod -aG sudo eva #添加到sudo用戶組 su eva #切換至該用戶,后面步驟全部使用該用戶進(jìn)行
-
安裝nginx
sudo apt-get install nginx
-
安裝mysql
sudo apt-get install mysql-server
-
安裝Node.js
此處需要注意安裝對(duì)應(yīng)版本的node.js暇赤,Ghost支持的版本一般會(huì)比最新版本晚一代心例,可以在官網(wǎng)查詢curl -sL 'https://deb.nodesource.com/setup_10.x' | sudo -E bash #去掉引號(hào)再使用 sudo apt-get install -y nodejs
安裝Ghost
在新版本中我們得以使用官方安裝工具Ghost-CLI來(lái)進(jìn)行安裝,免去了自己下載包鞋囊、自己改配置文件的繁瑣步驟當(dāng)然也有會(huì)卡住的Bug
-
安裝Ghost-CLI
sudo npm install ghost-cli@latest -g
之后可以使用
ghost help
來(lái)獲得幫助止后,并可以在flags and options查詢更多選項(xiàng)與指令以個(gè)性化安裝 -
創(chuàng)建Ghost安裝目錄
注意現(xiàn)在你不是root用戶,在/root或/home下安裝極有可能出錯(cuò)
sudo mkdir -p /var/www/ghost #-p選項(xiàng)是為了確保有這個(gè)文件夾溜腐,沒有則創(chuàng)建 sudo chown eva:eva /var/www/ghost #改變文件夾所屬用戶與用戶組 sudo chmod 775 /var/www/ghost cd ghost #下一步操作也在ghost文件夾下進(jìn)行
-
安裝Ghost
ghost install
這里有可能會(huì)卡在 Downloading and installing Ghost 這里译株,如果是卡在 Downloading 或者 Fetching packages,那就是服務(wù)器網(wǎng)不好挺益,等待它自己重試即可歉糜;如果卡在 Building fresh packages 長(zhǎng)達(dá)二十分鐘多,那就是安裝卡住了望众,需要按Ctrl+C退出安裝匪补,然后執(zhí)行
ghost uninstall cd.. sudo rm -rf ghost
然后從創(chuàng)建文件夾那一步重新開始按流程做
如果安裝正常進(jìn)行的話,就會(huì)讓你自定義一些信息烂翰。Enter your blog URL: (http://localhost:2368) Enter your MySQL hostname: (localhost) Enter your MySQL username: Enter your MySQL password: Enter your Ghost database name: Do you wish to set up "ghost" mysql user? Do you wish to set up Nginx? Do you wish to set up SSL? Set up Systemd?
到這里都是按官網(wǎng)文檔安裝即可夯缺,基本上懶得設(shè)置的話一路默認(rèn)下去,如果是正常安裝的話到這里基本就沒啥事了甘耿,安裝完后登錄url就能看到頁(yè)面了踊兜,阿里云服務(wù)器的話別忘了到控制臺(tái)安全組開放端口就行
但是標(biāo)題都是折騰向了怎么可能平安無(wú)事呢(笑
踩坑:Systemd
在剛剛的Set up Systemd?
那一步時(shí),我按照官網(wǎng)的推薦選了yes佳恬,然后就喜聞樂(lè)見的報(bào)錯(cuò)退出了
結(jié)合之前的項(xiàng)目經(jīng)歷捏境,一股不詳?shù)念A(yù)感油然而生
-
Systemd是什么?
Systemd是一個(gè)系統(tǒng)管理守護(hù)進(jìn)程毁葱、工具和庫(kù)的集合典蝌,用于取代System V初始進(jìn)程。Systemd的功能是用于集中管理和配置類UNIX系統(tǒng)头谜。
Systemd 的核心是一個(gè)叫單元unit的概念骏掀,它是一些存有關(guān)于服務(wù)service(在運(yùn)行在后臺(tái)的程序)、設(shè)備、掛載點(diǎn)截驮、和操作系統(tǒng)其他方面信息的配置文件笑陈。Systemd 的其中一個(gè)目標(biāo)就是簡(jiǎn)化這些事物之間的相互作用,因此如果你有程序需要在某個(gè)掛載點(diǎn)被創(chuàng)建或某個(gè)設(shè)備被接入后開始運(yùn)行葵袭,Systemd 可以讓這一切正常運(yùn)作起來(lái)變得相當(dāng)容易涵妥。(在沒有 Systemd 的日子里,要使用腳本來(lái)把這些事情調(diào)配好坡锡,那可是相當(dāng)丑陋的蓬网。)簡(jiǎn)單來(lái)說(shuō)就是一個(gè)啟動(dòng)系統(tǒng)的時(shí)候用于管理各種服務(wù)的進(jìn)程。在還沒有systemd的時(shí)候鹉勒,內(nèi)核會(huì)去運(yùn)行
/sbin/init
帆锋,隨后這個(gè)程序會(huì)在名為 SysVinit 的系統(tǒng)中運(yùn)行其余的各種啟動(dòng)腳本。現(xiàn)在Systemd則取而代之成為了第一個(gè)執(zhí)行的進(jìn)程禽额,理所當(dāng)然的锯厢,她的PID為1 -
為什么會(huì)報(bào)錯(cuò):容器與虛擬機(jī)的區(qū)別
如上所述,我們來(lái)查看一下當(dāng)前容器內(nèi)的第一個(gè)進(jìn)程是什么
sudo ps -p 1
然后發(fā)現(xiàn)PID為1的進(jìn)程是
/bin/bash
脯倒!為什么會(huì)這樣呢实辑?
要搞清楚原因,先得重新回顧一下Docker的設(shè)計(jì)意圖與特點(diǎn)Docker最早是使用一種被稱為L(zhǎng)XC的容器技術(shù)藻丢,后來(lái)改用runC剪撬,另一方面,Docker的最大特色之一是被稱為AuFS的分層文件系統(tǒng)悠反。每一個(gè)鏡像都會(huì)先創(chuàng)建一個(gè)只讀的文件層婿奔,而每一個(gè)基于其的容器則不斷往上添加新的文件層,每層存儲(chǔ)的是其與鏡像所不同的地方问慎。
該特性使得容器非常的輕量萍摊,甚至允許上千個(gè)基于同一鏡像的容器共享區(qū)區(qū)1Gb的空間,這是傳統(tǒng)VM不可能做到的如叼。
Docker沒有傳統(tǒng)意義上的內(nèi)核冰木,其虛擬化并不像傳統(tǒng)虛擬機(jī)一樣使用數(shù)套不同的硬件驅(qū)動(dòng)、初始化進(jìn)程笼恰、加載模塊等踊沸,更很少像虛擬機(jī)一樣各自擁有一整套系統(tǒng)資源,而是通過(guò)“命名空間”的技術(shù)隔離進(jìn)程社证。一般地逼龟,容器和宿主系統(tǒng)共用同一套內(nèi)核。因此追葡,容器在輕量化的同時(shí)腺律,也導(dǎo)致了其隔離性的缺乏
比起一個(gè)虛擬機(jī)奕短,Docker的概念其實(shí)更接近于一般講的進(jìn)程沙箱,例如OJ里常用來(lái)防止提交的代碼危害系統(tǒng)安全的那種匀钧。雖然用起來(lái)和輕量化的虛擬機(jī)無(wú)異翎碑,但是和虛擬機(jī)還是有著巨大的不同,其設(shè)計(jì)意圖也不是想在每一個(gè)容器內(nèi)跑一個(gè)完整的系統(tǒng)之斯,而是在每一個(gè)容器內(nèi)跑一個(gè)單獨(dú)的進(jìn)程/應(yīng)用日杈,使得其在批量化測(cè)試、快速部署/遷移等場(chǎng)合有著亮眼的表現(xiàn)佑刷。像我過(guò)去一樣把docker當(dāng)成虛擬機(jī)一樣使用莉擒、在每個(gè)容器里部署一套笨重的LNMP無(wú)疑是越俎代庖的行為
這也解釋了為什么會(huì)報(bào)錯(cuò):我啟動(dòng)的容器并沒有、也不需要systemd這種用來(lái)在啟動(dòng)時(shí)管理加載過(guò)程的進(jìn)程瘫絮,在她眼里涨冀,自己的存在只是為了運(yùn)行run命令時(shí)輸入的/bin/bash
而已。
關(guān)于這塊更多的知識(shí)檀何,可以參考StackOverflow的這個(gè)回答-
如何解決
1.在本不存在SystemD的系統(tǒng)里模擬一個(gè)能執(zhí)行systemctl的腳本
有一個(gè)優(yōu)秀的項(xiàng)目叫docker-systemctl-replacement,通過(guò)重寫/bin/systemctl
使得進(jìn)程能在沒有systemd的情況下使用systemctl啟動(dòng)和停止服務(wù)
具體用法舉例如下
wget https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl.py -O /usr/local/bin/systemctl
然而我們并不是需要systemctl命令來(lái)管理服務(wù)廷支,而是Ghost框架需要依賴SystemD本身频鉴,所以根本沒用
2.在啟動(dòng)容器時(shí)將
/sbin/int
作為啟動(dòng)命令,并使用privileged=true
來(lái)賦予其訪問(wèn)宿主系統(tǒng)內(nèi)核的權(quán)限例如
docker run -d -v /docker:/docker -p 8168:2368 -p 8122:22 -p 8100:80 --privileged=true --name=m_ghost daocloud.io/library/ubuntu:latest /sbin/init
然而依舊報(bào)錯(cuò)恋拍,鏡像里根本就沒有/sbin/init......
但是沒有關(guān)西垛孔!我在這之前把自己配好的環(huán)境commit成了一個(gè)鏡像,那個(gè)鏡像是可以成功啟動(dòng)的施敢,而且pid1也是/sbin/init
但是那個(gè)容器里面的mysql壞掉了....出現(xiàn)了如下報(bào)錯(cuò)Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
而且網(wǎng)上對(duì)此的解決方案都毫無(wú)用處....
3.使用官方鏡像
老實(shí)說(shuō)這樣根本就沒有解決問(wèn)題嘛....有時(shí)間去研究下它的Dockerfile好了
順帶一提直接用其Dockerfile來(lái)build鏡像會(huì)出問(wèn)題周荐,意義不明 -
At Last
最后我還是使用了官方鏡像....
具體操作如下
docker pull ghost
docker run -d -v /docker:/docker -p 8168:2368 -p 8122:22 -p 8100:80 --name=m_ghost ghost
# 注意最后不用跟任何命令
唔然后就搭起來(lái)啦...接下來(lái)的事情就只有進(jìn)入我的博客主頁(yè)然后按說(shuō)明慢慢配置各項(xiàng)主題、設(shè)計(jì)等等了
暫時(shí)沒有域名so配置代理僵娃、配置SSL證書啥的都先擱置了概作,有需要的可以參考這里
結(jié)果最后也沒有解決systemd和mysql的問(wèn)題....是時(shí)候好好讀一讀操作系統(tǒng)原理了XD