Docker 容器編排利器 Docker Compose

Docker 容器編排利器 Docker Compose

一论寨、Docker Compose 簡(jiǎn)介

Docker Compose 項(xiàng)目是 Docker 官方的開源項(xiàng)目砾嫉,Compose 定位是 「定義和運(yùn)行多個(gè) Docker 容器的應(yīng)用(Defining and running multi-container Docker applications)」,來源于之前的 Fig 項(xiàng)目陋守,使用 Python 語言編寫础倍。負(fù)責(zé)實(shí)現(xiàn)對(duì) Docker 容器集群的快速編排亡嫌。項(xiàng)目地址為:https://github.com/docker/compose/releases

Compose 的默認(rèn)管理對(duì)象是項(xiàng)目运沦,通過子命令對(duì)項(xiàng)目中的一組容器進(jìn)行便捷地生命周期管理,實(shí)現(xiàn)上調(diào)用了 Docker 服務(wù)提供的 API 來對(duì)容器進(jìn)行管理涮母。因此谆趾,只要所操作的平臺(tái)支持 Docker API,就可以在其上利用 Compose 來進(jìn)行編排管理叛本。

我們知道使用一個(gè) Dockerfile 模板文件沪蓬,可以讓用戶很方便的定義一個(gè)單獨(dú)的應(yīng)用容器。然而炮赦,在日常工作中怜跑,經(jīng)常會(huì)碰到需要多個(gè)容器相互配合來完成某項(xiàng)任務(wù)的情況。例如要實(shí)現(xiàn)一個(gè) Web 項(xiàng)目吠勘,除了 Web 服務(wù)容器本身性芬,往往還需要再加上后端的負(fù)載均衡容器等。

Docker Compose 恰好滿足了這樣的需求剧防,它是用于定義和運(yùn)行多容器 Docker 應(yīng)用程序的工具植锉。它允許用戶通過一個(gè)單獨(dú)的 docker-compose.yml 模板文件(YAML 格式)來定義一組相關(guān)聯(lián)的應(yīng)用容器為一個(gè)項(xiàng)目(project)。然后使用一個(gè)命令峭拘,就可以通過 YAML 配置文件創(chuàng)建并啟動(dòng)所有服務(wù)俊庇。

Compose 中有兩個(gè)重要的概念:

  • 服務(wù) (service):一個(gè)應(yīng)用的容器,實(shí)際上可以包括若干運(yùn)行相同鏡像的容器實(shí)例鸡挠。
  • 項(xiàng)目 (project):由一組關(guān)聯(lián)的應(yīng)用容器組成的一個(gè)完整業(yè)務(wù)單元辉饱,在 docker-compose.yml 文件中定義。

Docker Compose 使用的三個(gè)步驟為:

  • 使用 Dockerfile 文件定義應(yīng)用程序的環(huán)境拣展;
  • 使用 docker-compose.yml 文件定義構(gòu)成應(yīng)用程序的服務(wù)彭沼,這樣它們可以在隔離環(huán)境中一起運(yùn)行;
  • 最后备埃,執(zhí)行 docker-compose up 命令來創(chuàng)建并啟動(dòng)所有服務(wù)姓惑。

二、Docker Compose 安裝

官方文檔:https://docs.docker.com/compose/install/linux/

2.1 Mac按脚、Windows 平臺(tái)默認(rèn)支持

Docker Desktop for Mac/Windows 自帶 docker-compose 二進(jìn)制文件于毙,安裝 Docker 之后可以直接使用。

$ docker-compose --version
Docker Compose version v2.23.3-desktop.2

2.2 Linux 安裝(通過包管理)

2.2.1 安裝

運(yùn)行以下命令以下載Docker Compose的當(dāng)前穩(wěn)定版本:

# 烏班圖 安裝
sudo apt-get install docker-compose-plugin -y
# Centos 安裝
sudo yum install docker-compose-plugin -y 

2.2.2 測(cè)試

docker compose version

2.2.3 卸載

如果您需要卸載 Docker Compose辅搬,可以使用以下命令:

在 Ubuntu 上:

sudo apt-get remove docker-compose-plugin -y

在 CentOS 上:

sudo yum remove docker-compose-plugin -y

2.3 使用PIP 安裝與卸載

2.3.1 PIP安裝

這種方式是將 Compose 當(dāng)作一個(gè) Python 應(yīng)用來從 pip 源中安裝唯沮。

首先,確保你的系統(tǒng)已經(jīng)安裝了Python和pip。你可以在終端中運(yùn)行以下命令來檢查它們是否已經(jīng)安裝:

python --version
pip --version

如果這些命令返回版本信息介蛉,則說明Python和pip已經(jīng)安裝夯缺。如果沒有安裝,請(qǐng)根據(jù)你使用的操作系統(tǒng)安裝Python和pip甘耿。

沒有安裝的話請(qǐng)參考教程:Linux系統(tǒng)安裝python3.8與卸載教程

接下來,使用pip安裝docker-compose竿滨。在終端中運(yùn)行以下命令:

$ sudo pip install -U docker-compose

2.3.2 PIP 卸載

如果是通過 pip 安裝的佳恬,則執(zhí)行如下命令即可刪除。

$ sudo pip uninstall docker-compose

三于游、基本使用

3.1 術(shù)語

首先介紹幾個(gè)術(shù)語毁葱。

  • 服務(wù) (service):一個(gè)應(yīng)用容器,實(shí)際上可以運(yùn)行多個(gè)相同鏡像的實(shí)例贰剥。
  • 項(xiàng)目 (project):由一組關(guān)聯(lián)的應(yīng)用容器組成的一個(gè)完整業(yè)務(wù)單元倾剿。

可見,一個(gè)項(xiàng)目可以由多個(gè)服務(wù)(容器)關(guān)聯(lián)而成蚌成,Compose 面向項(xiàng)目進(jìn)行管理前痘。

3.2 部署Flask 應(yīng)用

下面我們部署一個(gè)web 網(wǎng)站,該項(xiàng)目應(yīng)該包含 web 應(yīng)用和緩存担忧。

我們用Flask 框架構(gòu)建一個(gè)能夠記錄頁面訪問次數(shù)的 web 網(wǎng)站芹缔。

首先,創(chuàng)建一個(gè)簡(jiǎn)單的 Flask 應(yīng)用瓶盛。創(chuàng)建一個(gè)新目錄 flask-app最欠,并在其中創(chuàng)建一個(gè)名為 app.py 的文件:

# flask-app/app.py
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    visits = redis.incr('counter')
    return 'Hello World! I have been seen {} times.\n'.format(visits)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

接著,編寫 Dockerfile 文件,內(nèi)容為:

FROM python:3.12-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]

編寫 docker-compose.yml 文件惩猫,這個(gè)是 Compose 使用的主模板文件芝硬。

version: '3.0'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

這個(gè) docker-compose.yml 文件定義了兩個(gè)服務(wù):webredisweb 服務(wù)使用當(dāng)前目錄下的 Dockerfile 構(gòu)建轧房,并將容器內(nèi)的端口 5000 綁定到宿主機(jī)的端口 5000拌阴。web 服務(wù)依賴于 redis 服務(wù)。

flask-app 目錄中锯厢,運(yùn)行以下命令來啟動(dòng)應(yīng)用:

docker compose up --build

這個(gè)命令會(huì)構(gòu)建 Flask 應(yīng)用的 Docker 鏡像皮官,啟動(dòng) Redis 容器,然后啟動(dòng) Flask 應(yīng)用容器实辑〗劣酰看到終端輸出如下,說明容器啟動(dòng)起來了胡岔。

現(xiàn)在漓穿,您可以通過瀏覽器訪問 http://localhost:5000 來查看您的 Flask 應(yīng)用,并且每次刷新頁面都會(huì)看到訪問次數(shù)的增加。

或者終端使用 curl 命令訪問本地運(yùn)行的 Flask 應(yīng)用

curl http://localhost:5000

如圖馍佑,此時(shí)訪問本地 5000 端口斋否,每次刷新頁面,計(jì)數(shù)就會(huì)加 1拭荤。

四茵臭、Compose 常用命令

4.1 命令對(duì)象與格式

docker compose 命令的基本的使用格式是

docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]

部分命令選項(xiàng)如下:

  • -f,--file:指定使用的 Compose 模板文件舅世,默認(rèn)為 docker-compose.yml旦委,可以多次指定,指定多個(gè) yml雏亚;
  • -p, --project-name:指定工程名稱缨硝,默認(rèn)使用 docker-compose.yml 文件所在目錄的名稱;
  • -v:打印版本并退出罢低;
  • --log-level:定義日志等級(jí)(DEBUG, INFO, WARNING, ERROR, CRITICAL)查辩。

我們通過終端輸入命令docker compose可以查看到所有命令和選項(xiàng):

用法:  docker compose [選項(xiàng)] 命令

使用 Docker 定義和運(yùn)行多容器應(yīng)用程序

選項(xiàng):
      --ansi string                控制何時(shí)打印 ANSI 控制字符 ("never"|"always"|"auto")
                                   (默認(rèn) "auto")
      --compatibility              以向后兼容模式運(yùn)行 Compose
      --dry-run                    以干運(yùn)行模式執(zhí)行命令
      --env-file stringArray       指定一個(gè)替代的環(huán)境文件
  -f, --file stringArray           指定 Compose 配置文件
      --parallel int               控制最大并行性,-1 為無限制 (默認(rèn) -1)
      --profile stringArray         指定要啟用的配置文件
      --progress string             設(shè)置進(jìn)度輸出的類型 (auto, tty, plain, quiet) (默認(rèn) "auto")
      --project-directory string   指定一個(gè)替代的工作目錄
                                   (默認(rèn):第一個(gè)指定的 Compose 文件的路徑)
  -p, --project-name string        項(xiàng)目名稱

命令:
  attach      將本地標(biāo)準(zhǔn)輸入网持、輸出和錯(cuò)誤流附加到服務(wù)的運(yùn)行容器上
  build       構(gòu)建或重建服務(wù)
  config      解析宜岛、解析并呈現(xiàn) Compose 文件的規(guī)范格式
  cp          在服務(wù)容器和本地文件系統(tǒng)之間復(fù)制文件/文件夾
  create      為服務(wù)創(chuàng)建容器
  down        停止并刪除容器和網(wǎng)絡(luò)
  events      從容器接收實(shí)時(shí)事件
  exec        在運(yùn)行中的容器內(nèi)執(zhí)行命令
  images      列出由創(chuàng)建的容器使用的鏡像
  kill        強(qiáng)制停止服務(wù)容器
  logs        查看容器的輸出
  ls          列出運(yùn)行中的 Compose 項(xiàng)目
  pause      暫停服務(wù)
  port        打印端口的公共端口綁定
  ps          列出容器
  pull        拉取服務(wù)鏡像
  push        推送服務(wù)鏡像
  restart     重啟服務(wù)容器
  rm          刪除已停止的服務(wù)容器
  run         對(duì)服務(wù)運(yùn)行一次性命令
  scale       設(shè)置服務(wù)運(yùn)行的容器數(shù)量
  start       啟動(dòng)服務(wù)
  stats       顯示容器的實(shí)時(shí)資源使用統(tǒng)計(jì)信息
  stop        停止服務(wù)
  top         顯示正在運(yùn)行的進(jìn)程
  unpause     恢復(fù)暫停的服務(wù)
  up          創(chuàng)建并啟動(dòng)容器
  version     顯示 Docker Compose 版本信息
  wait        阻塞直到第一個(gè)服務(wù)容器停止
  watch       監(jiān)視服務(wù)的構(gòu)建上下文,并在文件更新時(shí)重建/刷新容器

運(yùn)行 'docker compose 命令 --help' 以獲取有關(guān)一個(gè)命令的更多信息翎碑。

4.2 docker-compose 常用命令

4.2.1 config

  • docker compose config -q 驗(yàn)證 docker-compose.yml 文件谬返。當(dāng)配置正確時(shí),不輸出任何內(nèi)容日杈,當(dāng)配置錯(cuò)誤時(shí)遣铝,輸出錯(cuò)誤信息。

4.2.2 pull

  • docker compose pull 拉取服務(wù)依賴的鏡像莉擒。
# 拉取工程中所有服務(wù)依賴的鏡像
docker compose pull
# 拉取工程中 redis 服務(wù)依賴的鏡像
docker compose pull redis
# 拉取鏡像過程中不打印拉取進(jìn)度信息
docker compose pull -q

4.2.3 up

docker compose up 創(chuàng)建并啟動(dòng)所有服務(wù)的容器酿炸。指定多個(gè) yml 加 -f 選項(xiàng)。以守護(hù)進(jìn)程模式運(yùn)行加 -d 選項(xiàng)涨冀。

# 前臺(tái)啟動(dòng)
docker compose up
# 后臺(tái)啟動(dòng)
docker compose up -d
# -f 指定使用的 Compose 模板文件填硕,默認(rèn)為 docker-compose.yml,可以多次指定鹿鳖,指定多個(gè) yml
docker compose -f docker-compose.yml up -d 

4.2.4 logs

docker compose logs 查看服務(wù)容器的輸出日志扁眯。默認(rèn)情況下,docker-compose 將對(duì)不同的服務(wù)輸出使用不同的顏色來區(qū)分翅帜∫鎏矗可以通過 --no-color 來關(guān)閉顏色。

# 輸出日志涝滴,不同的服務(wù)輸出使用不同的顏色來區(qū)分
docker compose logs
# 跟蹤日志輸出
docker compose logs -f
# 關(guān)閉顏色
docker compose logs --no-color

4.2.5 ps

docker compose ps 列出工程中所有服務(wù)的容器绣版。

# 列出工程中所有服務(wù)的容器
docker compose ps
# 列出工程中指定服務(wù)的容器
docker compose ps redis

4.2.6 run

docker compose run 在指定服務(wù)容器上執(zhí)行一個(gè)命令胶台。

# 在工程中指定服務(wù)的容器上執(zhí)行 echo "hello"
docker compose run redis echo "hello"

4.2.7 exec

docker compose exec 進(jìn)入服務(wù)容器。

# 進(jìn)入工程中指定服務(wù)的容器
docker compose exec redis bash
# 當(dāng)一個(gè)服務(wù)擁有多個(gè)容器時(shí)杂抽,可通過 --index 參數(shù)進(jìn)入到該服務(wù)下的任何容器
docker compose exec --index=1 redis bash

4.2.8 pause

docker compose pause 暫停服務(wù)容器诈唬。

# 暫停工程中所有服務(wù)的容器
docker compose pause
# 暫停工程中指定服務(wù)的容器
docker compose pause redis

4.2.9 unpause

docker compose unpause 恢復(fù)服務(wù)容器。

# 恢復(fù)工程中所有服務(wù)的容器
docker compose unpause
# 恢復(fù)工程中指定服務(wù)的容器
docker compose unpause redis

4.2.10 restart

docker compose restart 重啟服務(wù)容器缩麸。

# 重啟工程中所有服務(wù)的容器
docker compose restart
# 重啟工程中指定服務(wù)的容器
docker compose restart redis

4.2.11 start

docker compose start 啟動(dòng)服務(wù)容器铸磅。

# 啟動(dòng)工程中所有服務(wù)的容器
docker compose start
# 啟動(dòng)工程中指定服務(wù)的容器
docker compose start nginx

4.2.12 stop

docker compose stop 停止服務(wù)容器。

# 停止工程中所有服務(wù)的容器
docker compose stop
# 停止工程中指定服務(wù)的容器
docker compose stop redis

4.2.13 kill

docker compose kill 通過發(fā)送 SIGKILL 信號(hào)停止指定服務(wù)的容器杭朱。

# 通過發(fā)送 SIGKILL 信號(hào)停止工程中指定服務(wù)的容器
docker compose kill redis

4.2.14 rm

docker compose rm 刪除服務(wù)(停止?fàn)顟B(tài))容器愚屁。

# 刪除所有(停止?fàn)顟B(tài))服務(wù)的容器
docker compose rm
# 先停止所有服務(wù)的容器,再刪除所有服務(wù)的容器
docker compose rm -s
# 不詢問是否刪除痕檬,直接刪除
docker compose rm -f
# 刪除服務(wù)容器掛載的數(shù)據(jù)卷
docker compose rm -v
# 刪除工程中指定服務(wù)的容器
docker compose rm -sv redis

4.2.15 down

停止并刪除所有服務(wù)的容器、網(wǎng)絡(luò)送浊、鏡像梦谜、數(shù)據(jù)卷。

# 停止并刪除工程中所有服務(wù)的容器袭景、網(wǎng)絡(luò)
docker compose down
# 停止并刪除工程中所有服務(wù)的容器唁桩、網(wǎng)絡(luò)、鏡像
docker compose down --rmi all
# 停止并刪除工程中所有服務(wù)的容器耸棒、網(wǎng)絡(luò)荒澡、數(shù)據(jù)卷
docker compose down -v

4.2.16 images

docker compose images 打印服務(wù)容器所對(duì)應(yīng)的鏡像。

# 打印所有服務(wù)的容器所對(duì)應(yīng)的鏡像
docker compose images
# 打印指定服務(wù)的容器所對(duì)應(yīng)的鏡像
docker compose images redis

4.2.17 port

docker compose port 打印指定服務(wù)容器的某個(gè)端口所映射的宿主機(jī)端口与殃。

[root@VM-16-centos flask-app]# docker compose port nginx 80
0.0.0.0:80

4.2.18 top

docker compose top 顯示正在運(yùn)行的進(jìn)程单山。

# 顯示工程中所有服務(wù)的容器正在運(yùn)行的進(jìn)程
docker compose top
# 顯示工程中指定服務(wù)的容器正在運(yùn)行的進(jìn)程
docker compose top redis

五、docker-compose.yml 文件詳解

5.1 概念

Docker Compose 允許用戶通過 docker-compose.yml 文件(YAML 格式)來定義一組相關(guān)聯(lián)的容器為一個(gè)工程(project)幅疼。一個(gè)工程包含多個(gè)服務(wù)(service)米奸,每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像、參數(shù)爽篷、依賴等悴晰。

工程名若無特殊指定,即為 docker-compose.yml 文件所在目錄的名稱逐工。

Docker Compose 模板文件我們需要關(guān)注的頂級(jí)配置有:version铡溪、servicesnetworks泪喊、volumes 幾個(gè)部分棕硫,除 version 外,其他幾個(gè)頂級(jí)配置下還有很多下級(jí)配置窘俺,后面也會(huì)詳細(xì)給大家介紹饲帅,先來看看這幾個(gè)頂級(jí)配置都什么意思:

  • version:描述 Compose 文件的版本信息复凳,當(dāng)前最新版本為 3.8,對(duì)應(yīng)的 Docker 版本為 19.03.0+灶泵;
  • services:定義服務(wù)育八,可以多個(gè),每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像赦邻、參數(shù)髓棋、依賴等;
  • networkds:定義網(wǎng)絡(luò)惶洲,可以多個(gè)按声,根據(jù) DNS server 讓相同網(wǎng)絡(luò)中的容器可以直接通過容器名稱進(jìn)行通信;
  • volumes:數(shù)據(jù)卷恬吕,用于實(shí)現(xiàn)目錄掛載签则。

5.2 案例

在配置文件中,所有的容器通過 services 來定義铐料,然后使用 docker-compose 腳本來啟動(dòng)渐裂,停止和重啟容器,非常適合多個(gè)容器組合使用進(jìn)行開發(fā)的場(chǎng)景钠惩。我們先從一個(gè)簡(jiǎn)單的 Compose 案例開始柒凉。我們編寫第一個(gè) docker-compose.yml 文件。

# 創(chuàng)建目錄
mkdir -p ./docker-nginx
# 切換至指定目錄
cd ./docker-nginx/
# 編寫 docker-compose.yml 文件
vi docker-compose.yml

在文件 docker-compose.yml 文件中添加以下內(nèi)容:

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)篓跛,可以多個(gè)
services:
  nginx: # 服務(wù)名稱
    image: nginx # 創(chuàng)建容器時(shí)所需的鏡像
    container_name: mynginx # 容器名稱膝捞,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
    ports: # 宿主機(jī)與容器的端口映射關(guān)系
      - "80:80" # 左邊宿主機(jī)端口:右邊容器端口
    networks: # 配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目
      - nginx-net

# 定義網(wǎng)絡(luò)愧沟,可以多個(gè)蔬咬。如果不聲明,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
  nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
    name: nginx-net # 網(wǎng)絡(luò)名稱沐寺,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
    driver: bridge # 網(wǎng)絡(luò)模式计盒,默認(rèn)為 bridge

使用 docker-compose up 創(chuàng)建并啟動(dòng)所有服務(wù)。

# 前臺(tái)啟動(dòng)
docker-compose up
# 后臺(tái)啟動(dòng)
docker-compose up -d

瀏覽器訪問:http://localhost/結(jié)果如下:

使用 docker-compose down 可以停止并刪除容器芽丹、網(wǎng)絡(luò)北启。

https://mrhelloworld.com/resources/articles/docker/image-20200905151142759.png

5.3 version

  • version是Docker Compose文件的一個(gè)主要組成部分,用于指定當(dāng)前Docker Compose文件的版本拔第。

version字段通常在文件的頂部進(jìn)行定義咕村,如下所示:

version: "3.8"

在這個(gè)例子中,version被設(shè)置為'3.8'蚊俺,這意味著這個(gè)Docker Compose文件使用的是3.8版本的語法和功能懈涛。

重要的是要注意不同版本的Docker Compose之間可能存在不兼容性。因此泳猬,在升級(jí)或更改您的docker-compose.yaml文件時(shí)批钠,請(qǐng)確保查看有關(guān)版本的特定說明和變更日志宇植,以便了解您當(dāng)前所使用版本的支持的功能和變更情況。

官網(wǎng)提供的鏈接比較老了埋心,且compose版本和其version字段不相同指郁,對(duì)應(yīng)起來比較麻煩(二者的對(duì)應(yīng)關(guān)系可以參考鏈接

5.4 services

剛才我們提到 docker-compose.yml 文件中包含很多下級(jí)配置項(xiàng),下面帶大家把一些常用的配置項(xiàng)詳細(xì)了解一下拷呆,先從頂級(jí)配置 services 開始闲坎。

services 用來定義服務(wù),可以多個(gè)茬斧,每個(gè)服務(wù)中定義了創(chuàng)建容器時(shí)所需的鏡像腰懂、參數(shù)、依賴等项秉,就像將命令行參數(shù)傳遞給 docker run 一樣绣溜。同樣,網(wǎng)絡(luò)和數(shù)據(jù)卷的定義也是一樣的娄蔼。

5.4.1 services 簡(jiǎn)單舉例

舉個(gè)例子涮毫,之前我們通過 docker run 命令構(gòu)建一個(gè) MySQL 應(yīng)用容器的命令如下:

docker run -di --name mysql8 -p 3306:3306 -v /mydata/docker_mysql/conf:/etc/mysql/conf.d -v /mydata/docker_mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:8

使用 docker-compose.yml 以后則可以這樣定義:

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù),可以多個(gè)
services:
  mysql: # 服務(wù)名稱
    image: mysql:8 # 創(chuàng)建容器時(shí)所需的鏡像以及版本號(hào)
    container_name: mysql8 # 容器名稱贷屎,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
    ports: # 宿主機(jī)與容器的端口映射關(guān)系
      - "3306:3306" # 左邊宿主機(jī)端口:右邊容器端口
    environment: # 創(chuàng)建容器時(shí)所需的環(huán)境變量
      MYSQL_ROOT_PASSWORD: 1234 # MySQL root 用戶的密碼
    volumes:
      - "/mydata/docker_mysql/conf:/etc/mysql/conf.d"
      - "/mydata/docker_mysql/data:/var/lib/mysql"

然后通過 dokcer-compose 相關(guān)命令即可完成容器的創(chuàng)建,停止或刪除等一系列操作艘虎。

5.4.2 image

指定創(chuàng)建容器時(shí)所需的鏡像名稱標(biāo)簽或者鏡像 ID唉侄。如果鏡像在本地不存在,會(huì)去遠(yuǎn)程拉取野建。

services:
  web:
    image: mysql:8

5.4.3 build

除了可以基于指定的鏡像構(gòu)建容器属划,還可以基于 Dockerfile 文件構(gòu)建,在使用 up 命令時(shí)會(huì)執(zhí)行構(gòu)建任務(wù)候生。

通過 build 配置項(xiàng)可以指定 Dockerfile 所在文件夾的路徑同眯。Compose 將會(huì)利用 Dockerfile 自動(dòng)構(gòu)建鏡像,然后使用鏡像啟動(dòng)服務(wù)容器唯鸭。

build 配置項(xiàng)可以使用絕對(duì)路徑须蜗,也可以使用相對(duì)路徑。

# 絕對(duì)路徑目溉,在該路徑下基于名稱為 Dockerfile 的文件構(gòu)建鏡像
/usr/local/docker-centos
# 相對(duì)路徑明肮,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄,基于名稱為 Dockerfile 的文件構(gòu)建鏡像
.

接下來我們來個(gè)稍微復(fù)雜點(diǎn)的練習(xí)缭付,首先我們使用Go編寫一個(gè)HTTP Server:

創(chuàng)建一個(gè)目錄:

# 創(chuàng)建目錄
mkdir -p /usr/local/docker-centos
# 切換至指定目錄
cd /usr/local/docker-centos/
mkdir ./httpserver

編寫main.go內(nèi)容如下:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", rootHandler)
    http.HandleFunc("/ping", pingHandler)
    fmt.Println("Server started at http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "哈嘍柿估,Go!")
}

func pingHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "pong")
}

接著通過基礎(chǔ)鏡像 centos:8,在該鏡像中安裝 go 和 并且運(yùn)行HTTP Server以后將其制作為一個(gè)新的鏡像 mycentos:8陷猫。編寫 Dockerfile 文件秫舌。

# 編寫 Dockerfile 文件
vi Dockerfile

Dockerfile 文件內(nèi)容如下:

# 指明構(gòu)建的新鏡像是來自于 centos:8 基礎(chǔ)鏡像
FROM centos:8

# 通過鏡像標(biāo)簽聲明了作者信息
LABEL maintainer="blog.jarvis.com"

# 設(shè)置工作目錄
WORKDIR /usr/local

# 拷貝 Go 語言壓縮包并解壓到指定目錄
ADD go1.22.1.linux-amd64.tar.gz /usr/local/

# 設(shè)置 Go 環(huán)境變量
ENV GOROOT=/usr/local/go
ENV GOPATH=/usr/local/gopath
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin

# 將 httpserver 代碼拷貝到容器中
COPY ./httpserver /usr/local/httpserver

# 設(shè)置工作目錄到 httpserver 目錄
WORKDIR /usr/local/httpserver

# 編譯 Go HTTP 服務(wù)器
RUN go build -o httpserver main.go

# 暴露容器運(yùn)行時(shí)的 8080 監(jiān)聽端口給外部
EXPOSE 8080

# 使用 CMD 運(yùn)行 HTTP 服務(wù)器
CMD ["./httpserver"]

接著通過如下命令下載Go 編譯器:

# 下載GO 編譯器
wget https://golang.google.cn/dl/go1.22.1.linux-amd64.tar.gz

創(chuàng)建目錄并編寫 docker-compose.yml 文件的妖。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù),可以多個(gè)
services:
  mycentos: # 服務(wù)名稱
    build: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄足陨,基于名稱為 Dockerfile-alternate 的文件構(gòu)建鏡像
    container_name: mycentos7 # 容器名稱嫂粟,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
    ports: # 宿主機(jī)與容器的端口映射關(guān)系
      - "8080:8080" # 左邊宿主機(jī)端口:右邊容器端口

然后通過 dokcer-compose 相關(guān)命令即可完成容器的創(chuàng)建,停止或刪除等一系列操作钠右。

(一). context

該選項(xiàng)可以是 Dockerfile 文件的絕對(duì)/相對(duì)路徑赋元,也可以是遠(yuǎn)程 Git 倉(cāng)庫(kù)的 URL,當(dāng)提供的值是相對(duì)路徑時(shí)飒房,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄搁凸。

build:
  context: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄,基于名稱為 Dockerfile 的文件構(gòu)建鏡像
(二). dockerfile

一般情況下狠毯,默認(rèn)都基于文件名叫 Dockerfile 的文件構(gòu)建鏡像护糖,當(dāng)然也可以是自定義的文件名,使用 dockerfile 聲明嚼松,不過這個(gè)選項(xiàng)只能聲明文件名嫡良,文件所在路徑還是要通過 centext 來聲明。

build:
  context: . # 相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
  dockerfile: Dockerfile-alternate # 基于名稱為 Dockerfile-alternate 的文件構(gòu)建鏡像

5.4.4 container_name

Compose 創(chuàng)建的容器默認(rèn)生成的名稱格式為:工程名稱_服務(wù)條目名稱_序號(hào)献酗。如果要使用自定義名稱寝受,使用 container_name 聲明。

services:
  mycentos:
    build: .
    container_name: mycentos7 # 容器名稱罕偎,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"

因?yàn)?Docker 容器名稱必須是唯一的很澄,所以如果指定了自定義名稱,就不能將服務(wù)擴(kuò)展至多個(gè)容器颜及。這樣做可能會(huì)導(dǎo)致錯(cuò)誤甩苛。

關(guān)于序號(hào)

序號(hào)是干什么用的呢,看下面這個(gè)列子你就懂了俏站,docker-compose.yml 文件內(nèi)容如下:

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)讯蒲,可以多個(gè)
services:
  helloworld: # 服務(wù)名稱
    image: hello-world

然后通過 --scale 指定 helloworld 服務(wù)一次性啟動(dòng) 3 個(gè)。

docker-compose up -d --scale helloworld=3

通過下圖可以看到有 3 個(gè)容器被創(chuàng)建肄扎,容器名稱最后的序號(hào)是從 1 開始累加的墨林,這就是序號(hào)的作用。所以如果指定了自定義名稱犯祠,就不能將服務(wù)擴(kuò)展至多個(gè)容器萌丈。

5.4.5 depends_on

使用 Compose 最大的好處就是敲最少的命令做更多的事情,但一般項(xiàng)目容器啟動(dòng)的順序是有要求的雷则,如果直接從上到下啟動(dòng)容器辆雾,必然會(huì)因?yàn)槿萜饕蕾噯栴}而啟動(dòng)失敗。例如在沒有啟動(dòng)數(shù)據(jù)庫(kù)容器的情況下啟動(dòng)了 Web 應(yīng)用容器月劈,應(yīng)用容器會(huì)因?yàn)檎也坏綌?shù)據(jù)庫(kù)而退出度迂。depends_on 就是用來解決容器依賴藤乙、啟動(dòng)先后問題的配置項(xiàng)。

version: "3.8"

services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: mysql

上述 YAML 文件定義的容器會(huì)先啟動(dòng) db 和 redis 兩個(gè)服務(wù)惭墓,最后才啟動(dòng) web 服務(wù)坛梁。

5.4.6 ports

容器對(duì)外暴露的端口,格式:左邊宿主機(jī)端口:右邊容器端口腊凶。

ports:
  - "80:80"
  - "8080:8080"

5.4.7 expose

容器暴露的端口不映射到宿主機(jī)划咐,只允許能被連接的服務(wù)訪問。

expose:
  - "80"
  - "8080"

5.4.8 restart

容器重啟策略钧萍,簡(jiǎn)單的理解就是 Docker 重啟以后容器要不要一起啟動(dòng):

  • no:默認(rèn)的重啟策略褐缠,在任何情況下都不會(huì)重啟容器;
  • on-failure:容器非正常退出時(shí)风瘦,比如退出狀態(tài)為非0(異常退出)队魏,才會(huì)重啟容器;
  • always:容器總是重新啟動(dòng)万搔,即使容器被手動(dòng)停止了胡桨,當(dāng) Docker 重啟時(shí)容器也還是會(huì)一起啟動(dòng);
  • unless-stopped:容器總是重新啟動(dòng)瞬雹,除非容器被停止(手動(dòng)或其他方式)昧谊,那么 Docker 重啟時(shí)容器則不會(huì)啟動(dòng)。
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    restart: always

5.4.9 environment

添加環(huán)境變量酗捌∧匚埽可以使用數(shù)組也可以使用字典。布爾相關(guān)的值(true意敛、false、yes膛虫、no)都需要用引號(hào)括起來草姻,以確保 YML 解析器不會(huì)將它們轉(zhuǎn)換為真或假。

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

或者以下格式:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

5.4.10 env_file

從文件中獲取環(huán)境變量稍刀,可以指定一個(gè)或多個(gè)文件撩独,其優(yōu)先級(jí)低于 environment 指定的環(huán)境變量。

env_file:
  - /opt/runtime_opts.env # 絕對(duì)路徑
  - ./common.env # 相對(duì)路徑账月,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
  - ./apps/web.env # 相對(duì)路徑综膀,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄

注意:env 文件中的每一行需采用 鍵=值 格式。以 # 開頭的行會(huì)被視為注釋并被忽略局齿【缛埃空行也會(huì)被忽略。

5.4.11 command

覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令抓歼。

command: echo "helloworld"

該命令也可以是一個(gè)列表讥此。

command: ["echo", "helloworld"]

5.4.12 volumes

數(shù)據(jù)卷拢锹,用于實(shí)現(xiàn)目錄掛載,支持指定目錄掛載萄喳、匿名掛載卒稳、具名掛載

  • 指定目錄掛載的格式為:左邊宿主機(jī)目錄:右邊容器目錄他巨,或者左邊宿主機(jī)目錄:右邊容器目錄:讀寫權(quán)限充坑;
  • 匿名掛載格式為:容器目錄即可,或者容器目錄即可:讀寫權(quán)限染突;
  • 具名掛載格式為:數(shù)據(jù)卷?xiàng)l目名稱:容器目錄捻爷,或者數(shù)據(jù)卷?xiàng)l目名稱:容器目錄:讀寫權(quán)限
# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)觉痛,可以多個(gè)
services:
  mysql: # 服務(wù)名稱
    image: mysql:8 # 創(chuàng)建容器時(shí)所需的鏡像
    container_name: mysql8 # 容器名稱役衡,默認(rèn)為"工程名稱_服務(wù)條目名稱_序號(hào)"
    ports: # 宿主機(jī)與容器的端口映射關(guān)系
      - "3306:3306" # 左邊宿主機(jī)端口:右邊容器端口
    environment: # 創(chuàng)建容器時(shí)所需的環(huán)境變量
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      # 絕對(duì)路徑
      - "/mydata/docker_mysql/data:/var/lib/mysql"
      # 相對(duì)路徑,相對(duì)當(dāng)前 docker-compose.yml 文件所在目錄
      - “./conf:/etc/mysql/conf.d“
      # 匿名掛載薪棒,匿名掛載只需要寫容器目錄即可手蝎,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
      - "/var/lib/mysql"
      # 具名掛載,就是給數(shù)據(jù)卷起了個(gè)名字俐芯,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定義數(shù)據(jù)卷棵介,可以多個(gè)
volumes:
  mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱
    name: mysql-data-volume # 數(shù)據(jù)卷名稱,默認(rèn)為"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"

5.4.13 network_mode

設(shè)置網(wǎng)絡(luò)模式吧史,類似 docker run 時(shí)添加的參數(shù) --net host 或者 --network host 的用法邮辽。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

5.4.14 networks

配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目贸营。

# 定義服務(wù)吨述,可以多個(gè)
services:
  nginx: # 服務(wù)名稱
    networks: # 配置容器連接的網(wǎng)絡(luò),引用頂級(jí) networks 下的條目
      - nginx-net # 一個(gè)具體網(wǎng)絡(luò)的條目名稱

# 定義網(wǎng)絡(luò)钞脂,可以多個(gè)揣云。如果不聲明,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
  nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
    name: nginx-net # 網(wǎng)絡(luò)名稱冰啃,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
    driver: bridge # 網(wǎng)絡(luò)模式邓夕,默認(rèn)為 bridge
aliases

網(wǎng)絡(luò)上此服務(wù)的別名。同一網(wǎng)絡(luò)上的其他容器可以使用服務(wù)名或此別名連接到服務(wù)容器阎毅。同一服務(wù)在不同的網(wǎng)絡(luò)上可以具有不同的別名焚刚。

# 定義服務(wù),可以多個(gè)
services:
  nginx: # 服務(wù)名稱
    networks: # 配置容器連接的網(wǎng)絡(luò)扇调,引用頂級(jí) networks 下的條目
      nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
        aliases: # 服務(wù)別名矿咕,可以多個(gè)
          - nginx1 # 同一網(wǎng)絡(luò)上的其他容器可以使用服務(wù)名或此別名連接到服務(wù)容器

# 定義網(wǎng)絡(luò),可以多個(gè)。如果不聲明痴腌,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
networks:
  nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
    name: nginx-net # 網(wǎng)絡(luò)名稱雌团,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
    driver: bridge # 網(wǎng)絡(luò)模式,默認(rèn)為 bridge

5.5 volumes

通過頂級(jí)配置 services 的學(xué)習(xí)士聪,大家應(yīng)該已經(jīng)明白頂級(jí)配置 volumes 是干嘛的了锦援,這里再詳細(xì)把配置的不同方式研究一下。

以下方式的數(shù)據(jù)卷聲明創(chuàng)建卷時(shí)會(huì)使用默認(rèn)的名稱:"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"剥悟。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)灵寺,可以多個(gè)
services:
  mysql:
    image: mysql:8
    container_name: mysql8
    ports:
      - "3306:3306"
    environment
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      # 具名掛載,就是給數(shù)據(jù)卷起了個(gè)名字区岗,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定義數(shù)據(jù)卷略板,可以多個(gè)
volumes:
  mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱

以下方式的數(shù)據(jù)卷聲明創(chuàng)建卷時(shí)會(huì)使用自定義的名稱。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)慈缔,可以多個(gè)
services:
  mysql:
    image: mysql:8
    container_name: mysql8
    ports:
      - "3306:3306"
    environment
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      # 具名掛載叮称,就是給數(shù)據(jù)卷起了個(gè)名字,容器外對(duì)應(yīng)的目錄會(huì)在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定義數(shù)據(jù)卷藐鹤,可以多個(gè)
volumes:
  mysql-data-volume: # 一個(gè)具體數(shù)據(jù)卷的條目名稱
    name: mysql-data-volume # 數(shù)據(jù)卷名稱瓤檐,默認(rèn)為"工程名稱_數(shù)據(jù)卷?xiàng)l目名稱"

5.6 networks

通過頂級(jí)配置 services 的講解,大家其實(shí)已經(jīng)明白頂級(jí)配置 volumes 是干嘛的了娱节,這里再詳細(xì)把配置的不同方式研究一下挠蛉。

如果不聲明網(wǎng)絡(luò),每個(gè)工程默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"bridge 網(wǎng)絡(luò)肄满。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù)谴古,可以多個(gè)
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"

# 定義網(wǎng)絡(luò),可以多個(gè)稠歉。如果不聲明掰担,默認(rèn)會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)名稱為"工程名稱_default"的 bridge 網(wǎng)絡(luò)
#networks:

以下方式的網(wǎng)絡(luò)聲明創(chuàng)建網(wǎng)絡(luò)時(shí)會(huì)使用默認(rèn)的名稱:"工程名稱_網(wǎng)絡(luò)條目名稱"刃泡,網(wǎng)絡(luò)模式默認(rèn)為 bridge预厌。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù),可以多個(gè)
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    networks: # 配置容器連接的網(wǎng)絡(luò)乔外,引用頂級(jí) networks 下的條目
      nginx-net:

# 定義網(wǎng)絡(luò)横媚,可以多個(gè)
networks:
  nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱

以下方式的網(wǎng)絡(luò)聲明創(chuàng)建網(wǎng)絡(luò)時(shí)會(huì)使用自定義的名稱纠炮,還可以通過 driver 選擇網(wǎng)絡(luò)模式月趟,默認(rèn)為 bridge灯蝴。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務(wù),可以多個(gè)
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    networks: # 配置容器連接的網(wǎng)絡(luò)孝宗,引用頂級(jí) networks 下的條目
      nginx-net:

# 定義網(wǎng)絡(luò)穷躁,可以多個(gè)
networks:
  nginx-net: # 一個(gè)具體網(wǎng)絡(luò)的條目名稱
    name: nginx-net # 網(wǎng)絡(luò)名稱,默認(rèn)為"工程名稱_網(wǎng)絡(luò)條目名稱"
    driver: bridge # 網(wǎng)絡(luò)模式,默認(rèn)為 bridge

六问潭、小結(jié)

Docker Compose 的整體使用步驟還是比較簡(jiǎn)單的猿诸,三個(gè)步驟為:

  • 使用 Dockerfile 文件定義應(yīng)用程序的環(huán)境;
  • 使用 docker-compose.yml 文件定義構(gòu)成應(yīng)用程序的服務(wù)狡忙,這樣它們可以在隔離環(huán)境中一起運(yùn)行梳虽;
  • 最后,執(zhí)行 docker-compose up 命令來創(chuàng)建并啟動(dòng)所有服務(wù)灾茁。

雖然 docker-compose.yml 文件詳解Compose 常用命令這兩大塊的內(nèi)容比較多窜觉,但是如果要快速入門使用 Compose,其實(shí)只需要了解其中部分內(nèi)容即可北专。后期大家可在項(xiàng)目生產(chǎn)環(huán)境中根據(jù)自身情況再進(jìn)一步深入學(xué)習(xí)即可禀挫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拓颓,隨后出現(xiàn)的幾起案子语婴,更是在濱河造成了極大的恐慌,老刑警劉巖驶睦,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰左,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡啥繁,警方通過查閱死者的電腦和手機(jī)菜职,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旗闽,“玉大人酬核,你說我怎么就攤上這事∈适遥” “怎么了嫡意?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)捣辆。 經(jīng)常有香客問我蔬螟,道長(zhǎng),這世上最難降的妖魔是什么汽畴? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任旧巾,我火速辦了婚禮,結(jié)果婚禮上忍些,老公的妹妹穿的比我還像新娘鲁猩。我一直安慰自己,他們只是感情好罢坝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布廓握。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隙券。 梳的紋絲不亂的頭發(fā)上男应,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音娱仔,去河邊找鬼沐飘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛牲迫,可吹牛的內(nèi)容都是我干的薪铜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恩溅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼隔箍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脚乡,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蜒滩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奶稠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俯艰,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年锌订,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竹握。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辆飘,死狀恐怖啦辐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜈项,我是刑警寧澤芹关,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站紧卒,受9級(jí)特大地震影響侥衬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜跑芳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一轴总、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧博个,春花似錦怀樟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至罪塔,卻和暖如春投蝉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背征堪。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工瘩缆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佃蚜。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓庸娱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谐算。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熟尉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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