麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 操作系統(tǒng) > 正文

Docker Compose構(gòu)建開發(fā)環(huán)境的好方式

2024-07-26 00:27:14
字體:
供稿:網(wǎng)友
  最近,我考慮了很多關(guān)于這種個(gè)人開發(fā)環(huán)境的搭建方式,原因是,我現(xiàn)在把所有的計(jì)算工作都搬到了一個(gè)私有云上,大概 20 美元/月的樣子。這樣一來,我就不用在工作的時(shí)候花時(shí)間去思考應(yīng)該如何管理幾千臺(tái) AWS 服務(wù)器了。
 
  在此之前,我曾花了兩天的時(shí)間,嘗試使用其他的工具來嘗試搭建一個(gè)開發(fā)環(huán)境,搭到后面,我實(shí)在是心累了。相比起來,Docker Compose 就簡單易用多了,我非常滿意。于是,我和妹妹分享了我的 ​​docker-compose​​ 使用經(jīng)歷,她略顯驚訝:“是吧!你也覺得 Docker Compose 真棒對吧!” 嗯,我覺得我應(yīng)該寫一篇博文把過程記錄下來,于是就有了你們看到的這篇文章。
 
  我們的目標(biāo)是:搭建一個(gè)開發(fā)環(huán)境
  目前,我正在編寫一個(gè) Ruby on Rails 服務(wù)(它是一個(gè)計(jì)算機(jī)“調(diào)試”游戲的后端)。在我的生產(chǎn)服務(wù)器上,我安裝了:
 
  一個(gè) Nginx 服務(wù)器
  一個(gè) Rails 服務(wù)
  一個(gè) Go 服務(wù)(使用了​​gotty​​ 來代理一些 SSH 連接)
  一個(gè) Postgres 數(shù)據(jù)庫
  在本地搭建 Rails 服務(wù)非常簡單,用不著容器(我只需要安裝 Postgres 和 Ruby 就行了,小菜一碟)。但是,我還想要把匹配 ​​/proxy/*​​ 的請求的發(fā)送到 Go 服務(wù),其他所有請求都發(fā)送到 Rails 服務(wù),所以需要借助 Nginx。問題來了,在筆記本電腦上安裝 Nginx 對我來說太麻煩了。
 
  是時(shí)候使用 ​​docker-compose​​ 了!
 
  docker-compose 允許你運(yùn)行一組 Docker 容器
  基本上,Docker Compose 的作用就是允許你運(yùn)行一組可以互相通信 Docker 容器。
 
  你可以在一個(gè)叫做 ​​docker-compose.yml​​​ 的文件中,配置你所有的容器。我在下方將貼上我為這個(gè)服務(wù)編寫的 ​​docker-compose.yml​​ 文件(完整內(nèi)容),因?yàn)槲矣X得它真的很簡潔、直接!
 
  復(fù)制
  version: "3.3"
      services:
        db:
          image: postgres
          volumes:
            - ./tmp/db:/var/lib/postgresql/data
          environment:
            POSTGRES_PASSWORD: password # yes I set the password to 'password'
        go_server:
          # todo: use a smaller image at some point, we don't need all of ubuntu to run a static go binary
          image: ubuntu
          command: /app/go_proxy/server
          volumes:
            - .:/app
        rails_server:
          build: docker/rails
          command: bash -c "rm -f tmp/pids/server.pid && source secrets.sh && bundle exec rails s -p 3000 -b '0.0.0.0'"
          volumes:
            - .:/app
        web:
          build: docker/nginx
          ports:
            - "8777:80" # this exposes port 8777 on my laptop
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  12.
  13.
  14.
  15.
  16.
  17.
  18.
  19.
  20.
  21.
  22.
  23.
  這個(gè)配置包含了兩種容器。對于前面兩個(gè)容器,我直接使用了現(xiàn)有的鏡像(​​image: postgres​​​ 和 ​​image: ubuntu​​​)。對于后面兩個(gè)容器,我不得不構(gòu)建一個(gè)自定義容器鏡像,其中, ​​build: docker/rails​​​ 的作用就是告訴 Docker Compose,它應(yīng)該使用 ​​docker/rails/Dockerfile​​ 來構(gòu)建一個(gè)自定義容器。
 
  我需要允許我的 Rails 服務(wù)訪問一些 API 密鑰和其他東西,因此,我使用了 ​​source secrets.sh​​,它的作用就是在環(huán)境變量中預(yù)設(shè)一組密鑰。
 
  如何啟動(dòng)所有服務(wù):先 “build” 后 “up”
  我一直都是先運(yùn)行 ​​docker-compose build​​​ 來構(gòu)建容器,然后再運(yùn)行 ​​docker-compose up​​ 把所有服務(wù)啟動(dòng)起來。
 
  你可以在 yaml 文件中設(shè)置 ​​depends_on​​,從而進(jìn)行更多啟動(dòng)容器的控制。不過,對于我的這些服務(wù)而言,啟動(dòng)順序并不重要,所以我沒有設(shè)置它。
 
  網(wǎng)絡(luò)互通也非常簡單
  容器之間的互通也是一件很重要的事情。Docker Compose 讓這件事變得超級簡單!假設(shè)我有一個(gè) Rails 服務(wù)正在名為 ​​rails_server​​​ 的容器中運(yùn)行,端口是 3000,那么我就可以通過 ​​http://rails_server:3000​​ 來訪問該服務(wù)。就是這么簡單!
 
  以下代碼片段截取自我的 Nginx 配置文件,它是根據(jù)我的使用需求配置的(我刪除了許多 ​​proxy_set_headers​​ 行,讓它看起來更清楚):
 
  復(fù)制
  location ~ /proxy.* {
        proxy_pass http://go_server:8080;
      }
      location @app {
        proxy_pass http://rails_server:3000;
      }
  1.
  2.
  3.
  4.
  5.
  6.
  或者,你可以參考如下代碼片段,它截取自我的 Rails 項(xiàng)目的數(shù)據(jù)庫配置,我在其中使用了數(shù)據(jù)庫容器的名稱(​​db​​):
 
  復(fù)制
  development:
        <<: *default
        database: myproject_development
        host: db # <-------- 它會(huì)被“神奇地”解析為數(shù)據(jù)庫容器的 IP 地址
        username: postgres
        password: password
  1.
  2.
  3.
  4.
  5.
  6.
  至于 ​​rails_server​​ 究竟是如何被解析成一個(gè) IP 地址的,我還真有點(diǎn)兒好奇。貌似是 Docker 在我的計(jì)算機(jī)上運(yùn)行了一個(gè) DNS 服務(wù)來解析這些名字。下面是一些 DNS 查詢記錄,我們可以看到,每個(gè)容器都有它自己的 IP 地址:
 
  復(fù)制
  $ dig +short @127.0.0.11 rails_server
      172.18.0.2
      $ dig +short @127.0.0.11 db
      172.18.0.3
      $ dig +short @127.0.0.11 web
      172.18.0.4
      $ dig +short @127.0.0.11 go_server
      172.18.0.5
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  是誰在運(yùn)行這個(gè) DNS 服務(wù)?
  我(稍微)研究了一下這個(gè) DNS 服務(wù)是怎么搭建起來的。
 
  以下所有命令都是在容器外執(zhí)行的,因?yàn)槲覜]有在容器里安裝很多網(wǎng)絡(luò)工具。
 
  第一步::使用 ​​ps aux | grep puma​​,獲取 Rails 服務(wù)的進(jìn)程 ID。
 
  找到了,它是 ​​1837916​​!簡單~
 
  第二步::找到和 ​​1837916​​ 運(yùn)行在同一個(gè)網(wǎng)絡(luò)命名空間的 UDP 服務(wù)。
 
  我使用了 ​​nsenter​​​ 來在 ​​puma​​​ 進(jìn)程的網(wǎng)絡(luò)命令空間內(nèi)運(yùn)行 ​​netstat​​​(理論上,我猜想你也可以使用 ​​netstat -tupn​​​ 來只顯示 UDP 服務(wù),但此時(shí),我的手指頭只習(xí)慣于打出 ​​netstat -tulpn​​)。
 
  復(fù)制
  $ sudo nsenter -n -t 1837916 netstat -tulpn
      Active Internet connections (only servers)
      Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
      tcp        0      0 127.0.0.11:32847        0.0.0.0:*               LISTEN      1333/dockerd
      tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      1837916/puma 4.3.7
      udp        0      0 127.0.0.11:59426        0.0.0.0:*                           1333/dockerd
  1.
  2.
  3.
  4.
  5.
  6.
  我們可以看到,此時(shí)有一個(gè)運(yùn)行在 ​​59426​​​ 端口的 UDP 服務(wù),它是由 ​​dockerd​​ 運(yùn)行的!或許它就是我們要找的 DNS 服務(wù)?
 
  第三步:確定它是不是我們要找的 DNS 服務(wù)
 
  我們可以使用 ​​dig​​ 工具來向它發(fā)送一個(gè) DNS 查詢:
 
  復(fù)制
  $ sudo nsenter -n -t 1837916 dig +short @127.0.0.11 59426 rails_server
      172.18.0.2
  1.
  2.
  奇怪,我們之前運(yùn)行 ​​dig​​​ 的時(shí)候,DNS 查詢怎么沒有發(fā)送到 ​​59426​​​ 端口,而是發(fā)送到了 ​​53​​ 端口呢?這到底是怎么回事呀?
 
  第四步:iptables
 
  對于類似“這個(gè)服務(wù)似乎正運(yùn)行在 X 端口上,但我卻在 Y 端口上訪問到了它,這是什么回事呢?”的問題,我的第一念頭都是“一定是 iptables 在作怪”。
 
  于是,我在運(yùn)行了容器的網(wǎng)絡(luò)命令空間內(nèi)執(zhí)行 ​​iptables-save​​,果不其然,真相大白:
 
  復(fù)制
  $ sudo nsenter -n -t 1837916 iptables-save
      .... redacted a bunch of output ....
      -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -m udp --sport 59426 -j SNAT --to-source :53
      COMMIT
  1.
  2.
  3.
  4.
  在輸出中有一條 iptables 規(guī)則,它將 ​​53​​​ 端口的流量發(fā)送到了 ​​59426​​ 上。哈哈,真有意思!
 
  數(shù)據(jù)庫文件儲(chǔ)存在一個(gè)臨時(shí)目錄中
  這樣做有一個(gè)好處:我可以直接掛載 Postgres 容器的數(shù)據(jù)目錄 ​​./tmp/db​​,而無需在我的筆記本電腦上管理 Postgres 環(huán)境。
 
  我很喜歡這種方式,因?yàn)槲艺娴牟幌朐诠P記本電腦上獨(dú)自管理一個(gè) Postgres 環(huán)境(我也真的不知道該如何配置 Postgres)。另外,出于習(xí)慣,我更喜歡讓開發(fā)環(huán)境的數(shù)據(jù)庫和代碼放在同一個(gè)目錄下。
 
  僅需一行命令,我就可以訪問 Rails 控制臺(tái)
  管理 Ruby 的版本總是有點(diǎn)棘手,并且,即使我暫時(shí)搞定了它,我也總是有點(diǎn)擔(dān)心自己會(huì)把 Ruby 環(huán)境搞壞,然后就要修它個(gè)十年(夸張)。
 
 ?。ㄊ褂?Docker Compose)搭建好這個(gè)開發(fā)環(huán)境后,如果我需要訪問 Rails 控制臺(tái)console(一個(gè)交互式環(huán)境,加載了所有我的 Rails 代碼),我只需要運(yùn)行一行代碼即可:
 
  復(fù)制
  $ docker-compose exec rails_server rails console
      Running via Spring preloader in process 597
      Loading development environment (Rails 6.0.3.4)
      irb(main):001:0>
  1.
  2.
  3.
  4.
  好耶!
 
  小問題:Rails 控制臺(tái)的歷史記錄丟失了
  我碰到了一個(gè)問題:Rails 控制臺(tái)的歷史記錄丟失了,因?yàn)槲乙恢痹诓粩嗟刂貑⑺?br /> 
  不過,我也找到了一個(gè)相當(dāng)簡單的解決方案(嘿嘿):我往容器中添加了一個(gè) ​​/root/.irbrc​​ 文件,它能夠把 IRB 歷史記錄文件的保存位置指向一個(gè)不受容器重啟影響的地方。只需要一行代碼就夠啦:
 
  復(fù)制
  IRB.conf[:HISTORY_FILE] = "/app/tmp/irb_history"
  1.
  我還是不知道它在生產(chǎn)環(huán)境的表現(xiàn)如何
  到目前為止,這個(gè)項(xiàng)目的生產(chǎn)環(huán)境搭建進(jìn)度,還停留在“我制作了一個(gè) DigitalOcean droplet(LCCT 譯注:一種 Linux 虛擬機(jī)服務(wù)),并手工編輯了很多文件”的階段。
 
  嗯……我相信以后會(huì)在生產(chǎn)環(huán)境中使用 docker-compose 來運(yùn)行一下它的。我猜它能夠正常工作,因?yàn)檫@個(gè)服務(wù)很可能最多只有兩個(gè)用戶在使用,并且,如果我愿意,我可以容忍它在部署過程中有 60 秒的不可用時(shí)間。不過話又說回來,出錯(cuò)的往往是我想不到的地方。
 
  推特網(wǎng)友提供了一些在生產(chǎn)中使用 docker-compose 的注意事項(xiàng):
 
  ​​docker-compose up​​ 只會(huì)重啟那些需要重啟的容器,這會(huì)讓重啟速度更快。
  有一個(gè) Bash 小腳本​​wait-for-it​​,你可以用它來保持等待一個(gè)容器,直到另一個(gè)容器的服務(wù)可用。
  你可以準(zhǔn)備兩份​​docker-compose.yaml​​​ 文件:用于開發(fā)環(huán)境的​​docker-compose.yaml​​​ 和用于生產(chǎn)環(huán)境的​​docker-compose-prod.yaml​​​。我想我會(huì)在分別為 Nginx 指定不同的端口:開發(fā)時(shí)使用​​8999​​​,生產(chǎn)中使用​​80​​。
  人們似乎一致認(rèn)為,如果你的項(xiàng)目是一臺(tái)計(jì)算機(jī)上運(yùn)行的小網(wǎng)站,那么 docker-compose 在生產(chǎn)中不會(huì)有問題。
  有個(gè)人建議說,如果愿意在生產(chǎn)環(huán)境搭建復(fù)雜那么一丟丟,Docker Swarm 就或許會(huì)是更好的選擇,不過我還沒試過(當(dāng)然,如果要這么說的話,干嘛不用 Kubernetes 呢?Docker Compose 的意義就是它超級簡單,而 Kubernetes 肯定不簡單 : ))。
  Docker 似乎還有一個(gè)特性,它能夠 ​​把你用 docker-compose 搭建的環(huán)境,自動(dòng)推送到彈性容器服務(wù)(ESC)上​​,聽上去好酷的樣子,但是我還沒有試過。
 
  docker-compose 會(huì)有不適用的場景嗎
  我聽說 docker-compose 在以下場景的表現(xiàn)較差:
 
  當(dāng)你有很多微服務(wù)的時(shí)候(還是自己搭建比較好)
  當(dāng)你嘗試從一個(gè)很大的數(shù)據(jù)庫中導(dǎo)入數(shù)據(jù)時(shí)(就像把幾百 G 的數(shù)據(jù)存到每個(gè)人的筆記本電腦里一樣)
  當(dāng)你在 Mac 電腦上運(yùn)行 Docker 時(shí)。我聽說 Docker 在 macOS 上比在 Linux 上要慢很多(我猜想是因?yàn)樗枰鲱~外的虛擬化)。我沒有 Mac 電腦,所以我還沒有碰到這個(gè)問題。
  以上就是全部內(nèi)容啦!
  在此之前,我曾花了一整天時(shí)間,嘗試使用 Puppet 來配置 Vagrant 虛擬機(jī),然后在這個(gè)虛擬機(jī)里配置開發(fā)環(huán)境。結(jié)果,我發(fā)現(xiàn)虛擬機(jī)啟動(dòng)起來實(shí)在是有點(diǎn)慢啊,還有就是,我也不喜歡編寫 Puppet 配置(哈哈,沒想到吧)。
 
  幸好,我嘗試了 Docker Compose,它真好簡單,馬上就可以開始工作啦!

(編輯:武林網(wǎng))

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久久青 | 日本不卡视频在线观看 | 视频一区二区三区在线播放 | 成人影片在线免费观看 | 一级大黄毛片免费观看 | 最新午夜综合福利视频 | 99re久久最新地址获取 | 涩涩伊人 | 精品国产九九九 | 久久精品女人天堂av | 逼特逼视频在线观看 | av成人免费看| 中文字幕在线第二页 | 羞羞视频在线免费 | 午夜丰满少妇高清毛片1000部 | 国产在线导航 | 91精品国产乱码久久桃 | 亚洲日本高清 | 日本中文高清 | 国产羞羞视频在线观看 | 中文日韩字幕 | 宅男噜噜噜66国产免费观看 | 久草视频福利在线观看 | 羞羞网站在线看 | 精品无码久久久久久国产 | 日本在线不卡一区二区三区 | 永久免费黄色大片 | 国产日产精品一区四区介绍 | 色播av在线 | 国产成年人视频 | 免费看操片 | 精品国产久 | 国产一级一片免费播放 | 久久亚洲精选 | 黄在线观看 | 国产精品久久久久久久久久大牛 | 中国字幕av | 中文字幕视频在线播放 | 精品国产一区二区三区久久久蜜 | 女18一级大黄毛片免费女人 | 99精品视频在线观看免费 |