Docker:糟糕的建議

Docker:糟糕的建議

當我學開車的時候,第一堂課教練把車倒車開進路口,然後說你不應該這樣做——絕對不行。 我立即記住了這條規則,並終生記住。

當你給孩子們讀格里戈里·奧斯特的《壞建議》時,你會發現他們很容易、自然地意識到他們不應該這樣做。

關於如何正確撰寫 Dockerfile 已經寫了很多文章。 但我沒有遇到有關如何編寫不正確的 Dockerfile 的說明。 我正在填補這個空白。 也許在我獲得支援的專案中,這樣的 dockerfile 會更少。

所有人物、場景和 Dockerfile 均屬虛構。 如果你認識自己的話,對不起。

創建一個 Dockerfile,不祥且可怕

Peter(資深java/rubby/php開發人員):Vasily同事,您已經將新模組上傳到Docker了嗎?
Vasily(初級):不,我沒有時間,我無法用這個 Docker 搞清楚。 這方面的文章太多了,讓人眼花撩亂。

彼得:我們一年前就有了最後期限。 讓我來幫助你,我們會在這個過程中解決這個問題。 告訴我什麼對你沒效。

Vasily:我無法選擇基本圖像,因此它很小,但具有您需要的一切。
Peter:以 ubuntu 鏡像為例,它有你需要的一切。 而且很多不必要的東西,以後都會派上用場的。 並且不要忘記添加最新標籤,以便版本始終是最新的。

第一行出現在 Dockerfile 中:

FROM ubuntu:latest

Peter:下一步是什麼,我們用什麼來寫我們的模組?
Vasily:Ruby,有一個 Web 伺服器和幾個服務守護程序應該啟動。
Peter:是的,我們需要什麼:ruby、bundler、nodejs、imagemagick 以及其他什麼...同時,進行升級以獲得新的軟體包。
Vasily:我們不會創建一個用戶,這樣我們就不會處於 root 狀態了?
彼得:操,那你還得玩弄權利。
Vasily:我需要時間,大約 15 分鐘,將所有內容整合到一個命令中,我讀到…
(彼得粗魯地打斷了這位細心且非常聰明的後輩。)
Peter:用單獨的指令寫,這樣會比較容易閱讀。

Dockerfile 成長:

FROM ubuntu:latest
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full
RUN gem install bundler
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
RUN bundle install --without development test --path vendor/bundle
RUN rm -rf /usr/local/bundle/cache/*.gem 
RUN apt-get clean 
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

然後 Igor Ivanovich,DevOps(但更多是運維而不是 Dev),衝進辦公室大喊:

AI:Petya,你們的開發者又破壞了食物資料庫,這什麼時候結束…

一場小衝突後,伊戈爾·伊凡諾維奇冷靜下來,開始了解他的同事在這裡做什麼。

艾:你在做什麼?
Vasily:Peter 正在幫助我為新模組建立 Dockerfile。
AI:讓我看看...你在這裡寫了什麼,你用一個單獨的命令清理儲存庫,這是一個附加層...但是如果你沒有複製 Gemfile,你如何安裝依賴項! 一般來說,這不好。
彼得:請忙你的事吧,我們會想辦法解決的。

伊戈爾·伊万諾維奇悲傷地嘆了口氣,然後離開去查明是誰破壞了資料庫。

彼得:是的,但他對程式碼的看法是對的,我們需要將其推入圖像中。 讓我們立即安裝 ssh 和supervisor,否則我們將啟動守護程式。

Vasily:然後我會先複製 Gemfile 和 Gemfile.lock,然後安裝所有內容,然後複製整個專案。 如果 Gemfile 沒有改變,則將從快取中取得該圖層。
Peter:為什麼你們都用這些圖層,一次複製所有內容。 立即複製。 第一行。

Dockerfile 現在看起來像這樣:

FROM ubuntu:latest
COPY ./ /app
WORKDIR /app
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
RUN gem install bundler
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs

RUN bundle install --without development test --path vendor/bundle
RUN rm -rf /usr/local/bundle/cache/*.gem 
RUN apt-get clean 
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

彼得:那麼,接下來怎麼辦? 有主管的配置嗎?
瓦西里:不,不。 但我會很快做的。
彼得:那你就去做吧。 現在讓我們草擬一個將啟動所有內容的初始化腳本。 好的,那麼你用 nohup 啟動 ssh,這樣我們就可以連接到容器並查看出了什麼問題。 然後以同樣的方式運行supervisor。 好吧,那你就跑乘客吧。
Q:但我讀到應該有一個進程,這樣 Docker 就會知道出了問題並且可以重新啟動容器。
P:別用廢話來打擾你的頭腦。 一般來說,怎麼樣? 如何在一個進程中運行所有這些? 讓伊戈爾·伊凡諾維奇考慮穩定,他收到薪水不是白費的。 我們的工作就是寫程式碼。 總的來說,讓他對我們為他編寫的文檔文件表示感謝。

10 分鐘和兩個關於貓的影片。

問:我已經做了一切。 我添加了更多評論。
普:告訴我!

Dockerfile 的最新版本:

FROM ubuntu:latest

# Копируем исходный код
COPY ./ /app
WORKDIR /app

# Обновляем список пакетов
RUN apt-get update 

# Обновляем пакеты
RUN apt-get upgrade

# Устанавливаем нужные пакеты
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor

# Устанавливаем bundler
RUN gem install bundler

# Устанавливаем nodejs используется для сборки статики
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs

# Устанавливаем зависимости
RUN bundle install --without development test --path vendor/bundle

# Чистим за собой кэши
RUN rm -rf /usr/local/bundle/cache/*.gem 
RUN apt-get clean 
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

# Запускаем скрипт, при старте контейнера, который запустит все остальное.
CMD [“/app/init.sh”]

普:太好了,我喜歡。 而且評論都是俄文的,方便易讀,大家都會這樣操作。 我已經教你一切了,剩下的你可以自己做。 我們去喝杯咖啡吧...

好吧,現在我們有了一個非常糟糕的 Dockerfile,看到它會讓 Igor Ivanovich 想退出,他的眼睛又會痛一個星期。 當然,Dockerfile 可能更糟,完美無極限。 但首先,這樣就可以了。

我想引用格里戈里·奧斯特的一句話作為結尾:

如果您還不確定
我們選擇了人生的道路,
而你不知道為什麼
開啟你的勞動之旅,
打破走廊裡的燈泡 -
人們會對你說「謝謝」。
你會幫助人民
節約用電。

來源: www.habr.com

添加評論