Docker COPY 導致 exec user process caused: no such file or directory

情境

現今有一個資料夾 folder 底下有 bin 跟 lib 還有其他東西

folder/
  |-- bin/
  |-- lib/
  |-- other/

然後要將之拷貝進系統中,bin 至 /bin、lib 至 /lib、other 至 /other

FROM ubuntu:18.04
COPY folder/ /

在 18.04 時沒問題,但在 20.04 下如果有後續指令,或者要開啟 container 的話會出現以下錯誤

standard_init_linux.go:228: exec user process caused: no such file or directory
The command '/bin/sh -c ...' returned a non-zero code: 1 

到這裡大家可以先想一下為何會出錯,同樣的拷貝在 18.04 沒問題,但到 20.04 就會出錯

查找錯誤過程

一開始想說是不是在 20.04 中 COPY 會直接將資料夾覆蓋而非將資料夾的內容放進去,為了避免 sh 被蓋掉,所以先將 folder/bin 改成 folder/bin-alt 這樣,但在確認過程發現他還是會用到 /lib 底下的,所以只好也將 folder/lib 改成 folder/lib-alt,為了確認有沒有覆蓋已有資料的情況發生,我有先建立 /other 並且放一些檔案在裡面,在進行複製 folder,但結果 /other 並沒有被覆蓋。

最後在想還有甚麼不同時,檢查了一下資料夾結構,發現在 18.04 /lib 跟 /bin 是獨立資料夾;但在 20.04 中,/bin 跟 /lib 只是捷徑分別指向 /usr/bin 跟 /usr/lib。那問題所在也呼之欲出,在拷貝時,如果目的地只是捷徑,那會直接把資料夾覆蓋過去,但如果是一般的資料夾,則會把東西複製過去。

結語

原因是目的地的資料夾是捷徑而非一般資料夾,複製時會將資料夾覆蓋,導致 docker 要用 /bin/sh 相關的 /bin, /lib 都變成只有 folder 下的,因此會跳出該錯誤

standard_init_linux.go:228: exec user process caused: no such file or directory
The command '/bin/sh -c ...' returned a non-zero code: 1 

最後只要將複製的目的地從 / 改成 /usr 就解決了

FROM ubuntu:20.04
COPY folder/ /usr

後續有指令或者要進 container 都沒問題。