原文地址:http://dockone.io/article/2500
Docker提供了容器級別的資源隔離。由於Python的外部依賴管理中存在的問題,我們通常會使用virtualenv來對不同的項目創建其唯一的依賴環境。這時利用Docker進行Python開發,可以輕松解決不同Python項目之間的依賴隔離問題。
作為應用程序,我們通常需要依賴於多種外部服務,比如數據庫、緩存服務等等。Docker-compose就是在Docker容器的基礎上,提供了統一的容器編排語言,可以讓你更輕松的利用Docker構建你的應用環境。
第一步:編寫Dockerfile
使用requirements.txt定義第三方python包依賴
# cat requirements.txt Flask flask-assets redis pymongo
項目目錄結構
# tree . ├── docker-compose-flask.yml ├── docker-compose.yml -> docker-compose-flask.yml ├── Dockerfile ├── requirements.txt └── server.py 0 directories, 5 files
Dockerfile文件內容
# cat Dockerfile FROM centos:6.6 ADD . /app WORKDIR /app RUN yum install -y wget RUN wget -q -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo && wget -q -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo RUN yum install -y python-devel python-pip RUN pip install --upgrade pip && pip install -r requirements.txt CMD server.py
server.py內容
# cat server.py from flask import Flask from flask import request import redis import pymongo r=redis.Redis(host='redis',port=6379) r.delete('key') r.set('key','kaixin001') r.expire('key', 10) redis_value = r.get('key') print redis_value #redis_value = "dongsheng" app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def home(): return '<h1>Home %s</h1>' % redis_value @app.route('/signin', methods=['GET']) def signin_form(): return '''<form action="/signin" method="post"> <p><input name="username"></p> <p><input name="password" type="password"></p> <p><button type="submit">Sign In</button></p> </form>''' @app.route('/signin', methods=['POST']) def signin(): if request.form['username']=='admin' and request.form['password']=='password': return '<h3>Hello, admin!</h3>' return '<h3>Bad username or password.</h3>' if __name__ == '__main__': app.run('0.0.0.0',debug=True)
在Dockerfile中,我們主要目的:通過requirements.txt文件安裝第三方的Python庫依賴;利用Docker的容器隔離,可以忽略掉很多在本地開發中需要使用的東西,比如virtualenv。
第二步:編排容器
在案例中,應用程序依賴了mongodb作為數據存儲服務,以及redis作為緩存服務。在一般情況下,作為開發團隊要么我們搭建統一的mongodb;要不就每個人在開發機上單獨部署。
而在Docker中,我們則不在需要做這么多無用的事情。 Docker官方提供了大量的基礎容器,基本涵蓋了日常開發中我們需要的大部分依賴。 在https://hub.docker.com/我們可以搜索到我們需要的基礎鏡像。
比如mongodb以及redis,在docker-hub上官方都提供了容器話的服務。
以redis容器為例,我們在本地搭建redis服務要做的事情主要包括兩步:
docker pull redis:latest
docker run -d -p 6379:6379 redis
這個時候我們就可以通過訪問0.0.0.0:6379來訪問我們的redis服務器了。
我們也可以通過Docker原生的命令來連接我們的應用容器和redis容器,以使我們的代碼能夠正常的訪問redis服務
docker run --name some-app --line some-redis:redis -d application-that-uses-redis
而事實上,我們可以使用更加簡化的方式來定義我們的容器組合管理,使用Docker-compose來定義我們的容器組合關系。
# cat docker-compose.yml web: build: . ports: - 5000:5000 links: - redis - mongo working_dir: /app volumes: - .:/app command: python server.py redis: image: redis:latest mongo: image: mongo
這里我們定義了3個容器web、redis、mongo。 其中,web容器是通過當前目錄的Dockerfile進行構建,同時將當前目錄掛在到/app目錄。 而redis和mongo則直接使用官方進行。
通過使用links,我們可以在web容器中通過 ‘redis:6379’以及’mongo:21707’直接訪問相應的服務。
第三步:開始coding
docker-compose up -d
Docker會根據當前的目錄下得Dockerfile構建基礎鏡像,並且使用python server.py運行程序,並且運行redis以及mongo服務。
同時由於使用了volumes掛載了本地目錄到/app,此時如果我們是開啟的Debug模式,我們就可以直接在本地使用你喜歡的文本編輯器去編寫代碼,並且更新的代碼能夠實時被重新加載。
當然在使用Docker中最漫長的過程就是,下鏡像,下鏡像&下鏡像。
第四步:效果展示