wait-for-it.sh - 使用 Docker Compose depends_on 的必備 bash script

Posted on  Nov 1, 2019  in  Docker  by  Amo Chen  ‐ 2 min read

撰寫 docker-compose.yaml 經常會遇到要使用 depends_on 的情況,確保某些特定的服務可以先啟動,例如 Web Application 經常要 depends_on 資料庫(database)服務。

但是 depends_on 指確保該 container 狀態會進到 running ,而非確保 container 內的服務會完整啟動結束。

However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running.

以 Web Application 與資料庫服務為例,在這種情況下,就會遇到資料庫服務的 container 已經進到 running ,但其實資料庫的程序(process)還沒完全啟動,進而導致 Web Application 服務連不到資料庫而失敗。

遇到這問題,建議可以使用 wait-for-it.sh 來解決!

wait-for-it.sh

wait-for-it.sh 是用 bash 所寫成的 script, 專門用以確定指定的 Host 與 Port 能夠連線,因此可以避免 depends_on 可能會遇到的問題。

當然,如果你所使用的 docker image 有內建的 sleep 指令可以使用的話,其實也可以簡單使用 sleep 等待個幾秒就好,但不見得所有的 docker image 內都有 sleep ,譬如 golang 的 image 就沒有 sleep 指令能夠使用,所以使用 wait-for-it.sh 會讓事情簡單許多。

wait-for-it.sh 可以在 vishnubob/wait-for-it 下載,並不需要額外安裝什麼軟體,唯一的要求只有 bash 。

最簡單的使用方法如下:

$ chmod +x ./wait-for-it.sh
$ ./wait-for-it.sh 127.0.0.1:9999 -t 5 -- echo "server is up"

上述的指令會負責確認本機(127.0.0.1)的 9999 通訊埠可以連線,如果超過 5 秒都無法連線就直接結束執行,如果能夠正常連線則直接列印 “server is up” 字串。

docker-compose.yaml 與 wait-for-it.sh 應用範例

接下來以實際範例解說如何將 wait-for-it.sh 應用至 docker-compose.yaml 中。

以下 docker-compose.yaml 中的 web 需要 db 先啟動完成:

version: "3"
services:
  web:
    container_name: "web"
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - db
    ports:
      - "5000:5000"
  db:
    image: "postgres:10"
    restart: always
    container_name: "db"
    ports:
      - "5432:5432"

那麼就必須在 web 的 Dockerfile 中加上 wait-for-it.sh ,讓 web 等待 db 能夠連線後再執行真正的服務,例如以下的 golang Dockerfile 最後 CMD 的部分:

FROM golang:1.12.12-buster
WORKDIR /go/app
COPY . .
RUN go build -o webapp main.go
EXPOSE 5000
CMD ["./wait-for-it.sh", "db:5432", "--", "./webapp"]

最後,除了 bash 寫成的 wait-for-it.sh 之外,如果是習慣使用 sh 的人,則可以使用 wait-for

以上, Happy Coding!

References

https://docs.docker.com/compose/startup-order/

FOLLOW US

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!