手动部署 wordpress
# 部署 mysqldocker run -d --name mysql -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql:5.7# 部署 wordpressdocker run -d -e WORDPRESS_DB_HOST=mysql --link mysql -p 8080:80 wordpress
注意:如果平时最新版本的 Mysql,执行以上操作部署完成之后,访问 WordPress 站点会出现 ,Error establishing a database connection,显然,数据库连接失败。通过访问 mysql 容器的 log 来排查问题。
docker logs mysql#提示:The server requested authentication method unknown to the client#认证方法错误,mysql8.0 以后默认的认证方式改了,所以才会有这样的错误# 解决办法#进入mysql容器docker exec -it mysql /bin/bash#登陆数据库mysql -u root -puse mysql;#开启root远程访问权限grant all on *.* to 'root'@'%';#修改加密规则alter user 'root'@'localhost' identified by 'root' password expire never;#更新密码alter user 'root'@'%' identified with mysql_native_password by 'root';#刷新权限flush privileges;
通过手动部署 WordPress 可以发现,手动部署一个多容器应用非常不方便,至少需要经过以下几个步骤:
- 从 Dockerfile build image 或者 Docker Hub 拉取 image
 - 创建多个 container
 - 管理这些 container(启动、停止、删除)
 
所以我们需要使用 Docker Compose 去部署和管理多容器应用。
Docker Compose
基本概念
Docker Compose 是 docker 官方编排工具 ,可以通过一个模板(YAML格式)定义多容器的 docker 应用,通过一条命令就可以根据模板创建和管理多个容器。
Docker Compose 目前有三个版本,推荐使用 Version 3,因为Version 3 可以用于多机部署。
注意:Mac、Window10 环境下安装 docker 时同时安装了 docker compose,linux 环境下需要手动安装。
模板文件的组成:
service
- 一个 service 代表一个 container ,这个 container 可以从 dockerhub 的 image 来创建,或者从本地 Dockerfile 文件 build 出来的 image 创建。
 - service 的启动类似 docker run,我们可以给它指定 network 和 volume
```yaml
从 dockerhub 的 image 来创建
services: db:image:mysqlvolumes:- mysql:/var/lib/mysql
 
从本地 Dockerfile 文件创建
services: node-http: build: context: . # 指定 Dockerfile 文件所在的目录 dockerfile: Dockerfile links: # 连接到同一个自定义 network 的容器默认是互相连接的,可以不配置 links
- mysql
**volume**```yaml# 指定数据卷volumes:db-data:# 等同于docker volume create db-data
network
# 指定自定义网络networks:my-bridge:driver: bridge# 等同于docker network create -d bridge my-bridge
部署 wordpress 的 模板文件
# 使用默认的自定义网络# 默认情况下会自动创建一个自定义网络,并且容器默认都连接到这个自定义网络version: '3'services:wordpress:image: wordpressports:- 8080:80environment:WORDPRESS_DB_HOST: mysqlWORDPRESS_DB_PASSWORD: rootmysql:image: mysql:5.7environment:MYSQL_ROOT_PASSWORD: rootMYSQL_DATABASE: wordpressvolumes:- mysql:/var/lib/mysqlvolumes:mysql:# 使用 networks 关键字指定自定义网络version: '3'services:wordpress:image: wordpressports:- 8080:80environment:WORDPRESS_DB_HOST: mysqlWORDPRESS_DB_PASSWORD: rootnetworks:- my-bridgemysql:image: mysql:5.7environment:MYSQL_ROOT_PASSWORD: rootMYSQL_DATABASE: wordpressvolumes:- mysql:/var/lib/mysqlnetworks:- my-bridgevolumes:mysql:networks:my-bridge:driver: bridge
基本命令
# 创建容器docker-compose build# 创建并启动容器docker-compose up -d # -d 参数指定在后台启动容器# 启动容器docker-compose start# 停止容器docker-compose stop# 停止并删除容器和对应的自定义网络docker-compose down# 查看对应的镜像和容器docker-compose images# 查看对应容器docker-compose ps# 进入指定的容器docker-compose exec xxx # naem为 service 中定义的名称 docker-compose exec mysql bash# 查看容器运行日志docker-compose logs
水平扩展和负载均衡
通过 Docker Compose 的 —scale 命令可以同时部署多个web应用供用户访问,并结合负载均衡器实现负载均衡,提高服务的稳定性。
测试:通过 docker-compose --scale 命令部署多个 Web 服务,通过 HAproxy 转发到不同的服务
# app.pyfrom flask import Flaskfrom redis import Redisimport osimport socketapp = Flask(__name__)redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)@app.route('/')def hello():redis.incr('hits')return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())if __name__ == "__main__":app.run(host="0.0.0.0", port=80, debug=True)# DockerfileFROM python:2.7LABEL maintaner="gongyz 1018017334"COPY . /appWORKDIR /appRUN pip install flask redisEXPOSE 80CMD [ "python", "app.py" ]# docker-compose.ymlversion: "3"services:redis:image: redisweb:build:context: .dockerfile: Dockerfile# 使用 --scale 不要再指定宿主机端口,因为宿主机只有一个 8080 端口#ports:# - 8080:80environment:REDIS_HOST: redislb:image: dockercloud/haproxylinks:- webports:- 8080:80volumes:- /var/run/docker.sock:/var/run/docker.sock
启动容器
# 构建镜像docker-compose build# 部署镜像docker-compose up --scale web=4 -d
