全栈工程师开发手册 (作者:栾鹏)
​​ 架构系列文章​​


如果没有k8s环境,只能使用docker安装应用,而一个应用可能需要部署多个容器时就需要用到docker-compose了。

安装docker-compose

sudo pip install docker-compose

docker-compose示例

假设我们有两个应用,web后端和mysql应用,web后端需要调用mysql应用。

我们把web应用都放在web目录下面,该目录下两个文件
app.py

from flask import Flask
import pymysql

app = Flask(__name__)

conn = pymysql.connect(host='mysql', user='root', passwd='admin', db='test', port=3306, charset="utf8", cursorclass=pymysql.cursors.DictCursor, )

@app.route('/')
def hello():
return 'Hello World!'


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

Dockerfile-web文件

FROM python:3.6
RUN pip install flask pymysql
WORKDIR /web
CMD ["python", "app.py"]

docker-compose.yml 属性

在web目录外,我们定义docker-compose.yml

version : '3'        #docker引擎对应所支持的docker-compose文本格式
services: #本工程的服务配置列表

web: # 服务名,服务名自定义
container_name: web-compose
# 服务之后启动的容器实例的名字,如果指定,按照这个命名容器,如果未指定,容器命名规则是
#【[compose文件所在目录]_[服务名]_1】,例如【swappingdockercompose_swapping_1】
#如果多启动,也就是docker-compose scale swapping=3 mysql=2的话,就不需要指定容器名称,否则会报错 容器名重复存在的问题
build: #基于Dockerfile文件构建镜像时使用的属性
context: . # .代表当前目录,也可以指定绝对路径[/path/test/Dockerfile]或相对路径[../test/Dockerfile],尽量放在当前目录,便于管理
dockerfile: web/Dockerfile-web #指定Dockerfile文件名。如果context指定了文件名,这里就不用本属性了
ports: #影射端口属性
- "5000:5000" #建议使用字符串格式,指定宿主机端口映射到本容器的端口
volumes: #挂载属性
- ./web:/web #挂载路径在compose配置文件中只能指定容器内的目录,而docker run命令可以指定[宿主机目录:容器内目录]的挂载方式。可以使用:ro对容器内目录设置只读,来保护宿主机的文件系统
depends_on: #本服务启动,需要依赖哪些别的服务 例如这里;mysql服务就会先于swapping服务启动。至于配置多个的话,depends_on内的多个依赖的启动先后顺序未测试过
- mysql
links: #与depends_on相对应,上面控制启动顺序,这个控制容器连接问题。
- "mysql:mysql" #值可以是- mysql[- 服务名],也可以是- "mysql:mysql"[- "服务名:别名"]
restart: always #是否随docker服务启动重启
networks: #加入指定网络
- my-network #自定义的网络名
environment: #environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。设置容器的环境变量
- TZ=Asia/Shanghai #这里设置容器的时区为亚洲上海,也就解决了容器通过compose编排启动的 时区问题!!!!解决了容器的时区问题!!!

mysql: #服务名叫mysql,自定义
container_name: mysql-compose #容器名
image: mysql:5.7 #虽然没有使用build,但使用了image,指定基于mysql:5.7镜像为基础镜像来构建镜像。【使用build基于Dockerfile文件构建,Dockerfile文件中也有FROM基于基础镜像】
ports:
- "33061:3306"
command: [ #使用 command 可以覆盖容器启动后默认执行的命令
'--character-set-server=utf8mb4', #设置数据库表的数据集
'--collation-server=utf8mb4_unicode_ci', #设置数据库表的数据集
'--default-time-zone=+8:00' #设置mysql数据库的 时区问题!!!! 而不是设置容器的时区问题!!!!
]
environment:
MYSQL_DATABASE: test #设置初始的数据库名
MYSQL_ROOT_PASSWORD: admin #设置root连接密码
MYSQL_ROOT_HOST: '%'
restart: always
networks:
- my-network
networks: #关于compose中的networks的详细使用
my-network: #自定义的网络,会在第一次构建时候创建自定义网络,默认是bridge

docker-compose命令

ps:列出所有运行容器

docker-compose ps

logs:查看服务日志输出

docker-compose logs

port:打印绑定的公共端口,下面命令可以输出 eureka 服务 8761 端口所绑定的公共端口

docker-compose port eureka 8761

build:构建或者重新构建服务

docker-compose build

start:启动指定服务已存在的容器

docker-compose start eureka

stop:停止已运行的服务的容器

docker-compose stop eureka

rm:删除指定服务的容器

docker-compose rm eureka

up:构建、启动容器

docker-compose up

kill:通过发送 SIGKILL 信号来停止指定服务的容器

docker-compose kill eureka

pull:下载服务镜像
scale:设置指定服务运气容器的个数,以 service=num 形式指定

docker-compose scale user=3 movie=3

run:在一个服务上执行一个命令

docker-compose run web bash