感謝lemonwater提醒,須要在文章開頭說明一下html
這是個python開發的基於flask服務器的一個快速web服務開發框架,java
集成開發所需部分經常使用功能,參考java中的對象管理以及實例注入的一些思路,python
還有部分後期添加的優化功能(例如請求黑名單 <--- 初步概念,防高頻訪問)之類的mysql
有任何疑問或建議歡迎聯繫 請發送郵件至 ---> ealohu@163.comlinux
新版本(1.2.4加入模塊化管理,初步拆分db模塊,在ide上不利於開發,若想ide帶部分模塊提示請使用全模塊請使用1.1.8版本)web
該文檔爲1.1.8版本文檔,新版(1.2.4)模塊命名有不一樣之處,我會盡快出文檔sql
pip install dophon
from dophon import boot ... if '__main__' == __name__: boot.run_app()
# dophon.properties.__init__.py """<div/> 配置集合<div/> author:CallMeE<div/> date:2018-06-01<div/> """ # 定義工程根目錄(必須) project_root=os.getcwd() # 此處爲服務器配置(必須,默認開啓ssl) host = '127.0.0.1' # 服務器監聽地址(全ip監聽爲0.0.0.0),默認監聽本地 port = 443 # 服務器監聽端口 ssl_context = 'adhoc' # ssl證書路徑(默認本地證書) # 此處爲路由文件夾配置 blueprint_path = ['/routes'] # route model dir path(路由文件夾名稱) # 此處爲數據庫配置 pool_conn_num = 5 # size of db connect pool() # 數據庫鏈接池鏈接數(默認5個) pydc_host = 'localhost' # 數據庫鏈接地址 pydc_port = 3306 # 數據庫鏈接端口 pydc_user = 'username' # 數據庫鏈接用戶名 pydc_password = 'password' # 數據庫鏈接密碼 pydc_database = 'database' # 鏈接數據庫名(可在後面跟鏈接參數)
快速定義:docker
from dophon import boot app = boot.get_app()
方式一:數據庫
import dophon import DemoClass _DemoRou=None app=dophon.blue_print( inject_config={ 'inj_obj_list': { '_DemoRou': DemoClass }, 'global_obj': globals() }, # 此處爲自動注入參數配置(非必須,不須要請填入空字典) name='demo', # 此處爲路由代號(必須,不能重複) import_name=__name__ # 此處爲路由初始化名稱(必須,無特定需求填寫__name__) )
方式二:
from flask import Blueprint app=Blueprint('demo',__name__) # 具體參數參照flask.Blueprint
方式一: 參考<4.路由.方式一>
方式二:
from dophon import annotation import class_1 import class_2 inject_prop={ 'obj_1':class_1.obj1, 'obj_2':class_2.obj1 } obj_1=None obj_2=None @Autowired.OuterWired(inject_prop,globals()) def inject_method(): pass inject_method()
方式三(不推薦):
from dophon import annotation import class_1 import class_2 obj_1=None obj_2=None @Autowired.InnerWired([class_1.obj1,class_2.obj1],['obj_1','obj_2'],globals()) def inject_method(): pass inject_method()
ps:上列注入配置可經過引入外部對象進行管理,即建立一個文件經過引入文件中變量實現配置的統一管理
注入前必須定義一個實例管理器
from dophon.annotation import * class OwnBeanConfig(BeanConfig): """ 實例管理器必須繼承BeanConfig) 注意!!! 實例定義關鍵字必須惟一 """ # 方式一 @bean() def demo_obj_1(self): """ 此處返回管理關鍵字爲demo_obj_1的DemoObj()實例 """ return DemoObj() # 方式二 @bean(name='Demo') def demo_obj_2(self): """ 此處返回管理關鍵字爲Demo的DemoObj()實例 """ return DemoObj()
with OwnBeanConfig() as config: pass
OwnBeanConfig()() # 注意是兩個括號
ps:推薦使用BeanConfig子類做爲實例批量管理
from dophon.annotation import * bean=Bean('demo_obj_1') # 此處獲取管理關鍵字爲demo_obj_1對應的實例 # 或者使用類來定位實例 bean=Bean(DemoObj) # 多個同類實例會拋出語義錯誤
首先引入註解模塊
from dophon import annotation
或者
from dophon.annotation import *
返回json格式數據
from dophon.annotation import * @ResponseBody() def fun(): return 'result' # response -> result @ResponseBody() def fun(): return { 'message':'result' } # response -> { 'message' : 'result' } @ResponseBody() def fun(): result={ 'message':'result' } return result # response -> { 'message' : 'result' }
返回對應頁面(默認路由目錄下html文件)
from dophon.annotation import * @ResponseTemplate('index.html') def ...
ps:額外管理頁面路徑請在路由定義(dophon.blue_print())中配置template_folder,聽從linux系統cd路徑語法
自動配置請求中的參數(分離形式) 推薦指定裝飾器中的kwarg_list參數的列表(也就是說形參的列表形式),不然會出現參數混亂(嚴重)
from dophon.annotation import * @AutoParam(kwarg_list=['param_1','param_2','param_3']) def fun(param_1,param_2,param_3): print(param_1) print(param_2) print(param_3) # request -> (params){ 'param_1' : '1' , 'param_2' : '2' , 'param_3' : '3' } # console -> 1 # 2 # 3
因爲本裝飾器存在參數混亂,推薦使用FullParam參數裝飾器(下文)
自動配置請求中的參數(集中形式),表現形式爲dict 賦值參數無名稱要求,其中默認賦值參數列表中的第一個參數
from dophon.annotation import * @FullParam() def fun(args): print(args) # request -> (params){ 'param_1' : '1' , 'param_2' : '2' , 'param_3' : '3' } # console -> { 'param_1' : '1' , 'param_2' : '2' , 'param_3' : '3' }
簡化版路由(同app.route())
from dophon.annotation import * from dophon import boot app=boot.get_app() @RequestMapping(app=app,'/test',['get']) def fun(): pass
參考<5.對象注入>
from dophon.annotation import * @AutoWired() def fun(): pass
from dophon import logger logger.inject_logger(globals())
其中: globals()爲注入日誌記錄功能的變量域,能夠爲本地變量域,局部變量域,也能夠爲自定義變量管理域
控制檯帶顏色輸出(略醜)
日誌輸出格式以下:
'%(levelname)s : (%(asctime)s) ==> ::: %(message)s'
例如:
INFO : (2018-08-02 15:34:11) ==> ::: 執行批量實例管理初始化
格式代碼以下:
經過自定義配置文件(application.py)定義日誌配置:
# 此處爲日誌配置 logger_config={ # 'filename': 'app.log', # 'level': 'logging.DEBUG', 'format': '%(levelname)s : <%(module)s> (%(asctime)s) ==> %(filename)s {%(funcName)s} [line:%(lineno)d] ::: %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S' }
// 消息隊列單機承載上限爲推薦30-50個話題(tag)
上面這句話已經沒有任何意義了,後續版本(1.18+)中經過封裝了彈性容量的線程池(默認係數爲2)進行自動伸縮尺容量
可經過自定義配置配置上限
<application.py>
msg_queue_max_num = 30 # 消息隊列線程池承載上限
推薦使用json格式傳遞數據(便於消費者轉義數據)
from dophon.msg_queue import * @producer(tag='DEMO_TAG') def producer(): return 'aaa'
方式一:
from dophon.msg_queue import * @consumer(tag='DEMO_TAG') def consumer(args): print(args) consumer() # ERROR : (2018-08-02 21:29:15) ==> ::: 2018080221291454499310002: consume() argument after ** must be a mapping, not str
非json會報錯,需在裝飾器上打開as_arg
from dophon.msg_queue import * @consumer(tag='DEMO_TAG',as_args=True) def consumer(args): print(args) consumer() # aaa
from dophon.msg_queue import * class TestConsumer(Consumer): @consumer(tag='test_msg_tag|test_msg_tag2', as_args=False, delay=1) def consume_msg(msg, timestamp, tag): print(msg) print(timestamp) print(tag) # 實例化衍生類啓動消費者 TestConsumer()
結果集:sql執行腳本的一個集合,因爲在實際開發中查詢居多,簡稱結果集
經過xml文件規範若干結果集組成
<!--test.xml--> <select id="findAll"> SELECT * FROM table </select>
經過代碼關聯xml文件,初始化結果集
from dophon.mysql import * _cursor=db_obj('/test.xml',auto_fix=True) # 根路徑爲配置文件路徑 # 文件路徑必須以/開頭
經過代碼獲取xml文件其中某一個結果集(以id區分)
result= _cursor.exe_sql(methodName='findAll')
支持動態參數傳入(#{}形式)以及骨架參數傳入(${形式})
動態參數傳入:
<select id="findAllById"> SELECT * FROM table WHERE id=#{id} </select>
result= _cursor.exe_sql(methodName='findAll',args={'id':'12345678'})
骨架參數傳入:
<select id="findAllByTableName"> SELECT * FROM ${table_name} </select>
result= _cursor.exe_sql(methodName='findAll',args={'id':'12345678'})
支持單條查詢,列表查詢,隊列查詢(結果集id與參數列表的列表形式和字典形式)
單條查詢:
result= _cursor.exe_sql_single(methodName='findAll',args={'id':'12345678'}) # result<dict>
列表查詢:
result= _cursor.exe_sql(methodName='findAll',args={'id':'12345678'}) # result<list>
隊列查詢(不穩定):
1.列表形式:
result= _cursor.exe_sql_queue( method_queue=['test1','test2'], args_queue=[ {'id':'123456','name':'tom'}, {} ] ) # result<dict> # { # method_name:exec_result # }
2.字典形式:
result= _cursor.exe_sql_obj_queue( queue_obj={ 'test1':{ 'id':'123456' }, 'test2':{} } ) # result<dict> # { # method_name:exec_result # }
支持結果集文件熱更新
update_round(_cursor,1) # update_round(<cursor>,second:int)
支持遠程維護結果集文件
remote_cell = remote.getCell('test.xml', remote_path='http://127.0.0.1:8400/member/export/xml/test.xml') _cursor = db_obj(remote_cell.getPath(), debug=True) 或者 _cursor = db_obj(remote_cell, debug=True)
暫時支持單條事務操做
經過初始化模型管理器獲取數據庫表映射骨架
from dophon import orm manager = orm.init_orm_manager(['user'])
經過實例化映射骨架獲取表操做緩存實例(操做實例)
user = manager.user()
經過對操做實例賦值進行對對應表模擬操做
print('打印對象變量域') for attr in dir(user): print(attr, ":", eval("user." + attr)) print('開始對對象賦值') user.user_id = 'id' user.info_id = 'info_id' user.user_name = 'user_name' user.user_pwd = 'user_pwd' user.user_status = 123 user.create_time = datetime.datetime.now().strftime('%y-%m-%d') user.update_time = datetime.datetime.now().strftime('%y-%m-%d') print('對象賦值完畢') print('打印對象變量域') for attr in dir(user): print(attr, ":", eval("user." + attr)) print('打印對象參數表') print(user([])) print('user([]):', user([])) print("user(['user_id','info_id']):", user(['user_id', 'info_id'])) print("user.get_field_list():", user.get_field_list()) print("user.alias('user_table').get_field_list():", user.alias('user_table').get_field_list())
經過對操做實例結構化操做對數據庫對應表結構進行數據落地操做
print(user.where()) print(user.values()) user.select() user.user_name = '111' user.select_one() user.select_all() user = manager.user() user.alias('u').select() user.user_name = '111' user.alias('us').select_one() user.alias('userr').select_all() user.user_id='test_id' user.info_id='test_info_id' user.user_name='test_user_name' user.user_pwd='test_user_pwd' user.user_status=1 user.create_time = datetime.datetime.now().strftime('%y-%m-%d') user.update_time = datetime.datetime.now().strftime('%y-%m-%d') print(user.insert()) # user.user_id = 'test_id' user.info_id = 'info_id' user.user_name = '柯李藝' user.user_pwd = '333' user.user_status = 123 print(user.update(update=['user_name','user_pwd'],where=['user_id'])) # user.user_id = 'test_id' user.info_id = 'info_id' user.user_name = 'user_name' user.user_pwd = 'user_pwd' user.user_status = 123 print(user.delete(where=['user_id'])) user1=manager.user() user2=manager.user() print(user1.select()) user1.user_name='early' user1.left_join(user2,['user_id'],['user_id']) user1.alias('u1').left_join(user2.alias('u2'),['user_id'],['user_id']) # print(user1.exe_join()) print(user1.select()) user1 = manager.user() print('user1', '---', id(user1)) user2 = user1.copy_to_obj(manager.user) print('user2', '---', id(user2)) print(user1('user_id')) user3 = user1.read_from_dict({ 'user_id': '111' }) print('user3', '---', id(user3)) print(user1('user_id')) print(user3('user_id'))
框架容器啓動功能:<br/>
- 實現自動生成部署容器
- 自動安裝項目相關依賴
- 開發ide控制檯調試
框架依賴容器: docker(點擊前往官網)
代碼:
# coding: utf-8" from dophon import docker_boot docker_boot.run_as_docker()
- 運行結果:
INFO : (2018-08-14 12:10:14) ==> ::: 容器前期準備 INFO : (2018-08-14 12:10:14) ==> ::: 生成依賴文件 INFO : (2018-08-14 12:10:17) ==> ::: 生成Dockerfile INFO : (2018-08-14 12:10:17) ==> ::: 暫停已運行的實例 demo INFO : (2018-08-14 12:10:28) ==> ::: 移除已運行的實例 demo INFO : (2018-08-14 12:10:29) ==> ::: 移除舊鏡像 Untagged: demo:latest Deleted: sha256:eb9ace16ac18eea033b87a4bcab0925dc0139664193e480796b00bff72ac132c Deleted: sha256:2a1af90ac889f36ce7b2861cd8a0f9efa3a98c31915e965cb0bfd7887c32cb05 Deleted: sha256:42bf2fedac374e453deaf06c62643679e8b71de52835a71b228966330b2e90ab INFO : (2018-08-14 12:10:30) ==> ::: 檢測配置合法性 INFO : (2018-08-14 12:10:31) ==> ::: 創建鏡像 Sending build context to Docker daemon 26.62kB Step 1/6 : FROM python:3.6.5 ---> 9a58cce9b09f Step 2/6 : ADD . ./demo ---> 2b30f0d25df8 Step 3/6 : ADD . ./demo/demo ---> 61c751581940 Step 4/6 : WORKDIR ./demo Removing intermediate container f9439713ab6f ---> 8ac1423c208b Step 5/6 : RUN pip install -r requirements.txt ---> Running in 60b5364841ee Collecting click==6.7 (from -r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB) Collecting dophon==1.1.7 (from -r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/98/81/33d06b15b37ef0715308a764c1cbf7a53ab69000d2bf7f029365b1c760cd/dophon-1.1.7-py3-none-any.whl (59kB) Collecting Flask==1.0.2 (from -r requirements.txt (line 3)) Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB) Collecting itsdangerous==0.24 (from -r requirements.txt (line 4)) Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB) Collecting Jinja2==2.10 (from -r requirements.txt (line 5)) Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB) Collecting MarkupSafe==1.0 (from -r requirements.txt (line 6)) Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz Collecting six==1.11.0 (from -r requirements.txt (line 7)) Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl Collecting Werkzeug==0.14.1 (from -r requirements.txt (line 8)) Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB) Collecting PyMySQL>=0.9.0 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/a7/7d/682c4a7da195a678047c8f1c51bb7682aaedee1dca7547883c3993ca9282/PyMySQL-0.9.2-py2.py3-none-any.whl (47kB) Collecting urllib3>=1.23 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB) Collecting Flask-Bootstrap>=3.3.7.1 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/88/53/958ce7c2aa26280b7fd7f3eecbf13053f1302ee2acb1db58ef32e1c23c2a/Flask-Bootstrap-3.3.7.1.tar.gz (456kB) Collecting schedule>=0.5.0 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/df/2c/3a94d846682a4fb94966e65bca19a1acb6f7dd85977f4e4cece6e677b757/schedule-0.5.0-py2.py3-none-any.whl Collecting pyOpenSSL>=18.0.0 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/96/af/9d29e6bd40823061aea2e0574ccb2fcf72bfd6130ce53d32773ec375458c/pyOpenSSL-18.0.0-py2.py3-none-any.whl (53kB) Collecting gevent>=1.3.5 (from dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/b6/2b/6be042be1023df54889d9e2a90b167f6fea65445384fccfdfd988cc16239/gevent-1.3.5-cp36-cp36m-manylinux1_x86_64.whl (4.6MB) Collecting cryptography (from PyMySQL>=0.9.0->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/c2/fa/fa9a8933c285895935d1392922fe721e9cb1b2c1881d14f149213a227ee3/cryptography-2.3-cp34-abi3-manylinux1_x86_64.whl (2.1MB) Collecting dominate (from Flask-Bootstrap>=3.3.7.1->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/43/b2/3b7d67dd59dab93ae08569384b254323516e8868b453eea5614a53835baf/dominate-2.3.1.tar.gz Collecting visitor (from Flask-Bootstrap>=3.3.7.1->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/d7/58/785fcd6de4210049da5fafe62301b197f044f3835393594be368547142b0/visitor-0.1.3.tar.gz Collecting greenlet>=0.4.13; platform_python_implementation == "CPython" (from gevent>=1.3.5->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/de/7b/cb662640540725deb0627264f6b890ee2b7725848b8cbca49e27bf3273c6/greenlet-0.4.14-cp36-cp36m-manylinux1_x86_64.whl (41kB) Collecting asn1crypto>=0.21.0 (from cryptography->PyMySQL>=0.9.0->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB) Collecting idna>=2.1 (from cryptography->PyMySQL>=0.9.0->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB) Collecting cffi!=1.11.3,>=1.7 (from cryptography->PyMySQL>=0.9.0->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/6d/c0/47db8f624f3e4e2f3f27be03a93379d1ba16a1450a7b1aacfa0366e2c0dd/cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl (421kB) Collecting pycparser (from cffi!=1.11.3,>=1.7->cryptography->PyMySQL>=0.9.0->dophon==1.1.7->-r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/8c/2d/aad7f16146f4197a11f8e91fb81df177adcc2073d36a17b1491fd09df6ed/pycparser-2.18.tar.gz (245kB) Building wheels for collected packages: itsdangerous, MarkupSafe, Flask-Bootstrap, dominate, visitor, pycparser Running setup.py bdist_wheel for itsdangerous: started Running setup.py bdist_wheel for itsdangerous: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5 Running setup.py bdist_wheel for MarkupSafe: started Running setup.py bdist_wheel for MarkupSafe: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46 Running setup.py bdist_wheel for Flask-Bootstrap: started Running setup.py bdist_wheel for Flask-Bootstrap: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/e8/b9/93/ef6ac3b8ead2d72cbcc042b9d58b613aaf47e533b9dc5b5999 Running setup.py bdist_wheel for dominate: started Running setup.py bdist_wheel for dominate: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/86/7c/76/a514f343c9e4f85f4c98fe13138ab9c8f756647155c4c1f25e Running setup.py bdist_wheel for visitor: started Running setup.py bdist_wheel for visitor: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/68/b0/a2/cc8c7cf94ca3d1088a7d2e27936c1e0da170e05f560973e8dd Running setup.py bdist_wheel for pycparser: started Running setup.py bdist_wheel for pycparser: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/c0/a1/27/5ba234bd77ea5a290cbf6d675259ec52293193467a12ef1f46 Successfully built itsdangerous MarkupSafe Flask-Bootstrap dominate visitor pycparser Installing collected packages: click, MarkupSafe, Jinja2, itsdangerous, Werkzeug, Flask, six, asn1crypto, idna, pycparser, cffi, cryptography, PyMySQL, urllib3, dominate, visitor, Flask-Bootstrap, schedule, pyOpenSSL, greenlet, gevent, dophon Successfully installed Flask-1.0.2 Flask-Bootstrap-3.3.7.1 Jinja2-2.10 MarkupSafe-1.0 PyMySQL-0.9.2 Werkzeug-0.14.1 asn1crypto-0.24.0 cffi-1.11.5 click-6.7 cryptography-2.3 dominate-2.3.1 dophon-1.1.7 gevent-1.3.5 greenlet-0.4.14 idna-2.7 itsdangerous-0.24 pyOpenSSL-18.0.0 pycparser-2.18 schedule-0.5.0 six-1.11.0 urllib3-1.23 visitor-0.1.3 You are using pip version 10.0.1, however version 18.0 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Removing intermediate container 60b5364841ee ---> 4f7f51326068 Step 6/6 : CMD ["python","./Bootstrap.py"] ---> Running in a01240a5675c Removing intermediate container a01240a5675c ---> 7fe9614a4948 Successfully built 7fe9614a4948 Successfully tagged demo:latest SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories. INFO : (2018-08-14 12:11:04) ==> ::: 運行鏡像 6686125b7b5ccef21240181bc08da3aabbf0765b72d4ae404d2cc15aabbd0999 INFO : (2018-08-14 12:11:06) ==> ::: 打印容器內部地址(空地址表明啓動失敗) '172.17.0.2' INFO : (2018-08-14 12:11:07) ==> ::: 打印容器載體地址 10.10.75.1 INFO : (2018-08-14 12:11:07) ==> ::: 啓動檢測容器端口 INFO : (2018-08-14 12:11:07) ==> ::: 容器啓動完畢 INFO : (2018-08-14 12:12:17) ==> ::: 容器存活性檢查:http://10.10.75.1:80 INFO : (2018-08-14 12:12:27) ==> ::: 容器存活性檢查:http://10.10.75.1:80 INFO : (2018-08-14 12:12:38) ==> ::: 容器存活性檢查:http://10.10.75.1:80