Docker的Fig 項目
在你的應用裏面添加一個 fig.yml
文件,並指定一些簡單的內容,執行 fig up
它就能幫你快速建立起一個容器
快速搭建基於 Docker 的隔離開發環境
使用 Dockerfile
文件指定你的應用環境,讓它能在任意地方復制使用:
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
在 fig.yml
文件中指定應用使用的不同服務,讓它們能夠在一個獨立的環境中一起運行:
web:
build: .
command: python app.py
links:
- db
ports:
- "8000:8000"
db:
image: postgres
*註意不需要再額外安裝 Postgres 了!
接著執行命令 fig up
,然後 Fig 就會啟動並運行你的應用了。
Fig 可用的命令有:
- 啟動、停止,和重建服務
- 查看服務的運行狀態
- 查看運行中的服務的輸入日誌
- 對服務發送命令
快速上手
我們試著讓一個基本的 Python web 應用運行在 Fig 上。這個實驗假設你已經知道一些 Python 知識,如果你不熟悉,但清楚概念上的東西也是沒有問題的。
首先,安裝 Docker 和 Fig
為你的項目創建一個目錄
$ mkdir figtest
$ cd figtest
進入目錄,創建 app.py
,這是一個能夠讓 Redis 上的一個值自增的簡單 web 應用,基於 Flask 框架。
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host=‘redis‘, port=6379)
@app.route(‘/‘)
def hello():
redis.incr(‘hits‘)
return ‘Hello World! I have been seen %s times.‘ % redis.get(‘hits‘)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
在 requirements.txt
文件中指定應用的 Python 依賴包。
flask
redis
下一步我們要創建一個包含應用所有依賴的 Docker 鏡像,這裏將闡述怎麽通過 Dockerfile
文件來創建。
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
以上的內容首先告訴 Docker 在容器裏面安裝 Python ,代碼的路徑還有Python 依賴包。關於 Dockerfile 的更多信息可以查看 鏡像創建 和 Dockerfile 使用
接著我們通過 fig.yml
文件指定一系列的服務:
web:
build: .
command: python app.py
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: redis
這裏指定了兩個服務:
- web 服務,通過當前目錄的
Dockerfile
創建。並且說明了在容器裏面執行python app.py
命令 ,轉發在容器裏開放的 5000 端口到本地主機的 5000 端口,連接 Redis 服務,並且掛載當前目錄到容器裏面,這樣我們就可以不用重建鏡像也能直接使用代碼。 - redis 服務,我們使用公用鏡像 redis。
- 現在如果執行
fig up
命令 ,它就會拉取 redis 鏡像,啟動所有的服務。
$ fig up
Pulling image redis...
Building web...
Starting figtest_redis_1...
Starting figtest_web_1...
redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
web_1 | * Running on http://0.0.0.0:5000/
這個 web 應用已經開始在你的 docker 守護進程裏面監聽著 5000 端口了(如果你有使用 boot2docker ,執行 boot2docker ip
,就會看到它的地址)。
如果你想要在後臺運行你的服務,可以在執行 fig up
命令的時候添加 -d
參數,然後使用 fig ps
查看有什麽進程在運行。
$ fig up -d
Starting figtest_redis_1...
Starting figtest_web_1...
$ fig ps
Name Command State Ports
-------------------------------------------------------------------
figtest_redis_1 /usr/local/bin/run Up
figtest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
fig run
指令可以幫你向服務發送命令。例如:查看 web 服務可以獲取到的環境變量:
$ fig run web env
執行幫助命令 fig --help
查看其它可用的參數。
假設你使用了 fig up -d
啟動 Fig,可以通過以下命令停止你的服務:
$ fig stop
以上內容或多或少的講述了如何使用Fig 。通過查看下面的引用章節可以了解到關於命令、配置和環境變量的更多細節。如果你有任何想法或建議,可以在 GitHub 上提出。
安裝 Fig
首先,安裝 1.3 或者更新的 Docker 版本。
如果你的工作環境是 OS X ,可以通過查看 Mac 安裝指南(英文) ,完成安裝 Docker 和 boot2docker 。一旦 boot2docker 運行後,執行以下指令設置一個環境變量,接著 Fig 就可以和它交互了。
$(boot2docker shellinit)
*如果想避免重啟後重新設置,可以把上面的命令加到你的 ~/.bashrc
文件裏。
關於 Ubuntu
還有 其它的平臺
的安裝,可以參照 Ubuntu 安裝指南(中文) 以及 官方安裝手冊(英文)。
下一步,安裝 Fig :
curl -L https://github.com/docker/fig/releases/download/1.0.1/fig-`uname -s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig
*如果你的 Docker 是管理員身份安裝,以上命令可能也需要相同的身份。
目前 Fig 的發行版本只支持 OSX 和 64 位的 Linux 系統。但因為它是用 Python 語言寫的,所以對於其它平臺上的用戶,可以通過 Python 安裝包來完成安裝(支持的系統同樣適用)。
$ sudo pip install -U fig
到這裏就已經完成了。 執行 fig --version
,確認能夠正常運行。
Docker中Fig命令參考
Fig客戶端參考
大部分命令都可以運行在一個或多個服務上。如果沒有特別的說明,這個命令則可以應用在所有的服務上。
執行 fig [COMMAND] --help
查看所有的使用說明。
選項
--verbose
顯示更多信息。
--version
打印版本並退出。
-f, --file FILE
使用特定的Fig文件,默認使用fig.yml。
-p, --project-name NAME
使用特定的項目名稱,默認使用文件夾名稱。
命令
build
構建或重新構建服務。
服務一旦構建後,將會標記為project_service,例如figtest_db。 如果修改服務的 Dockerfile
或構建目錄信息,你可以運行 fig build
來重新構建。
help
獲得一個命令的幫助。
kill
強制停止服務容器。
logs
查看服務的輸出。
port
打印端口綁定的公共端口。
ps
列出所有容器。
pull
拉取服務鏡像。
rm
刪除停止的服務容器。
run
在一個服務上執行一個命令。
例如:
$ fig run web python manage.py shell
默認情況下,鏈接的服務將會啟動,除非這些服務已經在運行中。
一次性命令會在使用與服務的普通容器相同的配置的新容器中開始運行,然後卷、鏈接等等都將會按照期望創建。 與普通容器唯一的不同就是,這個命令將會覆蓋原有的命令,如果端口有沖突則不會創建。
鏈接還可以在一次性命令和那個服務的其他容器間創建,然後你可以像下面一樣進行一些操作:
$ fig run db psql -h db -U docker
如果你不希望在執行一次性命令時啟動鏈接的容器,可以指定--no-deps選項:
$ fig run --no-deps web python manage.py shell
scale
設置一個服務需要運行的容器個數。
通過service=num的參數來設置數量。例如:
$ fig scale web=2 worker=3
start
啟動一個服務已經存在的容器.
stop
停止一個已經運行的容器,但不刪除它。通過 fig start
可以再次啟動這些容器。
up
構建,(重新)創建,啟動,鏈接一個服務的容器。
鏈接的服務都將會啟動,除非他們已經運行。
默認情況, fig up
將會聚合每個容器的輸出,而且如果容器已經存在,所有容器將會停止。如果你運行 fig up -d
,將會在後臺啟動並運行所有的容器。
默認情況,如果這個服務的容器已經存在, fig up
將會停止並重新創建他們(保持使用volumes-from掛載的卷),以保證 fig.yml
的修改生效。如果你不想容器被停止並重新創建,可以使用 fig up --no-recreate
。如果需要的話,這樣將會啟動已經停止的容器。
環境變量
環境變量可以用來配置Fig的行為。
變量以DOCKER_開頭,它們和用來配置Docker命令行客戶端的使用一樣。如果你在使用 boot2docker , $(boot2docker shellinit)
將會設置它們為正確的值。
FIG_PROJECT_NAME
設置通過Fig啟動的每一個容器前添加的項目名稱.默認是當前工作目錄的名字。
FIG_FILE
設置要使用的 fig.yml
的路徑。默認路徑是當前工作目錄。
DOCKER_HOST
設置docker進程的URL。默認docker client使用 unix:///var/run/docker.sock
。
DOCKER_TLS_VERIFY
如果設置不為空的字符,允許和進程進行 TLS 通信。
DOCKER_CERT_PATH
配置 ca.pem
的路徑, cert.pem
和 key.pem
文件用來進行TLS驗證.默認路徑是 ~/.docker
。
Docker fig.yml參考
每個在 fig.yml
定義的服務都需要指定一個鏡像或鏡像的構建內容。像 docker run
的命令行一樣,其它內容是可選的。
docker run
在 Dockerfile
中設置的選項(例如:CMD
, EXPOSE
, VOLUME
, ENV
) 作為已經提供的默認設置 - 你不需要在 fig.yml
中重新設置。
image
這裏可以設置為標簽或鏡像ID的一部分。它可以是本地的,也可以是遠程的 - 如果鏡像在本地不存在,Fig
將會嘗試拉去這個鏡像。
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
build
指定 Dockerfile
所在文件夾的路徑。 Fig
將會構建這個鏡像並給它生成一個名字,然後使用這個鏡像。
build: /path/to/build/dir
command
覆蓋默認的命令。
command: bundle exec thin -p 3000
links
在其它的服務中連接容器。使用服務名稱(經常也作為別名)或服務名稱加服務別名 (SERVICE:ALIAS)
都可以。
links:
- db
- db:database
- redis
可以在服務的容器中的 /etc/hosts
裏創建別名。例如:
172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis
環境變量也將被創建 - 細節查看環境變量參考章節。
ports
暴露端口。使用宿主和容器 (HOST:CONTAINER)
或者僅僅容器的端口(宿主將會隨機選擇端口)都可以。
註:當使用 HOST:CONTAINER
格式來映射端口時,如果你使用的容器端口小於60你可能會得到錯誤得結果,因為 YAML
將會解析 xx:yy
這種數字格式為60進制。所以我們建議用字符指定你得端口映射。
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
expose
暴露不發布到宿主機的端口 - 它們只被連接的服務訪問。僅僅內部的端口可以被指定。
expose:
- "3000"
- "8000"
volumes
卷掛載路徑設置。可以設置宿主機路徑 (HOST:CONTAINER)
或訪問模式 (HOST:CONTAINER:ro)
。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
volumes_from
從另一個服務或容器掛載所有卷。
volumes_from:
- service_name
- container_name
environment
設置環境變量。你可以使用數組或字典兩種格式。
環境變量在運行 Fig
的機器上被解析成一個key。它有助於安全和指定的宿主值。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
net
設置網絡模式。使用和 docker client
的 --net
參數一樣的值。
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
dns
配置DNS服務器。它可以是一個值,也可以是一個列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged
這些都是和 docker run
對應的一個值。
working_dir: /code
entrypoint: /code/entrypoint.sh
user: postgresql
hostname: foo
domainname: foo.com
mem_limit: 1000000000
privileged: true
Docker Fig環境變量參考
*註意: 現在已經不推薦使用環境變量鏈接服務。替代方案是使用鏈接名稱(默認就是被連接的服務名字)作為主機名來鏈接。詳情查看 fig.yml章節。
Fig 使用 Docker 鏈接來暴露一個服務的容器給其它容器。每一個鏈接的容器會註入一組以容器名稱的大寫字母開頭得環境變量。
查看一個服務有那些有效的環境變量可以執行 fig run SERVICE env
。
name_PORT
完整URL,例如: DB_PORT=tcp://172.17.0.5:5432
name_PORT_num_protocol
完整URL,例如: DB_PORT_5432_TCP=tcp://172.17.0.5:5432
name_PORT_num_protocol_ADDR
容器的IP地址,例如: DB_PORT_5432_TCP_ADDR=172.17.0.5
name_PORT_num_protocol_PORT
暴露端口號,例如: DB_PORT_5432_TCP_PORT=5432
name_PORT_num_protocol_PROTO
協議(tcp 或 udp),例如: DB_PORT_5432_TCP_PROTO=tcp
name_NAME
完整合格的容器名稱,例如: DB_1_NAME=/myapp_web_1/myapp_db_1
Docker Fig實戰 Django
使用 Django 入門 Fig
我們現在將使用 Fig 配置並運行一個 Django/PostgreSQL 應用。在此之前,先確保 Fig 已經 安裝。
在一切工作開始前,需要先設置好三個必要的文件。
第一步,因為應用將要運行在一個滿足所有環境依賴的 Docker 容器裏面,那麽我們可以通過編輯 Dockerfile
文件來指定 Docker 容器要安裝內容。內容如下:
FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
以上內容指定應用將使用安裝了 Python 以及必要依賴包的鏡像。更多關於如何編寫 Dockerfile 文件的信息可以查看 鏡像創建 和 Dockerfile 使用。
第二步,在 requirements.txt
文件裏面寫明需要安裝的具體依賴包名 。
Django
psycopg2
就是這麽簡單。
第三步,fig.yml
文件將把所有的東西關聯起來。它描述了應用的構成(一個 web 服務和一個數據庫)、使用的 Docker 鏡像、鏡像之間的連接、掛載到容器的卷,以及服務開放的端口。
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
查看 fig.yml
章節 了解更多詳細的工作機制。
現在我們就可以使用 fig run
命令啟動一個 Django 應用了。
$ fig run web django-admin.py startproject figexample .
Fig 會先使用 Dockerfile
為 web 服務創建一個鏡像,接著使用這個鏡像在容器裏運行 django-admin.py startproject figexample .
指令。
這將在當前目錄生成一個 Django 應用。
$ ls
Dockerfile fig.yml figexample manage.py requirements.txt
首先,我們要為應用設置好數據庫的連接信息。用以下內容替換 figexample/settings.py
文件中 DATABASES = ...
定義的節點內容。
DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.postgresql_psycopg2‘,
‘NAME‘: ‘postgres‘,
‘USER‘: ‘postgres‘,
‘HOST‘: ‘db‘,
‘PORT‘: 5432,
}
}
這些信息是在 postgres Docker 鏡像固定設置好的。
然後,運行 fig up
:
Recreating myapp_db_1...
Recreating myapp_web_1...
Attaching to myapp_db_1, myapp_web_1
myapp_db_1 |
myapp_db_1 | PostgreSQL stand-alone backend 9.1.11
myapp_db_1 | 2014-01-27 12:17:03 UTC LOG: database system is ready to accept connections
myapp_db_1 | 2014-01-27 12:17:03 UTC LOG: autovacuum launcher started
myapp_web_1 | Validating models...
myapp_web_1 |
myapp_web_1 | 0 errors found
myapp_web_1 | January 27, 2014 - 12:12:40
myapp_web_1 | Django version 1.6.1, using settings ‘figexample.settings‘
myapp_web_1 | Starting development server at http://0.0.0.0:8000/
myapp_web_1 | Quit the server with CONTROL-C.
這個 web 應用已經開始在你的 docker 守護進程裏監聽著 5000 端口了(如果你有使用 boot2docker ,執行 boot2docker ip
,就會看到它的地址)。
你還可以在 Docker 上運行其它的管理命令,例如對於同步數據庫結構這種事,在運行完 fig up
後,在另外一個終端運行以下命令即可:
$ fig run web python manage.py syncdb
Docker Fig實戰 Rails
使用 Rail 入門 Fig
我們現在將使用 Fig 配置並運行一個 Rails/PostgreSQL 應用。在開始之前,先確保 Fig 已經 安裝。
在一切工作開始前,需要先設置好三個必要的文件。
首先,因為應用將要運行在一個滿足所有環境依賴的 Docker 容器裏面,那麽我們可以通過編輯 Dockerfile
文件來指定 Docker 容器要安裝內容。內容如下:
FROM ruby
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
RUN bundle install
ADD . /myapp
以上內容指定應用將使用安裝了 Ruby、Bundler 以及其依賴件的鏡像。更多關於如何編寫 Dockerfile 文件的信息可以查看 鏡像創建 和 Dockerfile 使用。 下一步,我們需要一個引導加載 Rails 的文件 Gemfile
。 等一會兒它還會被 rails new
命令覆蓋重寫。
source ‘https://rubygems.org‘
gem ‘rails‘, ‘4.0.2‘
最後,fig.yml
文件才是最神奇的地方。 fig.yml
文件將把所有的東西關聯起來。它描述了應用的構成(一個 web 服務和一個數據庫)、每個鏡像的來源(數據庫運行在使用預定義的 PostgreSQL 鏡像,web 應用側將從本地目錄創建)、鏡像之間的連接,以及服務開放的端口。
db:
image: postgres
ports:
- "5432"
web:
build: .
command: bundle exec rackup -p 3000
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
所有文件就緒後,我們就可以通過使用 fig run
命令生成應用的骨架了。
$ fig run web rails new . --force --database=postgresql --skip-bundle
Fig 會先使用 Dockerfile
為 web 服務創建一個鏡像,接著使用這個鏡像在容器裏運行 rails new
和它之後的命令。一旦這個命令運行完後,應該就可以看一個嶄新的應用已經生成了。
$ ls
Dockerfile app fig.yml tmp
Gemfile bin lib vendor
Gemfile.lock config log
README.rdoc config.ru public
Rakefile db test
在新的 Gemfile
文件去掉加載 therubyracer
的行的註釋,這樣我們便可以使用 Javascript 運行環境:
gem ‘therubyracer‘, platforms: :ruby
現在我們已經有一個新的 Gemfile
文件,需要再重新創建鏡像。(這個會步驟會改變 Dockerfile 文件本身,僅僅需要重建一次)。
$ fig build
應用現在就可以啟動了,但配置還未完成。Rails 默認讀取的數據庫目標是 localhost
,我們需要手動指定容器的 db
。同樣的,還需要把用戶名修改成和 postgres 鏡像預定的一致。 打開最新生成的 database.yml
文件。用以下內容替換:
development: &default
adapter: postgresql
encoding: unicode
database: postgres
pool: 5
username: postgres
password:
host: db
test:
<<: *default
database: myapp_test
現在就可以啟動應用了。
$ fig up
如果一切正常,你應該可以看到 PostgreSQL 的輸出,幾秒後可以看到這樣的重復信息:
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick 1.3.1
myapp_web_1 | [2014-01-17 17:16:29] INFO ruby 2.0.0 (2013-11-22) [x86_64-linux-gnu]
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick::HTTPServer#start: pid=1 port=3000
最後, 我們需要做的是創建數據庫,打開另一個終端,運行:
$ fig run web rake db:create
這個 web 應用已經開始在你的 docker 守護進程裏面監聽著 3000 端口了(如果你有使用 boot2docker ,執行 boot2docker ip
,就會看到它的地址)。
Docker Fig實戰 wordpress
使用 Wordpress 入門 Fig
Fig 讓 Wordpress 運行在一個獨立的環境中很簡易。 安裝 Fig ,然後下載 Wordpress 到當前目錄:
wordpress.org/latest.tar.gz | tar -xvzf -
這將會創建一個叫 wordpress 目錄,你也可以重命名成你想要的名字。在目錄裏面,創建一個 Dockerfile
文件,定義應用的運行環境:
FROM orchardup/php5
ADD . /code
以上內容告訴 Docker 創建一個包含 PHP 和 Wordpress 的鏡像。更多關於如何編寫 Dockerfile 文件的信息可以查看 鏡像創建 和 Dockerfile 使用。
下一步,fig.yml
文件將開啟一個 web 服務和一個獨立的 MySQL 實例:
web:
build: .
command: php -S 0.0.0.0:8000 -t /code
ports:
- "8000:8000"
links:
- db
volumes:
- .:/code
db:
image: orchardup/mysql
environment:
MYSQL_DATABASE: wordpress
要讓這個應用跑起來還需要兩個文件。 第一個,wp-config.php
,它是一個標準的 Wordpress 配置文件,有一點需要修改的是把數據庫的配置指向 db
容器。
<?php
define(‘DB_NAME‘, ‘wordpress‘);
define(‘DB_USER‘, ‘root‘);
define(‘DB_PASSWORD‘, ‘‘);
define(‘DB_HOST‘, "db:3306");
define(‘DB_CHARSET‘, ‘utf8‘);
define(‘DB_COLLATE‘, ‘‘);
define(‘AUTH_KEY‘, ‘put your unique phrase here‘);
define(‘SECURE_AUTH_KEY‘, ‘put your unique phrase here‘);
define(‘LOGGED_IN_KEY‘, ‘put your unique phrase here‘);
define(‘NONCE_KEY‘, ‘put your unique phrase here‘);
define(‘AUTH_SALT‘, ‘put your unique phrase here‘);
define(‘SECURE_AUTH_SALT‘, ‘put your unique phrase here‘);
define(‘LOGGED_IN_SALT‘, ‘put your unique phrase here‘);
define(‘NONCE_SALT‘, ‘put your unique phrase here‘);
$table_prefix = ‘wp_‘;
define(‘WPLANG‘, ‘‘);
define(‘WP_DEBUG‘, false);
if ( !defined(‘ABSPATH‘) )
define(‘ABSPATH‘, dirname(__FILE__) . ‘/‘);
require_once(ABSPATH . ‘wp-settings.php‘);
第二個,router.php
,它告訴 PHP 內置的服務器怎麽運行 Wordpress:
<?php
$root = $_SERVER[‘DOCUMENT_ROOT‘];
chdir($root);
$path = ‘/‘.ltrim(parse_url($_SERVER[‘REQUEST_URI‘])[‘path‘],‘/‘);
set_include_path(get_include_path().‘:‘.__DIR__);
if(file_exists($root.$path))
{
if(is_dir($root.$path) && substr($path,strlen($path) - 1, 1) !== ‘/‘)
$path = rtrim($path,‘/‘).‘/index.php‘;
if(strpos($path,‘.php‘) === false) return false;
else {
chdir(dirname($root.$path));
require_once $root.$path;
}
}else include_once ‘index.php‘;
這些配置文件就緒後,在你的 Wordpress 目錄裏面執行 fig up
指令,Fig 就會拉取鏡像再創建我們所需要的鏡像,然後啟動 web 和數據庫容器。
接著訪問 docker 守護進程監聽的 8000 端口就能看你的 Wordpress 網站了。(如果你有使用 boot2docker ,執行 boot2docker ip
,就會看到它的地址)。
Docker的Fig 項目