手动部署 wordpress

  1. # 部署 mysql
  2. docker run -d --name mysql -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql:5.7
  3. # 部署 wordpress
  4. docker run -d -e WORDPRESS_DB_HOST=mysql --link mysql -p 8080:80 wordpress

注意:如果平时最新版本的 Mysql,执行以上操作部署完成之后,访问 WordPress 站点会出现 ,Error establishing a database connection,显然,数据库连接失败。通过访问 mysql 容器的 log 来排查问题。

  1. docker logs mysql
  2. #提示:The server requested authentication method unknown to the client
  3. #认证方法错误,mysql8.0 以后默认的认证方式改了,所以才会有这样的错误
  4. # 解决办法
  5. #进入mysql容器
  6. docker exec -it mysql /bin/bash
  7. #登陆数据库
  8. mysql -u root -p
  9. use mysql;
  10. #开启root远程访问权限
  11. grant all on *.* to 'root'@'%';
  12. #修改加密规则
  13. alter user 'root'@'localhost' identified by 'root' password expire never;
  14. #更新密码
  15. alter user 'root'@'%' identified with mysql_native_password by 'root';
  16. #刷新权限
  17. 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:
    1. imagemysql
    2. volumes
    3. - mysql:/var/lib/mysql

从本地 Dockerfile 文件创建

services: node-http: build: context: . # 指定 Dockerfile 文件所在的目录 dockerfile: Dockerfile links: # 连接到同一个自定义 network 的容器默认是互相连接的,可以不配置 links

  1. - mysql
  1. **volume**
  2. ```yaml
  3. # 指定数据卷
  4. volumes:
  5. db-data:
  6. # 等同于
  7. docker volume create db-data

network

  1. # 指定自定义网络
  2. networks:
  3. my-bridge:
  4. driver: bridge
  5. # 等同于
  6. docker network create -d bridge my-bridge

部署 wordpress 的 模板文件

  1. # 使用默认的自定义网络
  2. # 默认情况下会自动创建一个自定义网络,并且容器默认都连接到这个自定义网络
  3. version: '3'
  4. services:
  5. wordpress:
  6. image: wordpress
  7. ports:
  8. - 8080:80
  9. environment:
  10. WORDPRESS_DB_HOST: mysql
  11. WORDPRESS_DB_PASSWORD: root
  12. mysql:
  13. image: mysql:5.7
  14. environment:
  15. MYSQL_ROOT_PASSWORD: root
  16. MYSQL_DATABASE: wordpress
  17. volumes:
  18. - mysql:/var/lib/mysql
  19. volumes:
  20. mysql:
  21. # 使用 networks 关键字指定自定义网络
  22. version: '3'
  23. services:
  24. wordpress:
  25. image: wordpress
  26. ports:
  27. - 8080:80
  28. environment:
  29. WORDPRESS_DB_HOST: mysql
  30. WORDPRESS_DB_PASSWORD: root
  31. networks:
  32. - my-bridge
  33. mysql:
  34. image: mysql:5.7
  35. environment:
  36. MYSQL_ROOT_PASSWORD: root
  37. MYSQL_DATABASE: wordpress
  38. volumes:
  39. - mysql:/var/lib/mysql
  40. networks:
  41. - my-bridge
  42. volumes:
  43. mysql:
  44. networks:
  45. my-bridge:
  46. driver: bridge

基本命令
  1. # 创建容器
  2. docker-compose build
  3. # 创建并启动容器
  4. docker-compose up -d # -d 参数指定在后台启动容器
  5. # 启动容器
  6. docker-compose start
  7. # 停止容器
  8. docker-compose stop
  9. # 停止并删除容器和对应的自定义网络
  10. docker-compose down
  11. # 查看对应的镜像和容器
  12. docker-compose images
  13. # 查看对应容器
  14. docker-compose ps
  15. # 进入指定的容器
  16. docker-compose exec xxx # naem为 service 中定义的名称 docker-compose exec mysql bash
  17. # 查看容器运行日志
  18. docker-compose logs

水平扩展和负载均衡

通过 Docker Compose 的 —scale 命令可以同时部署多个web应用供用户访问,并结合负载均衡器实现负载均衡,提高服务的稳定性
Docker Compose 多容器部署 - 图1
测试:通过 docker-compose --scale 命令部署多个 Web 服务,通过 HAproxy 转发到不同的服务

  1. # app.py
  2. from flask import Flask
  3. from redis import Redis
  4. import os
  5. import socket
  6. app = Flask(__name__)
  7. redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
  8. @app.route('/')
  9. def hello():
  10. redis.incr('hits')
  11. return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())
  12. if __name__ == "__main__":
  13. app.run(host="0.0.0.0", port=80, debug=True)
  14. # Dockerfile
  15. FROM python:2.7
  16. LABEL maintaner="gongyz 1018017334"
  17. COPY . /app
  18. WORKDIR /app
  19. RUN pip install flask redis
  20. EXPOSE 80
  21. CMD [ "python", "app.py" ]
  22. # docker-compose.yml
  23. version: "3"
  24. services:
  25. redis:
  26. image: redis
  27. web:
  28. build:
  29. context: .
  30. dockerfile: Dockerfile
  31. # 使用 --scale 不要再指定宿主机端口,因为宿主机只有一个 8080 端口
  32. #ports:
  33. # - 8080:80
  34. environment:
  35. REDIS_HOST: redis
  36. lb:
  37. image: dockercloud/haproxy
  38. links:
  39. - web
  40. ports:
  41. - 8080:80
  42. volumes:
  43. - /var/run/docker.sock:/var/run/docker.sock

启动容器

  1. # 构建镜像
  2. docker-compose build
  3. # 部署镜像
  4. docker-compose up --scale web=4 -d