2015-12-29 103 views
4

我正在構建一個用C++編寫的服務器,並且想用Docker與docker-compose一起部署它。做這件事的「正確方法」是什麼?我應該從Dockerfile調用make還是手動構建,上傳到某個服務器,然後從Dockerfile中上傳COPY二進制文件?用Docker構建一個已編譯的應用程序

+0

無論哪種方式都應該工作,我更喜歡你的第一個選項 – user2915097

+2

但是你會在生產機器上有開發文件(例如'-dev'包)。那是...呃...不是很好,呃? –

+0

不,您可以構建,然後清理並只保留容器中的可執行文件。 – user2915097

回答

6

我會這樣做的方式是在你的容器外部運行你的構建,並只將構建的輸出(你的二進制文件和任何必要的庫)複製到你的容器中。然後,您可以將容器上傳到容器註冊表(例如,使用託管的容器或自己運行),然後從該註冊表中將其拉到生產機器上。因此,流動看起來是這樣的:

  1. 編譯二進制
  2. 測試/理智,檢查二進制本身
  3. 建集裝箱二進制
  4. 測試/理智,檢查容器圖像圖像與二進制
  5. 上傳到容器註冊表
  6. 部署到staging/test/qa,從註冊表中取出
  7. 部署督促,從

因爲它是重要的,你之前的生產部署測試,要測試的正是你會在生產中部署相同的事情註冊表拉,所以你不想提取或者在構建之後以任何方式修改Docker鏡像。

我不會跑構建你計劃在督促部署容器,因爲那麼你的容器將有更多的文物各種(如臨時生成輸出,工具等),你不需要進行生產並且不必要地增加容器映像,而不使用部署的東西。

+6

該解決方案與Docker理念不完全一致。這可能導致相同的老問題「哦,但它在我的機器上工作」。除非C++應用程序很少或沒有依賴關係,並且不依賴共享對象文件(.so文件),否則此解決方案將導致鏈接不正確版本的依賴關係 - blueskin 49分鐘前 – blueskin

+1

@blueskin - 感謝您提供此信息。我也想過這個;我認爲一種解決方案是使用兩個容器:一個用於構建,一個卷映射到將輸出導出到主機,第二個容器用於部署沒有任何構建工件或臨時文件,但只包含最終構建輸出。思考? –

5

我的建議是完全開發,構建和測試容器本身。這確保了Docker的理念,即開發人員的環境與生產環境相同https://blog.newrelic.com/2016/06/20/docker-osx-mac/ 尤其是,在C++應用程序中,通常與共享庫/對象文件存在依賴關係。

我不認爲在Docker上有開發,測試和部署C++應用程序的標準化開發過程。 要回答你的問題,我們這樣做是因爲現在是這樣,對待容器作爲開發環境和執行一套做法對球隊這樣的:

  1. 我們的代碼庫(除了配置文件)總是生活共享卷(本地機器上)(版本上GIT)上
  2. 共享/依賴庫和二進制文件等... 總是活容器
  3. 生成&測試上容器和提交所述圖像清潔不希望的物體上之前文件,庫等...並確保docker diff的變化如預期的那樣
  4. 更改/更新環境(包括共享庫),依賴性始終記錄在案並與團隊溝通。
6

我有困難docker-compose自動化我們的構建我結束了使用docker build的一切:

建設

運行

三層 - >開發 - >打造

然後我將構建輸出複製到'部署'映像中

運行 - >部署

四層玩:

運行
  • 包含任何軟件包需要爲應用程序運行
    • 例如libsqlite3-0
發展
  • FROM <projname>:run
  • 包含了構建
    • 例如需要的軟件包克++,cmake的,libsqlite3-dev的
  • Dockerfile執行任何外部構建
    • 例如步驟來建立升壓python3(不包管理器回購的)
構建
  • FROM <projname>:develop
  • 包含源
  • Dockerfile執行內部版本(代碼更改頻繁)
  • 內置二進制文件被複製出該映像以供部署使用
部署構建
  • FROM <projname>:run
  • 輸出複製到圖像,並安裝用於啓動應用程序

文件夾結構

  • RUNENTRYPOINT看起來是這樣的:

    . 
    ├── run 
    │   └── Dockerfile 
    ├── develop 
    │   └── Dockerfile 
    ├── build 
    │   ├── Dockerfile 
    │   └── removeOldImages.sh 
    └── deploy 
        ├── Dockerfile 
       └── pushImage.sh 
    

    設置構建服務器意味着執行:

    docker build -f run -t <projName>:run 
    docker build -f develop -t <projName>:develop 
    

    每次我們做一個構建,出現這種情況:

    # execute the build 
    docker build -f build -t <projName>:build 
    
    # install build outputs 
    docker build -f deploy -t <projName>:version 
    
    # if successful, push deploy image to dockerhub 
    docker tag <projName>:<version> <projName>:latest 
    docker push <projName>:<version> 
    docker push <projName>:latest 
    

    我是指人們對Dockerfiles爲如何如果構建失敗構建/運行/安裝工程

    文檔並且輸出不足以進行調查,我可以在<projname>:build中運行/bin/bash並捅過來查看出了什麼問題

  • +0

    看起來很酷。我很高興看到你的Github回購以HelloWorld C++爲例(所有4個docker文件和兩個shell文件......)感謝分享。 – zipzit

    相關問題