Docker:docker-compose多容器编排管理,部署Flask+MySQL Web应用

摘要:Docker

Docker Compose简介

Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,可以使用YAML文件来配置应用程序的服务。然后,使用一个命令,从配置中创建并启动所有服务。使用Compose基本上分为三个步骤:

  • 定义Dockerfile:使用Dockerfile定义应用程序的环境,以便可以在任何地方复制。
  • 编写docker-compose.yml:在docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
  • 运行docker compose up:运行docker compose up,docker compose命令启动并运行整个应用程序。也可以使用docker compose二进制文件运行docker compose up

docker-compose.yml示例

docker-compose.yml有多个版本,每个版本格式略有不同,以最新的version3为例一个yml文件如下

version: '3'
services:
  mysql:
    build: ./mysql
    ports: 
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=***
    restart: always
  redis:
    image: redis:3.2
    restart: always
  flask:
    build: ./flask
    ports:
     - "5000:5000"
    depends_on: 
     - mysql
     - redis
    links: 
     - mysql:mysql  
     - redis:redis-server 
    restart: always
  nginx: 
    build: ./nginx 
    ports: 
      - "80:80" 
    links: 
     - flask 

  • yaml的基本格式:yaml格式中:代表键值对,缩进代表嵌套,-代表属性值为多值列表
  • 工程,服务,容器:整个yaml文件定义了一个工程,该工程包括4个服务分别是mysql,redis,flask,nginx,每个服务各包含一个容器
  • 镜像构建和定义容器启动参数:在每个服务下定义了镜像的构建(需配合各目录下的Dockerfile)以及启动,以及各种启动参数,环境变量等相关信息
  • 设置依赖:多个服务可以设置依赖关系

docker-compose安装

在linux环境下使用curl从github上下载Docker Compose的当前稳定版本

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

赋予二进制文件可执行权限

root@ubuntu:/etc/openvpn# sudo chmod +x /usr/local/bin/docker-compose

也可以使用pip安装,必须是3.6之后的Python版本

pip install docker-compose

测试docker-compose命令查看版本

root@ubuntu:/etc/openvpn# docker-compose -v
docker-compose version 1.29.2, build 5becea4c

docker-compose部署应用Quickly start

(1)工程结构准备

创建一个目录test作为项目目录,创建两个子目录mysql,flask分别对应两个服务,目录结构如下

root@ubuntu:~/docker/docker-compose/test# tree
.
├── flask
│   ├── app
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       └── __init__.cpython-37.pyc
│   ├── blueprints
│   │   ├── compare.py
│   │   ├── detail.py
...
└── mysql
    └── pira.sql
(2)Flask工程准备

在flask目录下放置工程代码,数据,配置文件,以及Dockerfile,用于docker-compose下一步进行镜像构建和服务启动,其中Dockerfile如下

From python:3.7
MAINTAINER xiaogp
ENV PIPURL "https://pypi.tuna.tsinghua.edu.cn/simple"
COPY . /home
WORKDIR /home
RUN pip install -r requirements.txt -i ${PIPURL} --default-timeout=1000
CMD gunicorn -c gun.conf.py manage:app

其中的部分关键的数据库配置如下,数据库的user,password,db通过docker启动时的-e环境变量传入,数据库host需要访问MySQL容器的IP,采用--link的自动获取

# vim settings.py

class ProductionConfig(BaseConfig):
    USERNAME = os.environ.get('MYSQL_USER')
    PASSWORD = os.environ.get('MYSQL_PASSWORD')
    HOST = 'mysql'
    PORT = '3306'
    DATABASE = os.environ.get('MYSQL_DB')
    DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOST, PORT, DATABASE)
    SQLALCHEMY_DATABASE_URI = DB_URI
(3)MySQL服务准备

MySQL直接采用默认的latest MySQL镜像,不在额外编写Dockerfile,在mysql目录下放置MySQL的数据导出文件(mysqldump),在启动MySQL容器时挂载到容器内导入(source)

root@ubuntu:~/docker/docker-compose/test/mysql# ls -lh
total 80M
-rw-r--r-- 1 root root 80M 7月  10 19:04 pira.sql
(4)docker-compose.yml构建

在test项目目录下创建docker-compose.yml文件如下

version: '3'
services: 
  mysql:
    image: mysql
    restart: always
    volumes: 
      - ./mysql:/home
    environment:
      - MYSQL_ROOT_PASSWORD=gp123456
  flask:
    build: ./flask
    volumes: 
      - ./flask:/home
    links: 
      - mysql:mysql
    environment: 
      - MYSQL_USER=xiaogp
      - MYSQL_PASSWORD=gp123456
      - MYSQL_DB=pira
    ports:
      - "5000:5000"

启动docker-compose up,该命令可以自动完成包括构建镜像,(重新)创建服务,启动服务

  • 默认前台运行:docker-compose up启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。当通过Ctrl+c停止命令时,所有容器将会停止。如果希望在后台启动并运行所有的容器,使用docker-compose up -d
  • 重建镜像和重启容器:如果服务容器已经存在,并且在创建容器后更改了服务的配置(即docker-compose.yml文件)或者镜像,那么docker-compose会停止容器,然后重新创建容器
  • 指定docker-compose.yml文件:docker-compose up需要配合docker-compose.yml一起使用,默认位置是当前目录下的./docker-compose.yml
root@ubuntu:~/docker/docker-compose/test# docker-compose up
Starting test_mysql_1 ... done
Starting test_flask_1 ... done
Attaching to test_mysql_1, test_flask_1
mysql_1  | 2021-07-18 14:53:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.25-1debian10 started.
mysql_1  | 2021-07-18 14:53:33+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_1  | 2021-07-18 14:53:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.25-1debian10 started.
mysql_1  | 2021-07-18T14:53:33.633919Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.25) starting as process 1
mysql_1  | 2021-07-18T14:53:33.673943Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
flask_1  | [2021-07-18 14:53:38 +0000] [8] [INFO] Starting gunicorn 20.0.4
flask_1  | [2021-07-18 14:53:38 +0000] [8] [INFO] Listening at: http://0.0.0.0:5000 (8)
flask_1  | [2021-07-18 14:53:38 +0000] [8] [INFO] Using worker: gevent
flask_1  | [2021-07-18 14:53:38 +0000] [11] [INFO] Booting worker with pid: 11
flask_1  | [2021-07-18 14:53:38 +0000] [12] [INFO] Booting worker with pid: 12
flask_1  | [2021-07-18 14:53:38 +0000] [13] [INFO] Booting worker with pid: 13
flask_1  | [2021-07-18 14:53:39 +0000] [14] [INFO] Booting worker with pid: 14
flask_1  | [2021-07-18 14:53:39 +0000] [15] [INFO] Booting worker with pid: 15
flask_1  | [2021-07-18 14:53:39 +0000] [16] [INFO] Booting worker with pid: 16
flask_1  | [2021-07-18 14:53:39 +0000] [17] [INFO] Booting worker with pid: 17
flask_1  | [2021-07-18 14:53:39 +0000] [18] [INFO] Booting worker with pid: 18
flask_1  | [2021-07-18 14:53:39 +0000] [19] [INFO] Booting worker with pid: 19

启动成功,分别创建了两个容器test_mysql_1和test_flask_1,都是以项目和服务(目录结构)进行命令,可以使用docker-compose imagesdocker-compose ps查看,也可以使用docker imagesdocker ps查看到

root@ubuntu:~/docker/docker-compose/test# docker-compose images
 Container     Repository    Tag       Image Id       Size  
------------------------------------------------------------
test_flask_1   test_flask   latest   6a05c4dd18fe   1.009 GB
test_mysql_1   mysql        latest   5c62e459e087   555.7 MB

分别启动了两个容器,test_mysql_1和test_flask_1

root@ubuntu:~/docker/docker-compose/test# docker-compose ps
    Name                  Command               State           Ports         
------------------------------------------------------------------------------
test_flask_1   /bin/sh -c gunicorn -c gun ...   Up      0.0.0.0:5000->5000/tcp
test_mysql_1   docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp   

下一步进入MySQL容器进行用户创建和导入数据

root@ubuntu:~/docker/docker-compose/test# docker exec -it test_mysql_1 /bin/bash
root@69bbf80dbb39:/# cd /home/
root@69bbf80dbb39:/home# ls
pira.sql
root@69bbf80dbb39:/home# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 27
...

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database pira default charset utf8mb4;
Query OK, 1 row affected (0.12 sec)

mysql> use pira;
Database changed
mysql> source pira.sql;
Query OK, 0 rows affected (0.00 sec)
...

下一步创建xiaogp用户,并且赋予全部表权限

mysql> create user 'xiaogp'@'%' identified by 'gp123456';
Query OK, 0 rows affected (0.14 sec)

mysql> grant all privileges on *.* to 'xiaogp'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> select host, user from user;
+-----------+---------------+
| host      | user          |
+-----------+---------------+
| localhost  | root          |
| %         | xiaogp        |
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
5 rows in set (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

测试远程登录ok

root@ubuntu:~/docker/docker-compose/test# mysql -h172.17.0.3 -p3306 -uxiaogp -pgp123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.34 MySQL Community Server (GPL)

mysql> 

数据库配置完成后访问web项目地址http://127.0.0.1:5000/PiraScore/,启动成功,在docker-compose终端也能查看到相关日志

...
flask_1  | 2021-07-19 12:26:48,925 INFO sqlalchemy.engine.base.Engine SELECT count(*) AS count_1 
flask_1  | FROM (SELECT pira_score.ent_name AS pira_score_ent_name, pira_score.score AS pira_score_score 
flask_1  | FROM pira_score 
flask_1  | WHERE pira_score.datetime = %(datetime_1)s) AS anon_1
flask_1  | 2021-07-19 12:26:48,925 INFO sqlalchemy.engine.base.Engine {'datetime_1': '2020-12-07'}
flask_1  | [2021-07-19 12:26:48,991] INFO in __init__: {"AccessLog": {"status_code": 200, "method": "GET", "ip": "172.19.0.1", "url": "http://127.0.0.1:5000/PiraScore/", "requestId": "7b34e51f19aa4c899934c686184a632f"}}
...

docker-compose.yml相关参数介绍

整理一下docker-compose.yml中的参数写法

(1)镜像相关
  • build:构建镜像,将在docker-compose中构造镜像,而不是使用已经在docker主机存在的镜像,需要指定Dockerfile所在的目录,一般指定某个服务目录
  • image:使用镜像,将使用docker主机已经存在的docker镜像,如果不存在则去指定的中央仓库/私服拉取
(2)容器启动相关
  • environment:环境变量配置,是列表形式,格式和docker run -e一致,是等于号=连接的方式
  • ports:端口映射到宿主机,是列表形式,格式和docker run -p一致,是冒号连接的字符串格式
  • volumes:挂载目录到容器,是列表格式,格式和docker run -v一致,是冒号连接的宿主机目录和容器目录
  • container_name:容器名,默认是项目名服务名序号,可以手动指定容器名
(3)容器间关系
  • depends_on:依赖关系,是列表格式,设置容器启动的前后依赖关系
  • links:容器间网络连接,是列表格式,接收容器可以通过指定的hostname访问源容器的IP,默认docker-compose.yml的服务名就可以作为hostname,也可以在某服务下手动指定hostname参数,格式和docker run -link一致,冒号间隔连接服务名和别名

docker-compose相关命令介绍

  • docker-compose up:构建和启动服务,指定-d后台启动,指定-f指定yml文件位置
  • docker-compose ps:列出所有的容器服务
  • docker-compose stop:停止所有在运行的容器,需要在项目的根目录下(yml同级目录)运行
  • docker-compose down:停止和删除项目容器
  • docker-compose logs:查看项目日志,-f跟踪查看
  • docker-compose rm:删除停止的容器

docker-compose + Harbor实践

你可能感兴趣的:(Docker:docker-compose多容器编排管理,部署Flask+MySQL Web应用)