成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用Dokcer創(chuàng)建開發(fā)環(huán)境

云計(jì)算
鑒于還沒有用Docker創(chuàng)建本地開發(fā)環(huán)境的先例,Jeff Nickoloff開創(chuàng)了一個(gè)先例,相信大家也可以。

 作者在此處使用了Frankenstein一詞。Frankenstein,《弗蘭肯斯坦》原是英國詩人雪萊的妻子瑪麗·雪萊在1818年創(chuàng)作的小說,被認(rèn)為是世界***部真正意義上的科幻小說。弗蘭肯斯坦來自于此小說,可以理解為怪人;毀滅創(chuàng)造者自己之物

 

4.jpeg

 

知道一個(gè)事物和實(shí)現(xiàn)這個(gè)事物是完全不同的事情。從Docker誕生那天開始,我們就夢想著諸如“15秒部署一個(gè)項(xiàng)目”,“版本可控開發(fā)環(huán)境”,以及時(shí)髦的運(yùn)維用語,如“滾動(dòng)開發(fā)”,“軟件定義架構(gòu)”。處于浪尖的行業(yè)人士都在以***的熱情參與到將很多名詞和工具,例如“編排”,“服務(wù)發(fā)現(xiàn)”等,定義,重新定義以及商品化大潮中。

我認(rèn)為這股大潮的催化劑來自于Docker在應(yīng)用和基礎(chǔ)架構(gòu)之間帶來的美妙接口和抽象。開發(fā)者可以在不必知道底層架構(gòu)情況下談?wù)摶A(chǔ)架構(gòu),操作人員也不必花大量時(shí)間研究如何安裝和管理軟件。肯定有什么力量隱藏在看似簡單的外表下使得大家生活簡化,更加高效。

現(xiàn)實(shí)世界時(shí)殘酷的,不要想當(dāng)然認(rèn)為采用一項(xiàng)新技術(shù)只會(huì)帶來享受。過去幾年經(jīng)過一些項(xiàng)目的磨練,經(jīng)歷過奇怪的環(huán)境,我認(rèn)為Docker也不例外。但是某一個(gè)經(jīng)驗(yàn)一般可以直接應(yīng)用到項(xiàng)目的下一階段。要想從Docker獲得功力,必須浸淫到實(shí)際項(xiàng)目中去磨練。

過去一年中,我全身心投入去教授我的關(guān)于Dokcer基礎(chǔ)的書,Docker in Action。

我注意到幾乎所有人開始學(xué)習(xí)Docker技術(shù)時(shí)都會(huì)糾結(jié)于如何創(chuàng)建開發(fā)環(huán)境,然后才能了解生態(tài)系統(tǒng)之內(nèi)大家的關(guān)系。每個(gè)人開始都會(huì)認(rèn)為使用Docker會(huì)使環(huán)境搭建變的簡單,也不是完全不對,有很多“容器化”教程都涵蓋了創(chuàng)建一個(gè)image和如何將某個(gè)工具打包到容器(Container)內(nèi),但是如何將開發(fā)環(huán)境Docker化是一個(gè)完全不同的事情。

作為一個(gè)踏坑先驅(qū)者,我可以分享一下我的經(jīng)驗(yàn)。

我曾經(jīng)是一個(gè)資深Java使用者,但這個(gè)分享的經(jīng)驗(yàn)不是關(guān)于Java的,而是圍繞著我使用Go和Node開發(fā)應(yīng)用發(fā)生的。我有一定的Go開發(fā)經(jīng)驗(yàn),主動(dòng)提高在這一領(lǐng)域的能力。進(jìn)入一個(gè)不熟悉領(lǐng)域迅速上手碰到的主要問題就是如何獲得正確的工作流,而且我還比較厭惡在筆記本上不斷安裝軟件,這些都驅(qū)使我嘗試用Docker做這些工作,或者有時(shí)候采用Vagrant。

 

[[162118]]

 

我所參與的項(xiàng)目是用Go寫一個(gè)標(biāo)準(zhǔn)的REST服務(wù),基于gin,依賴Redis和NSQ的某些庫和服務(wù)。也就是說需要import一些本地運(yùn)行著的Redis和NSQ實(shí)例的庫,更有趣的是我還使用了一些服務(wù)于NGINX的靜態(tài)資源。

對門外漢來說,Go是一種編程語言,實(shí)際上還有一種命令行工具也叫“go”。從依賴型管理、編譯、測試用例到其它各種任務(wù)都使用它。對Go項(xiàng)目來說,除了Git和一個(gè)好用的編輯器,剩下就是跟它打交道了。然而還是有一個(gè)問題,我不想在筆記本上安裝Go,筆記本上我只想安裝Git和Docker。這些問題限制了其他環(huán)境下的兼容性,并且對新手來說降低了門檻。

這個(gè)項(xiàng)目有運(yùn)行時(shí)依賴,意味著此工具集需要為簡單環(huán)境定義和編排而包括Docker Compose。 很多人會(huì)為此感到不適應(yīng),那么我們怎么辦?開始創(chuàng)建一個(gè)Dockerfile或者docker-compose.yml?好吧,先讓我告訴大家我是怎么辦的,然后解釋為什么這么做。

 

[[162119]]

 

此案中,我希望我的本地包是完全自動(dòng)的。我不喜歡手動(dòng)逐條執(zhí)行步驟,而且我的vim配置文件也很簡單。我只想從“是否運(yùn)行”層次控制運(yùn)行環(huán)境。本地化開發(fā)環(huán)境目標(biāo)被快速復(fù)制,不僅用于提高生產(chǎn)效率,而且用于共享Docker images。 我最終完成了Dockerfile,用來產(chǎn)生包含Go,Node,和我最經(jīng)常使用的打包工具Gulp的images。 此Dockerfile沒有嵌入代碼,image也沒有嵌入Gulpfile。相反的,在一個(gè)建立了的GOPATH(Go workspace的根路徑)上定義了一個(gè)卷。

最終,我為此images設(shè)置了給gulp提供服務(wù)的entrypoint,設(shè)置默認(rèn)命令來監(jiān)控。輸出images肯定不是我稱為build artifact的東西,從這個(gè)意義上來講,此環(huán)境唯一做的就是提供了一個(gè)運(yùn)行實(shí)例,幫助我們判斷是否代碼運(yùn)行。對我的場景來說,運(yùn)行的非常棒。而我將“artifacts”用于稱呼另外一個(gè)build。

下一步我用Compose定義本地開發(fā)環(huán)境。首先定義了在images中用到的所有Docker Hub 中定義的依賴服務(wù),將他們連接到某一個(gè)“目標(biāo)”服務(wù)。此服務(wù)引用了新Dockerfile從哪里生成,將本地源目錄綁定到新image期望輸出的掛載點(diǎn),暴露一些可以測試的端口。然后,添加了一個(gè)服務(wù),可以不斷地向目標(biāo)服務(wù)循環(huán)發(fā)起一系列集成測試。最終,我添加了NGINX服務(wù),掛載了有很多配置文件和靜態(tài)assets的卷。使用卷的好處在于重復(fù)使用配置文件和assets而不用重建image。

  1. $ cat ./service/local.df 
  2.  
  3. FROM golang:alpine 
  4.  
  5. RUN apk --update add --no-cache git nodejs 
  6.  
  7. RUN npm install --global gulp 
  8.  
  9. ENV GOPATH=/go PATH=$PATH:/go/bin 
  10.  
  11. VOLUME ["/go/src/github.com/.../myproj""/go/pkg","/go/bin"
  12.  
  13. WORKDIR /go/src/github.com/.../myproj 
  14.  
  15. Bring in dependencies in the imageRUN go get github.com/bitly/go-nsq && \ 
  16.  
  17. go get github.com/codegangsta/cli && \ 
  18.  
  19. go get github.com/gin-gonic/gin 
  20.  
  21. CMD ["gulp"
  22.  
  23. $ cat ./service/gulpfile.js 
  24.  
  25. var gulp = require('gulp'); 
  26.  
  27. var child = require('child_process'); 
  28.  
  29. var server = null
  30.  
  31. gulp.task('default', ['watch']); 
  32.  
  33. gulp.task('watch', function() { 
  34.  
  35. gulp.watch('./**/*.go', ['fmt','build','spawn']); 
  36.  
  37. }); 
  38.  
  39. gulp.task('fmt', function() { 
  40.  
  41. return child.spawnSync('go', ['fmt']); 
  42.  
  43. }); 
  44.  
  45. gulp.task('build', function() { 
  46.  
  47. return child.spawnSync('go', ['install']); 
  48.  
  49. }); 
  50.  
  51. gulp.task('spawn', function() { 
  52.  
  53. if (server) 
  54.  
  55. server.kill(); 
  56.  
  57. server = child.spawn('myproj'); 
  58.  
  59. server.stderr.on('data', function(data) { 
  60.  
  61. process.stdout.write(data.toString()); 
  62.  
  63. }); 
  64.  
  65. server.stdout.on('data', function(data) { 
  66.  
  67. process.stdout.write(data.toString()); 
  68.  
  69. }); 
  70.  
  71. }); 
  72.  
  73. $ cat docker-compose.yml 
  74.  
  75. web: 
  76.  
  77. image: nginx 
  78.  
  79. volumes: 
  80.  
  81. - ./web/assets:/var/www 
  82.  
  83. - ./web/config:/etc/nginx/conf.d 
  84.  
  85. integtest: 
  86.  
  87. build: ./integ 
  88.  
  89. links: 
  90.  
  91. - service 
  92.  
  93. service: 
  94.  
  95. build: ./service 
  96.  
  97. dockerfile: local.df 
  98.  
  99. volumes: 
  100.  
  101. - ./service/src/:/go/src/github.com/.../myproj 
  102.  
  103. links: 
  104.  
  105. - nsqd 
  106.  
  107. - redis 
  108.  
  109. nsqd: 
  110.  
  111. image: nsqio/nsq 
  112.  
  113. ... 
  114.  
  115. redis: 
  116.  
  117. image: redis 
  118.  
  119. ... 

所有代碼最終會(huì)在電腦上生成本地開發(fā)環(huán)境,當(dāng)使用:

  1. docker-compose up –d 

時(shí),會(huì)啟動(dòng)git clone,然后循環(huán)運(yùn)行;不需要重建image或者重啟容器。每當(dāng).go文件發(fā)生變化,Gulp就會(huì)重建,并且在運(yùn)行的容器中重啟我的服務(wù)。就這么簡單。

創(chuàng)建此環(huán)境很簡單嗎?不盡然,但是確實(shí)實(shí)現(xiàn)了。難道不用容器,而在本地直接安裝Go,Node,Gulp不是更簡單嗎?也許在這個(gè)場景是,但也只限于用Docker運(yùn)行此依賴服務(wù)。我不喜歡這樣。

我曾經(jīng)要管理這些工具的不同版本,而產(chǎn)生了復(fù)雜的環(huán)境變量,到處生成artifacts。我不得不提醒同事們注意這些容易發(fā)生沖突的環(huán)境變量,他們太缺乏集中版本控制了。

也許你并不喜歡上面描述的環(huán)境,或者對項(xiàng)目有不同的需求。很好,確實(shí)是這樣,本文并不是讓所有工具都運(yùn)行在Docker中,如果這樣就說明并沒考慮過要解決什么問題。

當(dāng)我設(shè)計(jì)這個(gè)環(huán)境時(shí),考慮過下面幾個(gè)問題,顧慮,以及某些潛在答案。當(dāng)開始Docker工作環(huán)境時(shí),就會(huì)發(fā)現(xiàn)實(shí)際情況可能比自己的回答更糟糕。

當(dāng)你考慮打包和環(huán)境時(shí),***考慮的因素是什么?

這個(gè)確實(shí)是最重要的問題。在此場景中,有幾個(gè)選項(xiàng)。我可以使用go直接在容器內(nèi)編程,看起來如下:

  1. get dependencies$ docker run --rm -v "$(pwd)"/go/src/app golang:1.5 go get -d -v 
  2.  
  3. start the other servicesbuild and link$ docker run --rm -v "$(pwd)":/go/src/app golang:1.5 go install \ 
  4.  
  5. github.com/allingeek/myproj 
  6.  
  7. run the program stand alone$ docker run --rm -v "$(pwd)"/bin/myproj:/bin/myproj alpine myproj 
  8.  
  9. to iterate, make changes and repeat the last two steps 

其實(shí)這個(gè)示例中大部分bolierplate可以通過shell別名或者函數(shù)隱藏,感覺Go是安裝在自己的設(shè)備中似的,還可以跟Go工作流聯(lián)系,創(chuàng)建artifacts。這些特性對非服務(wù)項(xiàng)目有益處,但是對庫和軟件項(xiàng)目就不一定了。

假設(shè)你已經(jīng)在使用Gulp,make,ant或者其他腳本,那么可以繼續(xù),并且使用Dokcer作為這些工具的目標(biāo)。

另外一種方法,我可以通過使用Dockerbuild來定義和控制我的build,獲得更多面向Docker的經(jīng)驗(yàn)。代碼如下:

  1. $ cat Dockerfile 
  2.  
  3. FROM golang:1.5-onbuild 
  4.  
  5. start the other servicesinstall dependencies, build, and link$ docker build -t local/myproj . 
  6.  
  7. run the program$ docker run --rm local/myprog 
  8.  
  9. to iterate, make changes and repeat the last two steps 

使用Dokcer來控制build有若干好處。可以使用以前編譯好的image,Dockerfilebuilds使用緩存方法,使得編譯工作只重復(fù)最小的步驟(假設(shè)有一個(gè)很棒的Dockerfile)。***,這些builds生成的images也可以跟其他開發(fā)者共享。

這個(gè)案例中,我使用golang資源庫中的onbuildimage作為基礎(chǔ)。其中包括一些很棒的下載依賴包邏輯。這個(gè)方法會(huì)生成可以方便用于其他非生產(chǎn)環(huán)境的Dockerimage。這個(gè)方法對于生產(chǎn)級別的image的問題在于,必須有步驟避免大image并且包括某些初始化腳本,用于啟動(dòng)和監(jiān)控服務(wù)前驗(yàn)證狀態(tài)。

有意思的是,Docker使用一系列腳本,Makefiles和Dockerfiles。build系統(tǒng)相對很健壯了,負(fù)責(zé)各種測試,linting等,以及各種操作系統(tǒng)和架構(gòu)的artifacts。本場景中,容器是用來產(chǎn)生二進(jìn)制的工具,然而是從一個(gè)本地build image中實(shí)現(xiàn)的。

擴(kuò)充Docker build的選項(xiàng),可以使用Compose來定義一整套開發(fā)環(huán)境。

  1. $ cat Dockerfile 
  2.  
  3. FROM golang:1.5-onbuild 
  4.  
  5. $ cat docker-compose.yml 
  6.  
  7. service: 
  8.  
  9. build: . 
  10.  
  11. links: 
  12.  
  13. - redis 
  14.  
  15. - nsq 
  16.  
  17. redis: 
  18.  
  19. image: redis 
  20.  
  21. nsq: 
  22.  
  23. image: nsqio/nsq 
  24.  
  25. install dependencies, build, link, launch dependency services, run$ docker-compose up -d 
  26.  
  27. to iterate, make changes and then$ docker-compose build && docker-compose up -d 

Compose負(fù)責(zé)環(huán)境管理。如果覺得系統(tǒng)非常干凈并不奇怪,Compose把所有事情都聯(lián)系起來,優(yōu)化卷管理,當(dāng)images缺失時(shí)自動(dòng)build,匯總?cè)罩据敵?。我之所以選這些開關(guān)是為了簡化服務(wù)依賴,也因?yàn)樗苌晌倚枰腶rtifacts。

這個(gè)示例是一個(gè)運(yùn)行時(shí)容器,Compose或者Docker都有合適的工具做到這點(diǎn)。此場景中,也可能更需要一個(gè)分布式image,或者可能希望build可以為本機(jī)產(chǎn)生一個(gè)二進(jìn)制文件。

如果期望獲得想要的image,必須確保源碼或者預(yù)編譯庫在build時(shí)候嵌入image中。build時(shí)候沒有掛載卷,也即需要每次重復(fù)時(shí)都要重建image。

如果希望在容器內(nèi)部產(chǎn)生某些artifacts,則需要引入掛載卷。使用Docker命令行或者Compose環(huán)境可以很容易實(shí)現(xiàn)。但是要注意,除非容器在運(yùn)行,否則build并不工作,也就意味著不能只用dockerbuild。

匯總

目前沒有Docker方式創(chuàng)建開發(fā)環(huán)境。Docker是一個(gè)可編排工具,不只是圣書。與其使用別人已有的dockerbuild系統(tǒng),不如花一定時(shí)間學(xué)習(xí)此工具,明確自己的需求,然后創(chuàng)建適合自己的Docker環(huán)境。

責(zé)任編輯:xinxiaoliang 來源: DockOne
相關(guān)推薦

2023-06-07 16:32:10

Python開發(fā)虛擬環(huán)境

2010-03-12 13:32:02

python2.6

2015-12-30 13:58:00

DockerGit開發(fā)環(huán)境

2010-03-22 09:54:38

Python開發(fā)環(huán)境

2024-10-12 09:38:53

2012-05-02 23:04:38

iOS

2012-05-13 12:43:50

iOS

2013-07-29 14:23:55

Eclipse開發(fā)環(huán)境Eclipse開發(fā)環(huán)境

2021-05-07 11:29:54

MacFlutter開發(fā)

2024-03-26 15:19:36

鴻蒙應(yīng)用開發(fā)開發(fā)工具

2011-07-06 17:34:47

iPhone

2010-01-28 11:07:59

Android NDK

2011-06-03 13:38:49

Android 開發(fā)環(huán)境

2009-07-07 10:47:58

Servlet開發(fā)環(huán)境

2013-07-23 06:11:44

Android開發(fā)學(xué)習(xí)Android開發(fā)環(huán)境Java

2010-02-01 17:18:23

Python多線程環(huán)境

2020-07-06 07:00:21

PyCharm虛擬環(huán)境

2015-03-30 08:56:18

Docker高效開發(fā)環(huán)境虛擬化

2023-07-27 08:24:28

2015-06-09 13:45:14

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 美女天堂在线 | 精品在线播放 | av网站免费 | 亚洲国产精品99久久久久久久久 | 久久中文字幕一区 | 欧美精品一区二区三区在线 | 精品国产欧美在线 | 亚洲免费在线播放 | 91影库| 亚州国产 | 久久亚洲欧美日韩精品专区 | 亚洲区一区二 | 欧美一区二区在线 | 日韩黄色av | 国产一二三区在线 | 亚洲欧美视频一区 | 国产一在线观看 | 国产日韩欧美在线 | www成年人视频 | 国产一区二区久久 | 99精品在线| 国产精品视频区 | 午夜爽爽爽男女免费观看影院 | 有码在线| 99久久久久久99国产精品免 | 精品成人免费一区二区在线播放 | 91久久久久 | 色综合久久久 | 欧美激情精品久久久久久免费 | 97精品超碰一区二区三区 | 中文字幕一二三区 | 中文字幕91av | 精品欧美 | 91在线精品秘密一区二区 | 精品一区二区免费视频 | a级毛片免费高清视频 | 国产色 | 在线视频成人 | 中文字幕亚洲欧美 | 欧美日韩在线一区 | 国产免费拔擦拔擦8x高清 |