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实践

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容