AWS Beanstalk: Cannot open shared object file and ldconfig
持續的 Beanstalk 部屬筆記,最近部屬的 Go web application,使用到 cgo
動態連結其他函數庫 (shared library) 的函數,在執行階段發生找不到函數庫的錯誤:
error while loading shared libraries: libexample.so: cannot open shared object file: No such file or directory
如果對於 Linux 有所了解的話,這錯誤解決方案通常是設定動態函數庫的載入路徑 LD_LIBRARY_PATH
或是 PATH
,使得程式執行階段 linker 能夠找到對應的動態函數庫,進而不會丟出這個錯誤。
不過這邊紀錄另外一種設定方式,在 /etc/ld.so.conf.d/
目的底下建立副檔名為 .conf
的設定檔 (例如 applibs.conf),檔案內容設定其動態函數庫的路徑,之後執行 ldconfig
來更新系統的動態函數庫清單。
(這樣可以運作的原因是 ldconfig
會讀取 /etc/ld.so.conf
的動態函數庫路徑設定,而該設定內容為 include ld.so.conf.d/*.conf
)
因此套用之前採用的 Source bundle 架構 (see Go WepApp 部屬筆記),額外加入或是改動以下幾個檔案,使用粗體字標示,其中 libs 資料夾放置所引用到的動態程式庫檔案 (*.so):
- .ebextensions/
- applogs.config
- ldconfig.config
- src/
- app/
- main.go
- vendor/
- libs/
- Procfile
- Buildfile
- build.sh
.ebextensions/ldconfig.config 設定檔內容,在 /etc/ld.so.conf.d/
資料夾下建立設定檔,設定動態資料庫路徑:
files:
"/etc/ld.so.conf.d/applibs.conf" :
mode: "000755"
owner: root
group: root
content: |
/var/app/libs/
修改原先的建置指令 build.sh,加入複製動態程式庫以及執行 ldconfig
指令:
export GOPATH=$APP_STAGING_DIR
# Create libs folder and copy all libraries (*.so) into it
sudo mkdir /var/app/libs/
sudo rm /var/app/libs/*.so
cp $APP_STAGING_DIR/libs/*.so /var/app/libs/
# Reload libs
sudo ldconfig
# Build golang app
go build -o app -v app
依照此配置重新更新 source bundle,再重新上傳部屬到 Beanstalk 便不會發生找不到動態韓式庫的錯誤。
Reference
AWS Beanstalk 系列文章
- Go WebApp 部署筆記
- Nginx header size 設定 (upstream sent too big header)
- Nginx 長連線設定 (keep-alive setup)
- 關於動態程式庫 (Cannot open shared object file)
- CloudWatch 日誌推送設定
沒有留言: