RUN
- source之類無效
- 在container運行前作的事不會保留到之後
- ex: roscore在這裡下, docker run後一樣不存在
ADD
- build時與
RUN wget
一樣都有可能不會被cache- https://github.com/moby/moby/issues/12361
- github的話個人只在windows的docker遇到, linux會正常cache
- 用法
ADD http://example.com/big.tar.xz /usr/src/things/
ARG
- 只在build時有效, 也可以在build時帶入
--build-arg
- 必須是key=value
ENV
- 在build & docker run時都有效
- 可以是key value or key=value
在ENV與ARG參數的設定上,可以透過下面方式
- ${variable:-word} 代表,如果variable有給值,則以variable設定的文字為主,如未設定,則以word字串為主。
- ${variable:+word} 代表,如果variable有給值,則值為word;如果variable未給值,則最後結果為空字串(empty)。
有沒有大括號都可
==docker build失敗會產生多餘的container**
https://stackoverflow.com/questions/36808476/why-docker-build-image-from-docker-file-will-create-container-when-build-exit-in
Layers
太多行的RUN可能會導致build的非常慢
https://stackoverflow.com/questions/47079114/should-i-minimize-the-number-of-docker-layers
最好的實作辦法:
- making sure the most general steps, and the longest are first, that will then cached
- making sure the longest RUN command come first and in their own layer (again to be cached)
optimized的tools
- dive: https://github.com/wagoodman/dive
exclude特定files
https://docs.docker.com/engine/reference/builder/#dockerignore-file You can even ==use the .dockerignore file to exclude the Dockerfile and .dockerignore files.== These files are still sent to the daemon because it needs them to do its job. But the ADD and COPY instructions do not copy them to the image.
build用/bin/sh
如何用/bin/bash來跑dockerfile內的RUN
https://stackoverflow.com/questions/20635472/using-the-run-instruction-in-a-dockerfile-with-source-does-not-work https://github.com/moby/moby/issues/7281
不能用RUN來執行background process
以下無效
要用CMD才行
https://stackoverflow.com/a/57175879
- 上面的
&
還是會有執行該指令的output, 只是ctrl+c不會中斷他 - 要做到完全無output要用
nohup
- https://stackoverflow.com/questions/9190151/how-to-run-a-command-in-the-background-and-get-no-output
nohup /path/to/your/script.sh > /dev/null 2>&1 &
https://charleslin74.pixnet.net/blog/post/405455902 https://kknews.cc/zh-tw/code/r3z2e3v.html ==2>&1表明將文件描述2(標準錯誤輸出)的內容重定向到文件描述符1(標準輸出)==,為什麼1前面需要&?當==沒有&時,1會被認為是一個普通的文件==,有&表示重定向的目標不是一個文件,而是一個文件描述符。 1與2誰先幾乎無差, https://blog.csdn.net/u011630575/article/details/52151995
暫時性操作無效, 像是修改環境變數
COPY新檔案失效
docker build --no-cache .
確保container不會結束
解法有三種
bin/bash
ortail -f /dev/null
xxx.sh ; sleep infinity
- &後面要導向output, ex:
roscore &
詳細解釋
use tail -f /dev/null
or /bin/bash
to make sure you shell done and suspend a process in system so that docker container not shutdown
https://stackoverflow.com/questions/42218957/dockerfile-cmd-instruction-will-exit-the-container-just-after-running-it
像是把roscore &
寫在dockerfile的cmd話也會觸發end, 因為roscore &
這個指令執行完了
但如果只用roscore
因為有output卡住就不會end
You run a container, which ==runs a shell script to perform some tasks. When the shell script completes, the container will exit==, because there’s nothing left for the container to run. https://www.tutorialworks.com/why-containers-stop/
docker的偵測process機制(PID 1)
https://stackoverflow.com/a/30632659 PID 1是啟動init 進程,是系統的第一個進程,又叫超級進程,也叫根進程。它負責產生其他所有用戶進程。所有的進程都會被掛在這個進程下,如果這個進程退出了,那麼所有的進程都被kill 。如果一個子進程的父進程退了,那麼這個子進程會被掛到PID 1 下面。(注:PID 0 是內核的一部分,主要用於內進換頁) https://coolshell.cn/articles/17998.html
官方文件對run mulitple background process的教學
https://docs.docker.com/config/containers/multi-service_container/
可以用runit來把container當小vm用
https://github.com/wk8/docker-runit
如果在背景run service也有可能遇到相同問題
https://stackoverflow.com/questions/25775266/how-to-keep-docker-container-running-after-starting-services
當然實際在delpoy時設計的container應該是
- there is only one process running (i.e. you should have one container for Nginx, and one for supervisord or the app it’s running)
- additionally, that process should run in the foreground
https://stackoverflow.com/a/25775424