docker-compose 运行 Flask 应用最佳实践


背景

  以前部署应用,需要各种环境配置,各种shell操作才能搭建一套可用的服务。现在有了Docker之后,部署方式变了更加容易,不容易出现配置错误,环境不一致问题。解决了在本地环境可以运行,迁移到线上出现各种问题,这些问题大多出现在线上和本地环境有差异,配置容易出现错误等情况。那么docker-compose 和 docker 之间存在着什么联系呢?

先来看看docker-compose 的定义:
「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」

  我们知道 docker 可以通过 Dockerfile 模板文件来定义一个应用容器。实际应用中,经常遇到多个容器相配合运行一套应用程序的情况。比如,实现一个Flask应用,除了 Flask 服务本身之外,还需要一些数据库服务容器等。Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
  通过 Docker-Compose 用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何管理编排的问题。

实施步骤

使用 Dockerfile 定制镜像

  镜像的定制实际上就是定制每一层所添加的配置、文件,因为 Flask 应用需要一些环境依赖才能运行起来。所以想要将 Flask 应用运行在 Docker 容器中,该容器必须将该应用所有的环境依赖安装好。而 Dockerfile 就是提供给我们配置相关的环境依赖等操作。Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

下面以我的GitHub项目 flask-v2ex 应用的 Dockerfile 文件为例:

FROM daocloud.io/python:3.5

MAINTAINER Guoweikuang <guoweikuang2015@gmail.com>
RUN mkdir -p /home/guoweikuang/app 
WORKDIR /home/guoweikuang/app 

ADD ./requirements.txt /home/guoweikuang/app/requirements.txt 

RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip 
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt 

ADD . /home/guoweikuang/app 

CMD python manage.py runserver -h 0.0.0.0

FROM: 指定了基础镜像,以该镜像为基础,在其上进行定制操作
MAINTAINER: 用来指定镜像创建者信息
RUN: 创建了 **/home/guoweikuang/app** 文件夹 (后面 RUN pip3 安装Python扩展库)
WORKDIR: 切换目录,可以多次切换(相当于cd命令)
ADD: 从本地目录相应文件拷贝到容器路径里
CMD: 设置container启动时执行的操作,运行 Flask 应用并设置host为0.0.0.0

编写 docker-compose.yml 文件

docker-compose.yml 文件将把所有的东西关联起来。它描述了应用的构成(一个 web 服务和一个数据库)、使用的 Docker 镜像、镜像之间的连接、挂载到容器的卷,以及服务开放的端口。

下面以我的GitHub项目 flask-v2ex 应用的 docker-compose.yml 文件为例:

version: '2'

services:
  web:
    build: .
    container_name: flask_v2ex
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

compose 中定义了两个服务 web 和 redis。

  • web 服务
    • build: 使用当前目录的 Dockerfile build 的镜像
    • ports: 映射宿主机 5000 端口到容器的 5000 端口
    • container_name: 指定了容器的名字
  • redis 服务
    • image: 使用 Docker Hub 中的 redis 镜像

使用 compose 构建并运行 Flask 应用

在运行 docker-compose up 之前,需要做一些修改,把项目里关于redis连接配置进行修改

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

修改为:

r = redis.Redis(host='redis', port=6379, decode_responses=True)

在flask-v2ex 项目的根目录下使用 docker-compose up 命令,如下所示:

$ docker-compose up

Starting flask_v2ex         ... done
Starting flask_v2ex_redis_1 ... done
Attaching to flask_v2ex_redis_1, flask_v2ex
redis_1  | 1:C 01 Jul 07:46:52.053 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 01 Jul 07:46:52.053 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 01 Jul 07:46:52.053 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1  | 1:M 01 Jul 07:46:52.064 * Running mode=standalone, port=6379.
redis_1  | 1:M 01 Jul 07:46:52.064 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1  | 1:M 01 Jul 07:46:52.064 # Server initialized
redis_1  | 1:M 01 Jul 07:46:52.065 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1  | 1:M 01 Jul 07:46:52.065 * DB loaded from disk: 0.000 seconds
redis_1  | 1:M 01 Jul 07:46:52.065 * Ready to accept connections
flask_v2ex |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
flask_v2ex |  * Restarting with stat
flask_v2ex |  * Debugger is active!
flask_v2ex |  * Debugger PIN: 742-073-002

可以看到 Docker 守护进程里监听着 5000 端口了。可以通过http://localhost:5000 访问 Flask 应用。

docker-compose 使用

  • docker-compose up -d : 后台运行
  • docker-compose stop: 停止正在运行的服务
  • docker-compose down: 关闭所有容器并删除,默认保留 数据卷
  • docker-compose ps:列出当前运行的服务状态和相关信息
$ docker-compose ps
       Name                     Command               State           Ports
------------------------------------------------------------------------------------
flask_v2ex           /bin/sh -c python manage.p ...   Up      0.0.0.0:5000->5000/tcp
flask_v2ex_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp
  • docker-compose run: 一次性命令。 例如查看 web 服务的环境变量:
$ docker-compose run web env 

PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=e4b6b17f39dc
TERM=xterm
LANG=C.UTF-8
GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D
PYTHON_VERSION=3.5.4
PYTHON_PIP_VERSION=9.0.1
HOME=/root

如果需要停止已经运行中的服务,可以通过ctrl + c 或者 docker-compose stop 来停止服务。

参考

Docker从入门到实践 --实战Django
使用Dockerfile构建Docker镜像

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

推荐阅读更多精彩内容

  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,270评论 1 39
  • 一 、什么是 Docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国...
    Blazzer阅读 3,101评论 0 13
  • 第一次用这支水笔的时候,觉得写字可丑了,而且笔好粗啊。 然后我果断换了钢笔练字,就是这支略有颜值的钢笔 这些天一直...
    顾陌涵阅读 184评论 0 0
  • 今天心情莫名地好, 阳光、花儿、小鸟都显得那么亲切 快到家的路上,偶遇一棵枇杷树, 满树的枇杷像在对我微笑, 刚下...
    bayseed阅读 236评论 1 2
  • 三十年前的同学回到母校,想寻找青春走过的痕迹,可母校三十年的发展,物是人非。但仍然有着被人遗忘了而没有被改变...
    云水居士阅读 189评论 0 2