docker-entrypoint.sh 檔案的用處
參考出處
很多著名庫的 Dockerfile 檔案中,通常都是 ENTRYPOINT 欄位會是這樣:
ENTRYPOINT ["docker-entrypoint.sh"]
這裡我們參考分析下 MySQL 的 Dockerfile 檔案,來認識下 docker-entrypoint.sh 的用處。
MySQL 8.0 Dockerfile
例子:MySQL 容器自建資料庫
網址:https://hub.docker.com/_/mysql/ 中,章節[ Initializing a fresh instance ] 中提到,可以在MySQL容器啟動時,初始化自定義資料庫:
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
原理就是如下:
Dockerfile 中定義:
ENTRYPOINT ["docker-entrypoint.sh"]
ls /docker-entrypoint-initdb.d/ > /dev/null
for f in /docker-entrypoint-initdb.d/*; do
process_init_file "$f" "${mysql[@]}"
done
/docker-entrypoint-initdb.d/ 中檔案哪裡來呢? 可以像這樣:
FROM mysql:5.5
COPY db.sql /docker-entrypoint-initdb.d/
通過上述例子,可以清楚的看到,在啟動容器時,可以通過 shell 指令碼執行些預處理邏輯,然後通過:
exec [email protected]
把啟動容器入口正式交給使用者
再舉個例子
比如本人遇到的一個專案,所以配置都在配置檔案中,不走程式啟動引數,也不走環境變數設定的。
那麼打成 docker 映象後,就是死配置了。
那麼如何在不修改程式碼的情況下,達成可變配置呢。
#!/bin/bash
if [[ $redis_ip ]]; then
sed -i 's/redis_ip="[0-9.]*"/redis_ip="'$redis_ip'"/' config.ini
fi
if [[ $redis_port ]]; then
sed -i 's/redis_port="[0-9]*"/redis_port="' $redis_port'"/' config.ini
fi
echo "1" > /proc/sys/kernel/core_uses_pid
echo $CORE_PATH"/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
exec "[email protected]"
docker 啟動指令碼如下:
docker run -d --restart=always \
--ulimit core=-1 --privileged=true\
-e redis_ip=$REDIS_IP \
-e redis_port=$REDIS_PORT \
xxx
以上,就可以達成自定義 redis ip/port ,並在啟動容器時,設定了 core 檔案路徑與命名。