使用Docker高效搭建開發環境

2021-02-13 分布式實驗室

Docker作為輕量級的基於容器的解決方案,它對系統侵入性低,容易移植,天生就適合做複雜業務部署和開發環境搭建,今天給大家帶來的是奇虎360的開發是如何使用Docker高效搭建開發環境的。作為一個平時喜歡折騰的開發人員,我喜歡嘗試各種環境,使用感興趣的各種開源軟體。同時,我也是有一些相對的小潔癖,很喜歡Linux中權限最小化原則,我也不喜歡自己的環境中有太多不知道的東西。

作業系統從CentOS 5到CentOS 7;

Web Server從Apache到Nginx;

開發語言從最初的PHP 5.2到PHP 7,又到現在主要使用Go,馬上還會開始接觸C++;

資料庫從MySQL 5.1到現在的5.7,前陣子又開始折騰MariaDB;

Cache選型從Memcache到Redis;

隊列用過Kafka,去年開始大量使用NSQ。

公司雖然有專門負責部署、運維這些服務的同學,但我在開發的時候,還是喜歡自己來搭建這些東西,因為這樣通常可以對使用到的服務有更多的認識,也能幫助自己使用的更好。今天我就來和大家分享下我是如何高效的搭建好自己的開發環境的。這裡先說明一點,對每個開源軟體,我幾乎都是自己編譯部署的,而不會使用類似yum install這種方式,也很少直接下載官方編譯好的二進位包,這都是為了能多深入了解用到的開源軟體。但一些依賴的動態庫文件,如zlib等,還有編譯工具,如GCC、make等,我都是通過方便的yum install這種方式直接安裝的,否則會累死。我在很長的一段時間內,都是把每個軟體的編譯、安裝過程寫成一個腳本,之後再需要用的時候直接運行腳本即可,但這樣的方式,通常會遇到下面這些問題:

腳本只能在我當時的作業系統環境下運行。記得當時購買過不同服務商的VPS,雖然不同VPS我都使用同樣的Linux發行版,但腳本通常都不能一鍵跑完。這也是沒辦法,因為每個VPS服務商都會製作自己的作業系統鏡像版本。

作業系統升級,如CentOS 5 - 6,或是換為Ubuntu,這樣基本上腳本都跑不了。

軟體升級,如MySQL 5.2 - 5.6,構建工具改為CMake,依賴庫改變或升級。

如果某個軟體依賴的公共庫版本和其它軟體不同,且公共庫升級後和舊版不兼容,那你就只能為這個軟體單獨編譯公共庫了,如果只是普通的公共庫還好,但如果是所需要的編譯工具版本不同,那可就慘了。

上面這些問題,如果你想每個發行版維護一個腳本,那會累死,因為一旦你每次想升級一個軟體,難道每個發行版都要編譯一遍嗎?這就變成了收穫價值很低的體力勞動了。由於喜歡折騰的個性,我對作業系統的升級以及軟體包版本的升級又經常發生,所以一直以來,我都在尋找一個好方法,能很方便的維護好自己的開發環境,儘量做到只=新東西只為它工作一次,最後我找到了Docker,目前我都是用它來搭建自己的開發環境的。

讓每個軟體運行在容器中,因為運行的容器環境是可以固定下來的,所以編譯安裝腳本寫一個就可以了。

代碼使用數據卷的方式加載到需要的容器中。

因為是開發環境,所以網絡方面使用最簡單的--net=host。

將鏡像的創建、容器的啟動維護在Git項目中,並抽象出統一的構建過程,很方面的做到新軟體接入,新機器部署。

我將構建過程放到Git中:https://gitee.com/andals/docker-nginx。Readme中記錄了構建所需要執行的腳本命令,大家訪問上面的網址就可以看到,這裡我簡單介紹下項目的結構:

├── Dockerfile        
├── pkg              
│   ├── conf
│   │   ├── fastcgi.conf
│   │   ├── http.d
│   │   ├── include
│   │   ├── koi-utf
│   │   ├── koi-win
│   │   ├── logrotate.conf
│   │   ├── logrotate.d
│   │   ├── mime.types
│   │   ├── Nginx.conf
│   │   ├── scgi_params
│   │   ├── uwsgi_params
│   │   └── win-utf
│   ├── luajit-2.0.3.tar.gz
│   └── Nginx-1.8.1.tar.gz
├── README.md
├── script                
│   ├── build_image.sh    
│   ├── build_pkg.sh      
│   ├── init.sh          
│   └── pre_build.sh      
└── src                  
   ├── modules
   │   ├── ngx_devel_kit-0.2.19.tgz
   │   ├── ngx_echo-0.53.tgz
   │   └── ngx_lua-0.9.7.tgz
   ├── Nginx-1.8.1.tar.gz
   └── openssl-1.0.2h.tar.gz

FROM andals/CentOS:7
MAINTAINER ligang <ligang1109@aliyun.com>
LABEL name="Nginx Image"
LABEL vendor="Andals"
COPY pkg/ /build/pkg/
COPY script/ /build/script/
RUN /build/script/build_image.sh
CMD /build/script/init.sh

把構建需要的包(PKG目錄中)放到鏡像中

把構建腳本放到鏡像中

執行構建腳本

容器啟動時,執行init.sh,裡面啟動相應的服務

Readme.md中記錄了執行構建的命令和容器運行命令,示例運行如下:

ligang@vm-xUbuntu16 ~/devspace/dbuild $ git clone git@gitee.com:andals/docker-Nginx.git Nginx
Cloning into 'Nginx'...
.
ligang@vm-xUbuntu16 ~/devspace/dbuild $ cd Nginx/
ligang@vm-xUbuntu16 ~/devspace/dbuild/Nginx $ ngxVer=1.8.1
ligang@vm-xUbuntu16 ~/devspace/dbuild/Nginx $ docker build -t andals/Nginx:${ngxVer} ./
Sending build context to Docker daemon   30.7MB
Step 1/8 : FROM andals/CentOS:7
.
Successfully built ea8147743031
Successfully tagged andals/Nginx:1.8.1
ligang@vm-xUbuntu16 ~/devspace/dbuild/Nginx $ docker run -d --name=Nginx-${ngxVer} --volumes-from=data-home -v /data/Nginx:/data/Nginx --net=host andals/Nginx:${ngxVer}
dbf3c0617eb34c4b1b4ea54c2961989612d5474db3b1acd1d717221e6e5cb516

--volumes-from=data-home這個就是我放置代碼的數據卷,我喜歡把代碼放到$HOME下面,所以這個卷的相關信息如下:

ligang@vm-xUbuntu16 ~ $ docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                   PORTS               NAMES
578912a08ea7        andals/CentOS:7          "echo Data Volumn Ho…"   9 days ago          Exited (0) 9 days ago                        data-home
.
ligang@vm-xUbuntu16 ~ $ docker inspect 578912a08ea7
.
       "Mounts": [
           {
               "Type": "bind",
               "Source": "/home",
               "Destination": "/home",
               "Mode": "",
               "RW": true,
               "Propagation": "rprivate"
           }
.

/data/Nginx中放置Nginx的conf、log等,每個軟體運行時的conf、log、data等我都統一放置在/data下面,如:

ligang@vm-xUbuntu16 ~ $ tree -d /data/ -L 1
/data/
├── mariadb
├── Nginx
└── redis
ligang@vm-xUbuntu16 ~ $ tree -d /data/Nginx/
/data/Nginx/
├── conf
│   ├── http.d
│   ├── include
│   └── logrotate.d
└── logs

啟動容器時使用--net=host,作為開發環境簡單實用。我就是通過這種方法完成了開發環境的構建,不再有多餘的重複工作,並且新機器部署開發環境效率極高。

ligang@vm-xUbuntu16 ~ $ docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                   PORTS               NAMES
dbf3c0617eb3        andals/Nginx:1.8.1       "/bin/sh -c /build/s…"   33 minutes ago      Up 33 minutes                                Nginx-1.8.1
3e31ef433298        andals/php:7.1.9         "/bin/sh -c /build/s…"   8 hours ago         Up 8 hours                                   php-7.1.9
360f94bf9c43        andals/jekyll:latest     "/bin/sh -c /build/s…"   9 days ago          Up 10 hours                                  jekyll-latest
0a7d58d1ca5e        andals/redis:4.0.8       "/bin/sh -c /build/s…"   9 days ago          Up 10 hours                                  redis-4.0.8
fdaa655b4a11        andals/samba:4.4.16      "/bin/sh -c /build/s…"   9 days ago          Up 10 hours                                  samba-4.4.16
6ad00a69befd        andals/mariadb:10.2.14   "/bin/sh -c /build/s…"   9 days ago          Up 10 hours                                  mariadb-10.2.14
578912a08ea7        andals/CentOS:7          "echo Data Volumn Ho…"   9 days ago          Exited (0) 9 days ago                        data-home

使用Docker環境後,有個問題,就是沒有辦法很方便的和軟體交互。這是因為軟體都執行在容器中,比如重啟Nginx吧,需要下面這幾步:

找到Nginx這個容器

進入Nginx這個容器

在容器裡面再執行reload

為了方便的做這些事情,我開發了一個工具dockerbox,可以很方便的做到這些事情。dockerbox的詳情及使用方法請見:https://github.com/ligang1109/dockerbox我使用虛擬機搭建的開發環境,所以配置這個會省事好多,我使用用了systemd:

ligang@vm-xUbuntu16 ~ $ ll /lib/systemd/system/dstart.service
-rw-r--r-- 1 root root 229 4月   3 21:35 /lib/systemd/system/dstart.service
ligang@vm-xUbuntu16 ~ $ cat /lib/systemd/system/dstart.service
[Unit]
Description=Docker Container Starter
After=network.target docker.service
Requires=docker.service
[Service]
ExecStart=/usr/local/bin/dbox -dconfPath=/home/ligang/.dconf.json start all
[Install]
WantedBy=multi-user.target

上面說的是我現在使用的開發環境搭建方法,有興趣愛折騰的同學不妨試試看,如果你有更好的方法,也希望能分享給我。本次培訓內容包括:Docker基礎、容器技術、Docker鏡像、數據共享與持久化、Docker三駕馬車、Docker實踐、Kubernetes基礎、Pod基礎與進階、常用對象操作、服務發現、Helm、Kubernetes核心組件原理分析、Kubernetes服務質量保證、調度詳解與應用場景、網絡、基於Kubernetes的CI/CD、基於Kubernetes的配置管理等,點擊了解具體培訓內容

相關焦點

  • 使用 Docker 搭建 Laravel 本地環境
    也就是一個虛擬機,但是跟 docker 比,它佔用體積太大,啟動速度慢,同時響應速度很慢,現在有了 docker 這種更好的方式,可以輕鬆方便的搭建整套 PHP 開發環境。本文就介紹如何使用 docker 搭建 Laravel 本地環境。安裝 docker首先安裝 docker。
  • 用Docker和Git搭建在線開發環境
    在線的集成開發環境:兼容各大主流瀏覽器隔離的運行環境:隔離,可定製,高效調試代碼:查看日誌,可設置跟蹤斷點基於技術難點,我做了一些調查研究,選擇了幾個備選的開源技術。目前,只確定了使用Docker來實現運行環境。集成在線開發環境,我使用Git來解耦代碼運行環境和編輯環境,並代碼同步。
  • PyCharm使用之利用Docker鏡像搭建Python開發環境
    在我們平時使用PyCharm的過程中,一般都是連接本地的Python環境進行開發,但是如果是離線的環境呢?
  • 基於 Docker 搭建 PHP 開發環境
    (給PHP開發者加星標,提升PHP技能)轉自:HesunflyDocker 是這幾年非常火的一項技術,作為一名軟體開發人員
  • 使用 Docker 快速搭建多版本 PHP 開發環境
    文章目錄:目標下載代理設置配置環境PHP 7.2.x,佔用本地埠 8081PHP 5.6.x,佔用本地埠 8082埠映射備註docker-compose 相關命令文章中使用的軟體:Mac:11.4(macOS Big Sur) ,處理器為:Intel Core。目標下載Docker 軟體下載安裝,不做過多解釋,一步步安裝即可。
  • Docker 搭建 Django+Mariadb 環境
    二、正文環境之「Docker-Mariadb」搭建參考:在 Mac 中直接安裝 Maridb(不推薦),Mac 中 MariaDB 資料庫的安裝步驟(https://www.jb51.net/article/93202.htm)首先,把你的宿主機 mac 或 linux 裝上 tree 命令。
  • Docker 開發鏡像搭建與DockerFile分享
    背景    之前搭建過一個開發鏡像,包含了 java、go 語言等基本的開發環境,結合 vscode remote 模式,可在本地直接進行開發,免去了安裝各種基礎環境和配置環境變量的麻煩但是對於使用者來說,依然有兩個並不方便的地方:易用性
  • 使用 Docker 搭建 Java Web 運行環境
    本文會對虛擬化技術與 Docker 容器技術做一個對比,然後引出一些 Docker 的名詞術語,比如:容器、鏡像等,隨後將使用 Docker 搭建一個 Java Web 運行環境,最後將對本文做一個總結。
  • 經驗分享|使用code-server為Docker容器搭建在線開發環境
    只要伺服器端配置好code-server,就可以在任何瀏覽器上使用VScode訪問伺服器的代碼進行編程。(GitHub地址:https://github.com/cdr/code-server)Docker是一個開源的Linux容器引擎。我們在日常的開發任務中可以利用Docker容器快速地搭建實驗環境或對項目進行遷移部署。
  • 如何在Linux下使用docker搭建LNMP環境
    最近在使用docker的過程中遇到了許許多多的坑。首次使用它也是浪費了大量的精力。今天我們來簡單說下如何用它搭建一個LNMP環境吧,遇到的坑和解決方法我也會寫到裡面。。            最近也是想構思一個小項目玩玩,首先就是環境的選擇,因為我是在個人電腦上測試環境等等,首先考慮的就是資源利用的問題,例如分布式,集群等等。
  • PHP/Laravel 本地開發環境搭建:Mac 篇
    聲明:本系列教程主體基於 Mac 環境,但是為了照顧使用 Windows 的同學,我也會基於 Windows 環境搭建開發環境進行代碼驗證。
  • Dockerfile搭建極簡LNMP環境
    來運行一個lnmp環境。常規環境搭建的方式有兩種,一種是把php、mysql、nginx分別編寫一個Dockerfile,然後再使用docker-compose.yml來編寫一個容器互連的配置,使用docker-compose來管理和生成容器。另外一種方式是把php、nginx、mysql都安裝到一個鏡像裡面,簡單粗暴。
  • 使用 Docker 搭建第一個 Node 項目到伺服器
    通過鏡像 dockerstudy 創建一個容器並運行。
  • 使用 Docker 作為 Python 開發環境
    雖然我本人專注於Python的Flask微框架,但本文目的是演示如何通過Docker更好地開發和共享應用程式,(由任何語言和框架開發的應用程式)。Docker通過封裝依賴項,大大減少了開發環境和正式產品的差距。大多數Python開發人員在開發中使用virtualenv。
  • IFTTT在開發環境中的Docker使用經驗
    改造我們的生產環境架構之前,我們決定首先從本地開發環境開始實踐。這樣我們就可以在冒險上生產環境之前發現應用程式的的一些問題。另外,本地開發環境已經偏離了我們現存的生產環境。我們使用Chef(一個系統集成框架,為整個架構提供配置管理功能)和Vagrant(一款用來構建虛擬開發環境的工具)提供管理本地虛擬機。它雖然一直在工作,但是我們知道它工作不了太久。
  • 如何在CentOS7下通過Docker方式搭建OpenStf環境?
    但其實這款工具還可以幫助解決公司內部行動裝置資源不能充分利用的問題,如:公司行動裝置其實是有限的,有的人借走了用完未及時歸還,導致其他人就無法使用,而使用這款工具就可以統一監控公司的所有行動裝置資源,使用者可在瀏覽器界面上查看哪些設備是空閒狀態,在頁面上就可以操作對應設備。
  • 基於Docker搭建輕量的私有構建環境
    這種工程實踐在為研發和交付帶來極大便利的同時,對應用本身的架構、配置管理以及本地環境的資源利用有效性都提出了很高的要求。我們的分享將解釋如何基於Docker搭建一套輕量級的私有構建環境並及集成到持續集成系統中。Docker技術的應用談的比較多的是改變伺服器管理和運維模式,在日常開發工作中如何使用Docker看到的實踐比較少。
  • Docker+Selenium Grid+Python搭建分布式測試環境
    於是搭建了一個分布式的測試環境來試試。來搭建測試Web兼容性的環境。  此方案不足的地方在於需要同時使用到多個機器或者多個虛擬機,這對於資金不足或者純上手練習的人來說不是一個好東西。  既然Docker現在已經如此流行,此次嘗試著在Docker的環境中搭建用於兼容性Web測試的分布式測試環境。  目標:  1.成功搭建docker結合selenium構建分布式測試環境。
  • 用Git子模塊和Docker Compose實現高效開發工作流
    曾經,我入職一個公司的第一整天都花在搭建開發環境上,試圖去理解所有的東西怎麼才能一起工作,而無法直接就去理解公司開發的應用到底是怎麼工作的。方案在具體介紹如何解決上述問題之前,我先介紹下我們項目使用的開發工作流。我們的每個項目都在Bitbucket上有自己的Team(和GitHub上的Organization對應)。
  • Docker搭建pwn環境
    本文為看雪論壇優秀文章看雪論壇作者ID:直木其實以前就想搭建一個docker環境,但是那時候想用dockfile來一步到位