本文目录导读:

在容器启动脚本中传递参数有多种方式,我来详细介绍几种常见方法:
Dockerfile 中使用 ENTRYPOINT + CMD
数组形式(推荐)
FROM alpine:latest # 使用 exec 形式的 ENTRYPOINT ENTRYPOINT ["/bin/sh", "-c", "./start.sh"] # 默认参数 CMD ["--default-arg"]
ENTRYPOINT 脚本处理
# start.sh 内容 #!/bin/sh echo "Starting with args: $@" # 执行你的命令 exec "$@"
# Dockerfile FROM alpine:latest COPY start.sh /start.sh RUN chmod +x /start.sh ENTRYPOINT ["/start.sh"] CMD ["default-command"]
启动时传递参数
# 传递单个参数 docker run myimage --arg1 value1 # 传递多个参数 docker run myimage \ --env ENV_NAME=production \ --param1 value1 \ --param2 value2 # 覆盖 CMD 参数 docker run myimage custom-arg1 custom-arg2
使用环境变量传递
启动脚本示例(start.sh)
#!/bin/bash
# 设置默认值
APP_PORT=${APP_PORT:-8080}
DB_HOST=${DB_HOST:-localhost}
LOG_LEVEL=${LOG_LEVEL:-info}
# 使用环境变量
echo "Starting app on port $APP_PORT"
echo "Connecting to database at $DB_HOST"
echo "Log level: $LOG_LEVEL"
# 执行实际程序
exec java -jar app.jar \
--server.port=$APP_PORT \
--db.host=$DB_HOST \
--logging.level=$LOG_LEVEL
Dockerfile
FROM openjdk:11-jre-slim COPY start.sh /app/start.sh RUN chmod +x /app/start.sh # 设置默认环境变量 ENV APP_PORT=8080 ENV LOG_LEVEL=info ENTRYPOINT ["/app/start.sh"]
运行命令
# 覆盖环境变量 docker run -e APP_PORT=3000 -e DB_HOST=myhost myimage # 使用 env-file docker run --env-file ./config.env myimage
结合命令行参数和环境变量
#!/bin/bash
# 处理命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
--port)
APP_PORT="$2"
shift 2
;;
--env)
ENVIRONMENT="$2"
shift 2
;;
--debug)
DEBUG=true
shift
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# 设置默认值
APP_PORT=${APP_PORT:-8080}
ENVIRONMENT=${ENVIRONMENT:-development}
# 执行应用程序
exec python app.py \
--port "$APP_PORT" \
--env "$ENVIRONMENT" \
${DEBUG:+--debug}
使用配置文件挂载
#!/bin/bash # 检查配置文件 CONFIG_FILE="/etc/app/config.yaml" ENV_FILE="/etc/app/env.sh" # 如果存在配置文件,加载环境变量 if [ -f "$ENV_FILE" ]; then source "$ENV_FILE" fi # 如果存在配置文件,使用它 if [ -f "$CONFIG_FILE" ]; then echo "Using config file: $CONFIG_FILE" fi # 执行应用程序 exec /usr/bin/app --config "$CONFIG_FILE"
完整的实战示例
start.sh
#!/bin/bash
set -e
# 函数:打印帮助信息
usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " --port PORT Application port (default: 8080)"
echo " --db-host HOST Database host (default: localhost)"
echo " --db-port PORT Database port (default: 5432)"
echo " --mode MODE Run mode (dev/staging/prod)"
echo " -h, --help Show this help message"
}
# 默认参数
APP_PORT=${APP_PORT:-8080}
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
RUN_MODE=${RUN_MODE:-dev}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
--port)
APP_PORT="$2"
shift 2
;;
--db-host)
DB_HOST="$2"
shift 2
;;
--db-port)
DB_PORT="$2"
shift 2
;;
--mode)
RUN_MODE="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
# 参数验证
if [[ ! "$APP_PORT" =~ ^[0-9]+$ ]] || [ "$APP_PORT" -lt 1024 ] || [ "$APP_PORT" -gt 65535 ]; then
echo "Error: Port must be between 1024 and 65535"
exit 1
fi
# 日志
echo "========================================"
echo "Starting application with configuration:"
echo " Port: $APP_PORT"
echo " DB Host: $DB_HOST:$DB_PORT"
echo " Mode: $RUN_MODE"
echo "========================================"
# 执行应用程序(使用 exec 替换当前进程)
exec python -m app \
--port "$APP_PORT" \
--db-host "$DB_HOST" \
--db-port "$DB_PORT" \
--mode "$RUN_MODE"
Dockerfile
FROM python:3.9-slim WORKDIR /app # 复制应用代码 COPY app/ /app/ # 复制启动脚本 COPY start.sh /start.sh RUN chmod +x /start.sh # 设置默认环境变量 ENV APP_PORT=8080 ENV RUN_MODE=dev # 使用 exec 格式的 ENTRYPOINT ENTRYPOINT ["/start.sh"] # 默认参数(可以被 docker run 覆盖) CMD ["--mode", "dev"]
运行示例
# 使用默认参数 docker run myapp # 覆盖所有参数 docker run myapp --port 3000 --db-host mydb.example.com --mode prod # 使用环境变量覆盖 docker run -e APP_PORT=3000 -e DB_HOST=local.db myapp # 混合使用 docker run -e RUN_MODE=prod myapp --port 9090 --db-host custom.db
最佳实践建议
- 使用 exec 替换:在脚本末尾使用
exec确保信号正确传递 - set -e:启用错误检测,脚本遇到错误立即退出
- 参数验证:验证传入的参数是否合法
- 帮助信息:提供 -h 或 --help 选项
- 默认值:为所有参数提供合理的默认值
- 环境变量优先:支持通过环境变量和命令行参数两种方式配置
这样设计的容器启动脚本既灵活又健壮,可以满足不同的部署需求。