用docker-compose构建flask应用

灵活性被过分高估—约束才是解放。- Ruby on Rails作者汉森。

最近没事的时候折腾docker,发现用docker-compose构建个flask小应用真的是炒鸡方便。一步一步来。
系统用的是ubuntu14.04。如果没有docker的话先装docker,然后装docker-compose,这个工具是python开发的,所以可以用pip安装。

# 方法1
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo 'deb https://apt.dockerproject.org/repo ubuntu-trusty main' | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt-get purge lxc-docker
sudo apt-cache policy docker-engine
sudo apt-get install -y docker-engine
sudo service docker start
sudo pip install docker-compose

# 方法2
# https://get.daocloud.io 或者用国内的daocloud装docker
curl -sSL https://get.daocloud.io/docker | sh
curl -L https://get.daocloud.io/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

之后可以随便创建一个目录,比如flask_compose, 目录结构如下:

1
2
3
4
5
6
7
flask_compose
├─- app.py
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
└── templates
└── todo.html

app.py 创建个简单的路由文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-


from flask import Flask, render_template, url_for, request, redirect
from pymongo import MongoClient
from redis import Redis

r = Redis(host='redis', port=6379)
app = Flask(__name__)

m = MongoClient('mongo', 27017)
db = m.tododb

@app.route('/')
def todo():
    _items = db.tododb.find()
    items = [item for item in _items]
    return render_template('todo.html', items=items)


@app.route('/new', methods=['POST'])
def new():
    item_doc = {
        'name': request.form['name'],
        'description': request.form['description']
    }
    db.tododb.insert_one(item_doc)
    return redirect(url_for('todo'))


@app.route('/redis')
def hello():
    r.incr('hits')
    return 'I have been seen %s times' % r.get('hits')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Dockerfile

FROM python:2.7
ADD . /flask_compose
WORKDIR /flask_compose
RUN pip install -r requirements.txt

docker-compose.yml 这里应用连接到redis和mongodb非常容易,配置下就好:

web:
    build: .
    command: python -u app.py
    ports:
        - "5000:5000"
    volumes:
        - .:/flask_compose
    links:
        - mongo
        - redis
mongo:
    image: mongo:3.0.2

redis:
    image: redis

requirements.txt

flask
redis
pymongo

templates/todo.html

<form action="/new" method="POST">
  <input type="text" name="name"></input>
  <input type="text" name="description"></input>
  <input type="submit"></input>
</form>
{% for item in items %}
  <h1> {{ item.name }} </h1>
  <p> {{ item.description }} <p>
{% endfor %}

构建

上边文件都有了,一个基本的使用redis和mongodb的flask页面就有了,接下来用docker-compose命令构建:
sudo docker-compose build
这一步可以能会花很长时间,包括下载镜像和构建。完成后运行:
sudo docker-compose up
访问本地http://localhost:5000 就可以看见页面了, 访问http://localhost:5000/redis 可以看见redis读取的效果。
注:写这个博客遇到了一个小问题,templates/todo.html里的jinja2模板语言for循环标签和hexo的冲突,可以用raw标签包含html代码,这样就可以正确显示了


Ref:

https://docs.docker.com/v1.5/compose/
http://containertutorials.com/docker-compose/flask-mongo-compose.html
https://hexo.io/docs/tag-plugins.html#Code-Block