Dockerfile學(xué)習(xí)And構(gòu)建Hexo鏡像

原文鏈接: http://yangbingdong.com/2017/note-of-dockefile-and-build-hexo-docker-image/

Preface

制作一個(gè)鏡像可以使用docker commit和定制Dockerfile,但推薦的是寫Dockerfile。

因?yàn)?code>docker commit是一個(gè)暗箱操作,除了制作鏡像的人知道執(zhí)行過什么命令、怎么生成的鏡像,別人根本無從得知,而且會(huì)加入一些沒用的操作導(dǎo)致鏡像臃腫

此篇記錄構(gòu)建Hexo的鏡像踩坑~

Build Images

首先在當(dāng)前空目錄創(chuàng)建一個(gè)Dockerfile:

FROM ubuntu:latest

ENV BLOG_PATH /root/blog
ENV NODE_VERSION 6

MAINTAINER yangbingdong <yangbingdong1994@gmail.com>

RUN \
    apt-get update -y && \
    apt-get install -y git curl libpng-dev && \
    curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - && \
    apt-get install -y nodejs && \
    apt-get clean && \
    apt-get autoclean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
    npm install -g hexo-cli

WORKDIR $BLOG_PATH

VOLUME ["$BLOG_PATH", "/root/.ssh"]

EXPOSE 4000

CMD ['/bin/bash']

然后在當(dāng)前目錄打開終端:

docker build -t <repo-name>/<image-name>:<tag> .

其中<repo-name>表示倉庫名,與遠(yuǎn)程倉庫(如docker hub)名字要一致,<tag>表示標(biāo)簽,不給默認(rèn)latest,都是可選項(xiàng),例如可以寫成這樣:

docker build -t <image-name> .

看到Successfully built就表示構(gòu)建成功了

注意docker build 命令最后有一個(gè) .表示構(gòu)建的上下文,鏡像構(gòu)建需要把上下文的東西上傳到Docker引擎去構(gòu)建。

Dockerfile 指令

From 指定基礎(chǔ)鏡像

所謂定制鏡像,那一定是以一個(gè)鏡像為基礎(chǔ),在其上進(jìn)行定制。而 FROM 就是指定基礎(chǔ)鏡像,因此一個(gè) DockerfileFROM 是必備的指令,并且必須是第一條指令。

Docker Hub上有非常多的高質(zhì)量的官方鏡像, 有可以直接拿來使用的服務(wù)類的鏡像,如 nginx、redis、mongo、mysql、httpdphptomcat 等; 也有一些方便開發(fā)、構(gòu)建、運(yùn)行各種語言應(yīng)用的鏡像,如 nodeopenjdk、pythonruby、golang 等。 可以在其中尋找一個(gè)最符合我們最終目標(biāo)的鏡像為基礎(chǔ)鏡像進(jìn)行定制。 如果沒有找到對(duì)應(yīng)服務(wù)的鏡像,官方鏡像中還提供了一些更為基礎(chǔ)的操作系統(tǒng)鏡像,如 ubuntu、debian、centosfedora、alpine 等,這些操作系統(tǒng)的軟件庫為我們提供了更廣闊的擴(kuò)展空間。

除了選擇現(xiàn)有鏡像為基礎(chǔ)鏡像外,Docker 還存在一個(gè)特殊的鏡像,名為 scratch。這個(gè)鏡像是虛擬的概念,并不實(shí)際存在,它表示一個(gè)空白的鏡像。

RUN 執(zhí)行命令

RUN 指令是用來執(zhí)行命令行命令的。由于命令行的強(qiáng)大能力,RUN 指令在定制鏡像時(shí)是最常用的指令之一。其格式有兩種:

  • shell 格式:RUN <命令>,就像直接在命令行中輸入的命令一樣。剛才寫的 Dockrfile 中的 RUN 指令就是這種格式。
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

  • exec 格式:RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"],這更像是函數(shù)調(diào)用中的格式。

注意

  • RUN命令盡量精簡(jiǎn),也就是像上面一樣一個(gè)RUN(使用$$ \),如果分開寫很多個(gè)RUN會(huì)導(dǎo)致鏡像鋪了很多層從而臃腫。
  • RUN最后記住清理掉沒用的垃圾,很多人初學(xué) Docker 制作出了很臃腫的鏡像的原因之一,就是忘記了每一層構(gòu)建的最后一定要清理掉無關(guān)文件。

COPY 復(fù)制文件

格式:

  • COPY <源路徑>... <目標(biāo)路徑>
  • COPY ["<源路徑1>",... "<目標(biāo)路徑>"]

RUN 指令一樣,也有兩種格式,一種類似于命令行,一種類似于函數(shù)調(diào)用。

COPY 指令將從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄復(fù)制到新的一層的鏡像內(nèi)的 <目標(biāo)路徑> 位置。比如:

COPY package.json /usr/src/app/

ADD 更高級(jí)的復(fù)制文件

ADD 指令和 COPY 的格式和性質(zhì)基本一致。但是在 COPY 基礎(chǔ)上增加了一些功能。

比如 <源路徑> 可以是一個(gè) URL,這種情況下,Docker 引擎會(huì)試圖去下載這個(gè)鏈接的文件放到 <目標(biāo)路徑> 去。下載后的文件權(quán)限自動(dòng)設(shè)置為 600,如果這并不是想要的權(quán)限,那么還需要增加額外的一層 RUN進(jìn)行權(quán)限調(diào)整,另外,如果下載的是個(gè)壓縮包,需要解壓縮,也一樣還需要額外的一層 RUN 指令進(jìn)行解壓縮。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下載,處理權(quán)限、解壓縮、然后清理無用文件更合理。因此,這個(gè)功能其實(shí)并不實(shí)用,而且不推薦使用。

如果 <源路徑> 為一個(gè) tar 壓縮文件的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,ADD 指令將會(huì)自動(dòng)解壓縮這個(gè)壓縮文件到 <目標(biāo)路徑> 去。

在某些情況下,這個(gè)自動(dòng)解壓縮的功能非常有用,比如官方鏡像 ubuntu 中:

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...

但在某些情況下,如果我們真的是希望復(fù)制個(gè)壓縮文件進(jìn)去,而不解壓縮,這時(shí)就不可以使用 ADD 命令了。

在 Docker 官方的最佳實(shí)踐文檔中要求,盡可能的使用 COPY,因?yàn)?COPY 的語義很明確,就是復(fù)制文件而已,而 ADD 則包含了更復(fù)雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場(chǎng)合,就是所提及的需要自動(dòng)解壓縮的場(chǎng)合。

另外需要注意的是,ADD 指令會(huì)令鏡像構(gòu)建緩存失效,從而可能會(huì)令鏡像構(gòu)建變得比較緩慢。

因此在 COPYADD 指令中選擇的時(shí)候,可以遵循這樣的原則,所有的文件復(fù)制均使用 COPY 指令,僅在需要自動(dòng)解壓縮的場(chǎng)合使用 ADD

CMD 容器啟動(dòng)命令

CMD 指令就是用于指定默認(rèn)的容器主進(jìn)程的啟動(dòng)命令的。

CMD 指令的格式和 RUN 相似,也是兩種格式:

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]
  • 參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數(shù)。

在運(yùn)行時(shí)可以指定新的命令來替代鏡像設(shè)置中的這個(gè)默認(rèn)命令,比如,ubuntu 鏡像默認(rèn)的 CMD/bin/bash,如果我們直接 docker run -it ubuntu 的話,會(huì)直接進(jìn)入 bash。我們也可以在運(yùn)行時(shí)指定運(yùn)行別的命令,如 docker run -it ubuntu cat /etc/os-release。這就是用 cat /etc/os-release 命令替換了默認(rèn)的 /bin/bash 命令了,輸出了系統(tǒng)版本信息。

在指令格式上,一般推薦使用 exec 格式,這類格式在解析時(shí)會(huì)被解析為 JSON 數(shù)組,因此一定要使用雙引號(hào) ",而不要使用單引號(hào)。

如果使用 shell 格式的話,實(shí)際的命令會(huì)被包裝為 sh -c 的參數(shù)的形式進(jìn)行執(zhí)行。比如:

CMD echo $HOME

在實(shí)際執(zhí)行中,會(huì)將其變更為:

CMD [ "sh", "-c", "echo $HOME" ]

所以如果使用shell格式會(huì)導(dǎo)致容器莫名退出,因?yàn)閷?shí)際上執(zhí)行的事sh命令,而sh命令執(zhí)行完時(shí)候容器也就沒有存在的意義。

ENTRYPOINT 入口點(diǎn)

ENTRYPOINT 的格式和 RUN 指令格式一樣,分為 exec 格式和 shell 格式。

ENTRYPOINT 的目的和 CMD 一樣,都是在指定容器啟動(dòng)程序及參數(shù)。ENTRYPOINT 在運(yùn)行時(shí)也可以替代,不過比 CMD 要略顯繁瑣,需要通過 docker run 的參數(shù) --entrypoint 來指定。

當(dāng)指定了 ENTRYPOINT 后,CMD 的含義就發(fā)生了改變,不再是直接的運(yùn)行其命令,而是將 CMD 的內(nèi)容作為參數(shù)傳給 ENTRYPOINT 指令,換句話說實(shí)際執(zhí)行時(shí),將變?yōu)椋?/p>

<ENTRYPOINT> "<CMD>"

這個(gè)指令非常有用,例如可以把命令后面的參數(shù)傳進(jìn)來或啟動(dòng)容器前準(zhǔn)備一些環(huán)境然后執(zhí)行啟動(dòng)命令(通過腳本exec "$@")。

ENV 設(shè)置環(huán)境變量

格式有兩種:

  • ENV <key> <value>
  • ENV <key1>=<value1> <key2>=<value2>...

這個(gè)指令很簡(jiǎn)單,就是設(shè)置環(huán)境變量而已,無論是后面的其它指令,如 RUN,還是運(yùn)行時(shí)的應(yīng)用,都可以直接使用這里定義的環(huán)境變量。

ex:

ENV NODE_VERSION 6
...
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - && \
...

ARG 構(gòu)建參數(shù)

格式:ARG <參數(shù)名>[=<默認(rèn)值>]

構(gòu)建參數(shù)和 ENV 的效果一樣,都是設(shè)置環(huán)境變量。所不同的是,ARG 所設(shè)置的構(gòu)建環(huán)境的環(huán)境變量,在將來容器運(yùn)行時(shí)是不會(huì)存在這些環(huán)境變量的。但是不要因此就使用 ARG 保存密碼之類的信息,因?yàn)?docker history 還是可以看到所有值的。

Dockerfile 中的 ARG 指令是定義參數(shù)名稱,以及定義其默認(rèn)值。該默認(rèn)值可以在構(gòu)建命令 docker build 中用 --build-arg <參數(shù)名>=<值> 來覆蓋。

在 1.13 之前的版本,要求 --build-arg 中的參數(shù)名,必須在 Dockerfile 中用 ARG 定義過了,換句話說,就是 --build-arg 指定的參數(shù),必須在 Dockerfile 中使用了。如果對(duì)應(yīng)參數(shù)沒有被使用,則會(huì)報(bào)錯(cuò)退出構(gòu)建。從 1.13 開始,這種嚴(yán)格的限制被放開,不再報(bào)錯(cuò)退出,而是顯示警告信息,并繼續(xù)構(gòu)建。這對(duì)于使用 CI 系統(tǒng),用同樣的構(gòu)建流程構(gòu)建不同的 Dockerfile 的時(shí)候比較有幫助,避免構(gòu)建命令必須根據(jù)每個(gè) Dockerfile 的內(nèi)容修改。

VOLUME 定義匿名卷

格式為:

  • VOLUME ["<路徑1>", "<路徑2>"...]
  • VOLUME <路徑>

之前我們說過,容器運(yùn)行時(shí)應(yīng)該盡量保持容器存儲(chǔ)層不發(fā)生寫操作,對(duì)于數(shù)據(jù)庫類需要保存動(dòng)態(tài)數(shù)據(jù)的應(yīng)用,其數(shù)據(jù)庫文件應(yīng)該保存于卷(volume)中,后面的章節(jié)我們會(huì)進(jìn)一步介紹 Docker 卷的概念。為了防止運(yùn)行時(shí)用戶忘記將動(dòng)態(tài)文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運(yùn)行時(shí)如果用戶不指定掛載,其應(yīng)用也可以正常運(yùn)行,不會(huì)向容器存儲(chǔ)層寫入大量數(shù)據(jù)。

VOLUME /data

這里的 /data 目錄就會(huì)在運(yùn)行時(shí)自動(dòng)掛載為匿名卷,任何向 /data 中寫入的信息都不會(huì)記錄進(jìn)容器存儲(chǔ)層,從而保證了容器存儲(chǔ)層的無狀態(tài)化。當(dāng)然,運(yùn)行時(shí)可以覆蓋這個(gè)掛載設(shè)置。比如:

docker run -d -v mydata:/data xxxx

在這行命令中,就使用了 mydata 這個(gè)命名卷掛載到了 /data 這個(gè)位置,替代了 Dockerfile 中定義的匿名卷的掛載配置。

EXPOSE 聲明端口

格式為 EXPOSE <端口1> [<端口2>...]。
EXPOSE 指令是聲明運(yùn)行時(shí)容器提供服務(wù)端口,這只是一個(gè)聲明,在運(yùn)行時(shí)并不會(huì)因?yàn)檫@個(gè)聲明應(yīng)用就會(huì)開啟這個(gè)端口的服務(wù)。在 Dockerfile 中寫入這樣的聲明有兩個(gè)好處,一個(gè)是幫助鏡像使用者理解這個(gè)鏡像服務(wù)的守護(hù)端口,以方便配置映射;另一個(gè)用處則是在運(yùn)行時(shí)使用隨機(jī)端口映射時(shí),也就是 docker run -P時(shí),會(huì)自動(dòng)隨機(jī)映射 EXPOSE 的端口。

此外,在早期 Docker 版本中還有一個(gè)特殊的用處。以前所有容器都運(yùn)行于默認(rèn)橋接網(wǎng)絡(luò)中,因此所有容器互相之間都可以直接訪問,這樣存在一定的安全性問題。于是有了一個(gè) Docker 引擎參數(shù) --icc=false,當(dāng)指定該參數(shù)后,容器間將默認(rèn)無法互訪,除非互相間使用了 --links 參數(shù)的容器才可以互通,并且只有鏡像中 EXPOSE 所聲明的端口才可以被訪問。這個(gè) --icc=false 的用法,在引入了 docker network后已經(jīng)基本不用了,通過自定義網(wǎng)絡(luò)可以很輕松的實(shí)現(xiàn)容器間的互聯(lián)與隔離。

要將 EXPOSE 和在運(yùn)行時(shí)使用 -p <宿主端口>:<容器端口> 區(qū)分開來。-p,是映射宿主端口和容器端口,換句話說,就是將容器的對(duì)應(yīng)端口服務(wù)公開給外界訪問,而 EXPOSE 僅僅是聲明容器打算使用什么端口而已,并不會(huì)自動(dòng)在宿主進(jìn)行端口映射。

WORKDIR 指定工作目錄

格式為 WORKDIR <工作目錄路徑>。
使用 WORKDIR 指令可以來指定工作目錄(或者稱為當(dāng)前目錄),以后各層的當(dāng)前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR 會(huì)幫你建立目錄。

之前提到一些初學(xué)者常犯的錯(cuò)誤是把 Dockerfile 等同于 Shell 腳本來書寫,這種錯(cuò)誤的理解還可能會(huì)導(dǎo)致出現(xiàn)下面這樣的錯(cuò)誤:

RUN cd /app
RUN echo "hello" > world.txt

如果將這個(gè) Dockerfile 進(jìn)行構(gòu)建鏡像運(yùn)行后,會(huì)發(fā)現(xiàn)找不到 /app/world.txt 文件,或者其內(nèi)容不是 hello。原因其實(shí)很簡(jiǎn)單,在 Shell 中,連續(xù)兩行是同一個(gè)進(jìn)程執(zhí)行環(huán)境,因此前一個(gè)命令修改的內(nèi)存狀態(tài),會(huì)直接影響后一個(gè)命令;而在 Dockerfile 中,這兩行 RUN 命令的執(zhí)行環(huán)境根本不同,是兩個(gè)完全不同的容器。這就是對(duì) Dokerfile 構(gòu)建分層存儲(chǔ)的概念不了解所導(dǎo)致的錯(cuò)誤。

之前說過每一個(gè) RUN 都是啟動(dòng)一個(gè)容器、執(zhí)行命令、然后提交存儲(chǔ)層文件變更。第一層 RUN cd /app 的執(zhí)行僅僅是當(dāng)前進(jìn)程的工作目錄變更,一個(gè)內(nèi)存上的變化而已,其結(jié)果不會(huì)造成任何文件變更。而到第二層的時(shí)候,啟動(dòng)的是一個(gè)全新的容器,跟第一層的容器更完全沒關(guān)系,自然不可能繼承前一層構(gòu)建過程中的內(nèi)存變化。

因此如果需要改變以后各層的工作目錄的位置,那么應(yīng)該使用 WORKDIR 指令。

USER 指定當(dāng)前用戶

格式:USER <用戶名>

USER 指令和 WORKDIR 相似,都是改變環(huán)境狀態(tài)并影響以后的層。WORKDIR 是改變工作目錄,USER則是改變之后層的執(zhí)行 RUN, CMD 以及 ENTRYPOINT 這類命令的身份。

當(dāng)然,和 WORKDIR 一樣,USER 只是幫助你切換到指定用戶而已,這個(gè)用戶必須是事先建立好的,否則無法切換。

RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]

踩坑

  • Dockerfile里也需要注意權(quán)限問題(nodejs7版本以上不能正常安裝hexo,需要?jiǎng)?chuàng)建用戶并制定權(quán)限去安裝)
  • 在docker容器里如果是root用戶對(duì)掛載的文件進(jìn)行了操作,那么實(shí)際上掛載文件的權(quán)限也變成了root的
  • 使用attach進(jìn)入容器,退出的時(shí)候容器也跟著退出了。。。囧
  • 每一個(gè)RUN是一個(gè)新的shell
  • su -之前在啟動(dòng)腳本加了-,導(dǎo)致環(huán)境變量以及工作目錄都變了

Hexo-Docker

最后獻(xiàn)上踩坑寫的Hexo Dockerfile:

# 使用Ubuntu官方鏡像
FROM ubuntu:latest

# 作者信息
MAINTAINER yangbingdong <yangbingdong1994@gmail.com>

# 設(shè)置環(huán)境變量,使用${變量名}取值
ENV \
    USER_NAME=hexo \
    NODE_VERSION=8.5.0 \
    NODE_DIR=/home/${USER_NAME}/nodejs

# 需要執(zhí)行的命令,使用 `$$ \` 分割多行多個(gè)命令
RUN \
    # 安裝基本的依賴以及工具
    apt-get update -y && \
    apt-get upgrade -y && \
    apt-get install -y git && \
    apt-get install -y curl && \
    apt-get install -y libpng-dev && \
    # 清理不必要的垃圾
    apt-get clean && \
    apt-get autoclean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
    # 創(chuàng)建hexo用戶去安裝hexo
    useradd -m -U ${USER_NAME} && \
    # 創(chuàng)建nodejs目錄
    mkdir ${NODE_DIR} && \
    # 將nodejs下載解壓到對(duì)應(yīng)目錄
    curl -L https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz | tar xvzf - -C ${NODE_DIR} --strip-components=1 && \
    # 把nodejs文件賦權(quán)給hexo用戶
    chown -R ${USER_NAME}.${USER_NAME} ${NODE_DIR} && \
    # 把node相關(guān)命令軟連接到/usr/local/bin目錄下以便我們使用
    ln -s ${NODE_DIR}/bin/node /usr/local/bin/node && \
    ln -s ${NODE_DIR}/bin/npm /usr/local/bin/npm && \
    # 以hexo用戶身份安裝hexo-cli
    su - ${USER_NAME} -c "npm install -g hexo-cli" && \
    # 同樣把hexo命令放到/usr/local/bin下
    ln -s ${NODE_DIR}/bin/hexo /usr/local/bin/hexo && \
    # 使用淘寶鏡像
    npm config set registry https://registry.npm.taobao.org/

# 切換到此目錄
WORKDIR /home/${USER_NAME}/blog

# 可以掛載進(jìn)來的卷(文件夾)
VOLUME ["/home/${USER_NAME}/blog", "/home/${USER_NAME}/.ssh"]

# 暴露端口
EXPOSE 4000

# 把上下文中的docker-entrypoint.sh復(fù)制進(jìn)來
COPY docker-entrypoint.sh /docker-entrypoint.sh

# 執(zhí)行腳本
ENTRYPOINT ["/docker-entrypoint.sh"]

# 這個(gè)...雞肋操作
CMD ['/bin/bash']

docker-entrypoint.sh :

#!/bin/sh

# 發(fā)生異?;貪L
set -e

# 設(shè)置git相關(guān)信息,不設(shè)置默認(rèn)為博主的=.=
GIT_USER_NAME=${GIT_USER_NAME:-yangbingdong}

GIT_USER_MAIL=${GIT_USER_MAIL:-yangbingdong1994@gmail.com}

# 你想要的用戶名
NEW_USER_NAME=${NEW_USER_NAME:-ybd}

# 由于每次啟動(dòng)容器都會(huì)執(zhí)行這個(gè)腳本,但這個(gè)只需要執(zhí)行一次,在此標(biāo)志一下
if [ $(git config --system user.name)x = ${GIT_USER_NAME}x ]
then
    su ${NEW_USER_NAME}
else
    # 修改用戶名
    /usr/sbin/usermod -l ${NEW_USER_NAME} ${USER_NAME}

    /usr/sbin/usermod -c ${NEW_USER_NAME} ${NEW_USER_NAME}

    /usr/sbin/groupmod -n ${NEW_USER_NAME} ${USER_NAME}

    chown -R ${NEW_USER_NAME}.${NEW_USER_NAME} /home/${USER_NAME}/blog

    chmod -R 766 /home/${USER_NAME}/blog
    
    # 設(shè)置git全局信息
    git config --system user.name $GIT_USER_NAME

    git config --system user.email $GIT_USER_MAIL

    su ${NEW_USER_NAME}
fi

# 執(zhí)行腳本之后的命令
exec "$@"

源碼:https://github.com/masteranthoneyd/docker-hexo

Last

參考:Docker從入門到實(shí)踐

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,514評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,373評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,743評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,199評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,414評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,951評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,780評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,218評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,673評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自 http://blog.opskumu.com/docker.html 一、Docker 簡(jiǎn)介 Docke...
    極客圈閱讀 10,520評(píng)論 0 120
  • Docker — 云時(shí)代的程序分發(fā)方式 要說最近一年云計(jì)算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,562評(píng)論 15 147
  • docker基本概念 1. Image Definition 鏡像 Image 就是一堆只讀層 read-only...
    慢清塵閱讀 8,789評(píng)論 1 21
  • 一、前言 最近在做直播(監(jiān)控類)的項(xiàng)目,剛開始一竅不通,各種難啊,沒辦法,總得做啊,于是就查資料,一步一步,最后總...
    溫暖C閱讀 14,644評(píng)論 28 21
  • 由于昨天晚上睡覺實(shí)在太晚,今天早早的就犯困了,捧著書本卻一直打瞌睡,一行行文字都成了催眠符,整個(gè)人困乏的不行。...
    鄰國(guó)宰相閱讀 334評(píng)論 0 2