feat: 更新相关脚本及Dockerfile文件
This commit is contained in:
+30
-15
@@ -1,4 +1,4 @@
|
||||
# Ver: 1.10 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.11 by Endial Fang (endial@126.com)
|
||||
#
|
||||
|
||||
# 系统默认变量 ====================================================================
|
||||
@@ -30,9 +30,6 @@ ARG APP_VER
|
||||
ARG APT_SOURCE
|
||||
ARG LOCAL_URL
|
||||
|
||||
# 选择软件包源,加速后续软件包安装
|
||||
RUN select_source ${APT_SOURCE};
|
||||
|
||||
# 下载并解压软件包
|
||||
RUN set -eux; \
|
||||
appName="${APP_NAME}-${APP_VER}.tar.gz"; \
|
||||
@@ -45,20 +42,38 @@ RUN set -eux; \
|
||||
|
||||
# 源码编译: 编译后将配置文件模板拷贝至 /usr/local/${APP_NAME}/share/${APP_NAME} 中
|
||||
RUN set -eux; \
|
||||
APP_ARCH=`arch` \
|
||||
APP_SRC="/tmp/${APP_NAME}-${APP_VER}"; \
|
||||
cd ${APP_SRC}; \
|
||||
# 禁用安全保护模式,在 Docker 中运行时不需要
|
||||
\
|
||||
# 禁用安全保护模式,在 Docker 中运行时不需要
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' ./src/config.c; \
|
||||
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' ./src/config.c; \
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' ./src/config.c; \
|
||||
make MALLOC=libc BUILD_TLS=yes \
|
||||
-j "$(nproc)" all; \
|
||||
\
|
||||
# 根据操作系统设置内存页大小
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
extraJemallocConfigureFlags="--build=$gnuArch"; \
|
||||
dpkgArch="$(dpkg --print-architecture)"; \
|
||||
case "${dpkgArch##*-}" in \
|
||||
amd64 | i386 | x32) \
|
||||
extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=12" ;; \
|
||||
*) \
|
||||
extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=16" ;; \
|
||||
esac; \
|
||||
extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-hugepage=21"; \
|
||||
grep -F 'cd jemalloc && ./configure ' ./deps/Makefile; \
|
||||
sed -ri 's!cd jemalloc && ./configure !&'"$extraJemallocConfigureFlags"' !' ./deps/Makefile; \
|
||||
grep -F "cd jemalloc && ./configure $extraJemallocConfigureFlags " ./deps/Makefile; \
|
||||
\
|
||||
export BUILD_TLS=yes; \
|
||||
make -j "$(nproc)" all; \
|
||||
make PREFIX=/usr/local/${APP_NAME} install; \
|
||||
# 将配置文件模板拷贝至应用安装目录的 etc/${APP_NAME} 目录下
|
||||
\
|
||||
# 将配置文件模板拷贝至应用安装目录的 etc/${APP_NAME} 目录下
|
||||
mkdir -p /usr/local/${APP_NAME}/etc/${APP_NAME}; \
|
||||
cp /tmp/${APP_NAME}-${APP_VER}/*.conf /usr/local/${APP_NAME}/etc/${APP_NAME}/; \
|
||||
# 删除重复的应用程序,并生成对应的连接
|
||||
\
|
||||
# 删除重复的应用程序,并生成对应的连接
|
||||
serverMd5="$(md5sum /usr/local/redis/bin/redis-server | cut -d' ' -f1)"; export serverMd5; \
|
||||
find /usr/local/redis/bin/redis* -maxdepth 0 \
|
||||
-type f -not -name redis-server \
|
||||
@@ -102,11 +117,6 @@ LABEL \
|
||||
"Github"="https://github.com/colovu/docker-${APP_NAME}" \
|
||||
"Vendor"="Endial Fang (endial@126.com)"
|
||||
|
||||
# 配置容器的数据卷、工作目录及服务端口(必须保证端口在1024之上)
|
||||
VOLUME ["/srv/${APP_NAME}"]
|
||||
WORKDIR /srv/${APP_NAME}
|
||||
EXPOSE 6379
|
||||
|
||||
# 拷贝多阶段构建结果输出及客制化脚本
|
||||
COPY --from=builder /usr/local/${APP_NAME} /usr/local/${APP_NAME}
|
||||
COPY customer /
|
||||
@@ -137,6 +147,11 @@ RUN set -eux; \
|
||||
redis-cli --version; \
|
||||
${APP_EXEC} --version;
|
||||
|
||||
# 配置容器的数据卷、工作目录及服务端口(必须保证端口在1024之上)
|
||||
VOLUME ["/srv/${APP_NAME}/conf", "/srv/${APP_NAME}/data", "/srv/${APP_NAME}/cert", "/srv/${APP_NAME}/log"]
|
||||
WORKDIR /srv/${APP_NAME}/data
|
||||
EXPOSE 6379
|
||||
|
||||
#HEALTHCHECK NONE
|
||||
#HEALTHCHECK --interval=30s --timeout=30s --retries=3 CMD curl -fs http://localhost:8080/ || exit 1
|
||||
HEALTHCHECK --interval=10s --timeout=10s --retries=3 CMD netstat -ltun | grep 6379
|
||||
|
||||
+215
-341
@@ -1,9 +1,8 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.2 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.4 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 应用通用业务处理函数
|
||||
|
||||
# 加载依赖脚本
|
||||
. /colovu/lib/libcommon.sh # 通用函数库
|
||||
|
||||
. /colovu/lib/libfile.sh
|
||||
@@ -13,17 +12,57 @@
|
||||
. /colovu/lib/libservice.sh
|
||||
. /colovu/lib/libvalidations.sh
|
||||
|
||||
# 函数列表
|
||||
# 检测应用相应的配置文件是否存在,如果不存在,则从默认配置文件目录拷贝一份
|
||||
# 默认配置文件路径:/etc/${APP_NAME}
|
||||
# 目标配置文件路径:/srv/conf/${APP_NAME}
|
||||
# 参数:
|
||||
# $1 - 目标路径
|
||||
# $2 - 源路径
|
||||
# $* - 基础路径下的文件及目录列表,以" "分割
|
||||
# 例子:
|
||||
# ensure_config_file_exist /etc/${APP_NAME} conf.d server.conf
|
||||
app_ensure_config_file_exist() {
|
||||
local -r dist_path="${1:?dist paths is missing}"
|
||||
local -r base_path="${2:?source paths is missing}"
|
||||
local f=""
|
||||
|
||||
# 使用环境变量中以 "APP_CFG_" 开头的的全局变量更新配置文件中对应项(全小写,以"."分隔)
|
||||
# 举例:
|
||||
# APP_CFG_LOG_DIRS 对应配置文件中的配置项:log.dirs
|
||||
redis_configure_from_env_variables() {
|
||||
# Map environment variables to config properties
|
||||
for var in "${!APP_CFG_@}"; do
|
||||
key="$(echo "$var" | sed -e 's/^APP_CFG_//g' -e 's/_/\./g' | tr '[:upper:]' '[:lower:]')"
|
||||
shift 2
|
||||
LOG_D "List to check in ${base_path}: $@"
|
||||
while [ "$#" -gt 0 ]; do
|
||||
f="${1}"
|
||||
LOG_D " Process \"${f}\""
|
||||
if [ -d "${base_path}/${f}" ]; then
|
||||
[[ ! -d "${dist_path}/${f}" ]] && LOG_D " Create directory: ${dist_path}/${f}" && mkdir -p "${dist_path}/${f}"
|
||||
[[ ! -z $(ls -A "${base_path}/${f}") ]] && app_ensure_config_file_exist "${dist_path}/${f}" "${base_path}/${f}" $(ls -A "${base_path}/${f}")
|
||||
else
|
||||
[[ ! -e "${dist_path}/${f}" ]] && LOG_D " Copy: ${base_path}/${f} to ${dist_path}" && cp "${base_path}/${f}" "${dist_path}"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# 检测以 "<PREFIX>" 开头的环境变量,并更新指定配置文件中对应配置项的值
|
||||
# 如果需要全部转换为小写,可使用命令: tr '[:upper:]' '[:lower:]'
|
||||
# 环境变量与配置项替换规则 : 环境变量中下划线 ==> 配置参数中特殊字符
|
||||
# - "_" ==> "-"(中划线)
|
||||
# - "__" ==> "_"(下划线)
|
||||
# - "___" ==> "."(半角点)
|
||||
#
|
||||
# 变量:
|
||||
# $1 - 配置文件
|
||||
# $2 - <PREFIX>前缀(不含结束的"_")
|
||||
app_configure_from_environment() {
|
||||
local confFile="${1:?missing file}"
|
||||
local envPrefix="${2:-APP_CFG}"
|
||||
|
||||
LOG_D "Configuration File: ${confFile}"
|
||||
|
||||
# 更新普通key-value配置文件,转换为小写后写入文件
|
||||
for var in $(eval echo \${!${envPrefix}_@}); do
|
||||
key="$(echo "$var" | sed -e 's/^'${envPrefix}'_//g' -e 's/___/./g' -e 's/__/--/g' -e 's/_/-/g' -e 's/--/_/g' | tr '[:upper:]' '[:lower:]')"
|
||||
value="${!var}"
|
||||
redis_conf_set "$key" "$value"
|
||||
LOG_D " ${key} ${value}"
|
||||
app_common_conf_set "$confFile" "$key" "$value"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -32,7 +71,7 @@ redis_configure_from_env_variables() {
|
||||
# $1 - 文件
|
||||
# $2 - 变量
|
||||
# $3 - 值(列表)
|
||||
redis_common_conf_set() {
|
||||
app_common_conf_set() {
|
||||
local file="${1:?missing file}"
|
||||
local key="${2:?missing key}"
|
||||
shift
|
||||
@@ -44,7 +83,7 @@ redis_common_conf_set() {
|
||||
return 1
|
||||
elif [[ "${#values[@]}" -ne 1 ]]; then
|
||||
for i in "${!values[@]}"; do
|
||||
redis_common_conf_set "$file" "${key[$i]}" "${values[$i]}"
|
||||
app_common_conf_set "$file" "${key[$i]}" "${values[$i]}"
|
||||
done
|
||||
else
|
||||
value="${values[0]}"
|
||||
@@ -53,10 +92,30 @@ redis_common_conf_set() {
|
||||
value="${value//&/\\&}"
|
||||
value="${value//\?/\\?}"
|
||||
[[ "$value" = "" ]] && value="\"$value\""
|
||||
# Check if the value was set before
|
||||
if grep -q "^[# ]*${key} .*" "$file"; then
|
||||
# Update the existing key
|
||||
replace_in_file "$file" "^[# ]*${key} .*" "${key} ${value}" false
|
||||
# 检测配置文件中是否有相应的配置项(含以"#"起始的)
|
||||
if grep -q "^[#]*${key} .*" "$file"; then
|
||||
# 更新当前被注释掉的配置项(以“#”开始)
|
||||
case ${key} in
|
||||
include)
|
||||
if grep -q "^${key} ${value}.*" "$file"; then
|
||||
LOG_W "Duplicated include: ${value}"
|
||||
else
|
||||
LOG_D "Add new include: ${value}"
|
||||
replace_in_file "$file" "^#${key} .*" "#include /path/to/local.conf\n${key} ${value}" false
|
||||
fi
|
||||
;;
|
||||
loadmodule)
|
||||
if grep -q "^${key} ${value}.*" "$file"; then
|
||||
LOG_W "Duplicated loadmodule: ${value}"
|
||||
else
|
||||
LOG_D "Add new loadmodule: ${value}"
|
||||
replace_in_file "$file" "^#${key} .*" "#loadmodule /path/to/my_module.so\n${key} ${value}" false
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
replace_in_file "$file" "^[#]*${key} .*" "${key} ${value}" false
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# 增加一个新的配置项;如果在其他位置有类似操作,需要注意换行
|
||||
printf "\n%s %s" "$key" "$value" >>"$file"
|
||||
@@ -64,151 +123,21 @@ redis_common_conf_set() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 获取配置文件中指定关键字对应的值
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
redis_conf_get() {
|
||||
local key="${1:?missing key}"
|
||||
# 使用环境变量中配置,更新配置文件
|
||||
app_update_conf() {
|
||||
LOG_I "Update configure files..."
|
||||
app_configure_from_environment "${REDIS_CONF_FILE}" "REDIS_CFG"
|
||||
|
||||
grep -E "^\s*$key " "${REDIS_CONF_FILE}" | awk '{print $2}'
|
||||
}
|
||||
|
||||
# 更新 redis.conf 配置文件中指定变量值,设置关键字及对应值
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
# $2 - 值(列表)
|
||||
redis_conf_set() {
|
||||
redis_common_conf_set "${REDIS_CONF_FILE}" "$@"
|
||||
}
|
||||
|
||||
# 更新 sentinel.conf 配置文件中指定变量值,设置关键字及对应值
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
# $2 - 值(列表)
|
||||
redis_sentinel_conf_set() {
|
||||
redis_common_conf_set "${REDIS_SENTINEL_FILE}" "$@"
|
||||
}
|
||||
|
||||
# 更新 redis.conf 配置文件中指定变量值,取消关键字设置信息
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
redis_conf_unset() {
|
||||
local key="${1:?missing key}"
|
||||
remove_in_file "${REDIS_CONF_FILE}" "^\s*$key .*" false
|
||||
}
|
||||
|
||||
# 获取 Redis 版本信息
|
||||
redis_version() {
|
||||
redis-cli --version | grep -E -o "[0-9]+.[0-9]+.[0-9]+"
|
||||
}
|
||||
|
||||
# 获取 Redis 主版本号
|
||||
redis_major_version() {
|
||||
redis_version | grep -E -o "^[0-9]+"
|
||||
}
|
||||
|
||||
# 禁用 Redis 不安全的命令
|
||||
# 参数:
|
||||
# $1 - 待禁用的命令列表
|
||||
redis_disable_unsafe_commands() {
|
||||
# The current syntax gets a comma separated list of commands, we split them
|
||||
# before passing to redis_disable_unsafe_commands
|
||||
read -r -a disabledCommands <<< "$(tr ',' ' ' <<< "$REDIS_DISABLE_COMMANDS")"
|
||||
LOG_D "Disabling commands: ${disabledCommands[*]}"
|
||||
echo "" >> "${REDIS_CONF_FILE}"
|
||||
for cmd in "${disabledCommands[@]}"; do
|
||||
if grep -E -q "^\s*rename-command\s+$cmd\s+\"\"\s*$" "${REDIS_CONF_FILE}"; then
|
||||
LOG_D "$cmd was already disabled"
|
||||
continue
|
||||
fi
|
||||
echo "rename-command $cmd \"\"" >> "${REDIS_CONF_FILE}"
|
||||
done
|
||||
}
|
||||
|
||||
# 生成默认配置文件
|
||||
redis_generate_conf() {
|
||||
redis_conf_set port "$REDIS_PORT"
|
||||
redis_conf_set dir "${APP_DATA_DIR}"
|
||||
redis_conf_set logfile "${APP_LOG_DIR}/redis.log" # Log to stdout
|
||||
redis_conf_set pidfile "${REDIS_PID_FILE}"
|
||||
redis_conf_set daemonize no
|
||||
redis_conf_set bind 127.0.0.1 # disallow remote connections when init
|
||||
# Enable AOF https://redis.io/topics/persistence#append-only-file
|
||||
# Leave default fsync (every second)
|
||||
redis_conf_set appendonly "${REDIS_AOF_ENABLED}"
|
||||
# Disable RDB persistence, AOF persistence already enabled.
|
||||
# Ref: https://redis.io/topics/persistence#interactions-between-aof-and-rdb-persistence
|
||||
redis_conf_set save ""
|
||||
# TLS configuration
|
||||
if is_boolean_yes "$REDIS_TLS_ENABLED"; then
|
||||
if [[ "$REDIS_PORT" == "6379" ]] && [[ "$REDIS_TLS_PORT" == "6379" ]]; then
|
||||
# If both ports are set to default values, enable TLS traffic only
|
||||
redis_conf_set port 0
|
||||
redis_conf_set tls-port "$REDIS_TLS_PORT"
|
||||
else
|
||||
# Different ports were specified
|
||||
redis_conf_set port "$REDIS_PORT"
|
||||
redis_conf_set tls-port "$REDIS_TLS_PORT"
|
||||
fi
|
||||
redis_conf_set tls-cert-file "$REDIS_TLS_CERT_FILE"
|
||||
redis_conf_set tls-key-file "$REDIS_TLS_KEY_FILE"
|
||||
redis_conf_set tls-ca-cert-file "$REDIS_TLS_CA_FILE"
|
||||
[[ -n "$REDIS_TLS_DH_PARAMS_FILE" ]] && redis_conf_set tls-dh-params-file "$REDIS_TLS_DH_PARAMS_FILE"
|
||||
redis_conf_set tls-auth-clients "$REDIS_TLS_AUTH_CLIENTS"
|
||||
fi
|
||||
|
||||
if [[ -n "$REDIS_PASSWORD" ]]; then
|
||||
redis_conf_set requirepass "$REDIS_PASSWORD"
|
||||
else
|
||||
redis_conf_unset requirepass
|
||||
fi
|
||||
if [[ -n "$REDIS_DISABLE_COMMANDS" ]]; then
|
||||
redis_disable_unsafe_commands
|
||||
fi
|
||||
}
|
||||
|
||||
# 配置 Redis 复制模式参数
|
||||
# 参数:
|
||||
# $1 - 复制模式
|
||||
redis_configure_replication() {
|
||||
LOG_I "Configuring replication mode..."
|
||||
|
||||
redis_conf_set replica-announce-ip "$(get_machine_ip)"
|
||||
redis_conf_set replica-announce-port "$REDIS_MASTER_PORT_NUMBER"
|
||||
if [[ "$REDIS_REPLICATION_MODE" = "master" ]]; then
|
||||
if [[ -n "$REDIS_PASSWORD" ]]; then
|
||||
redis_conf_set masterauth "$REDIS_PASSWORD"
|
||||
fi
|
||||
elif [[ "$REDIS_REPLICATION_MODE" =~ ^(slave|replica)$ ]]; then
|
||||
if [[ -n "$REDIS_SENTINEL_HOST" ]]; then
|
||||
local sentinel_info_command
|
||||
if is_boolean_yes "$REDIS_TLS_ENABLED"; then
|
||||
sentinel_info_command="redis-cli -h ${REDIS_SENTINEL_HOST} -p ${REDIS_SENTINEL_PORT_NUMBER} --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} sentinel get-master-addr-by-name ${REDIS_SENTINEL_MASTER_NAME}"
|
||||
else
|
||||
sentinel_info_command="redis-cli -h ${REDIS_SENTINEL_HOST} -p ${REDIS_SENTINEL_PORT_NUMBER} sentinel get-master-addr-by-name ${REDIS_SENTINEL_MASTER_NAME}"
|
||||
fi
|
||||
REDIS_SENTINEL_INFO=($($sentinel_info_command))
|
||||
REDIS_MASTER_HOST=${REDIS_SENTINEL_INFO[0]}
|
||||
REDIS_MASTER_PORT_NUMBER=${REDIS_SENTINEL_INFO[1]}
|
||||
fi
|
||||
LOG_I "Waitting for Redis Master ready..."
|
||||
redis_wait_service "${REDIS_MASTER_HOST}:${REDIS_MASTER_PORT_NUMBER}"
|
||||
[[ -n "$REDIS_MASTER_PASSWORD" ]] && redis_conf_set masterauth "$REDIS_MASTER_PASSWORD"
|
||||
# Starting with Redis 5, use 'replicaof' instead of 'slaveof'. Maintaining both for backward compatibility
|
||||
local parameter="replicaof"
|
||||
[[ $(redis_major_version) -lt 5 ]] && parameter="slaveof"
|
||||
redis_conf_set "$parameter" "$REDIS_MASTER_HOST $REDIS_MASTER_PORT_NUMBER"
|
||||
# Configure replicas to use TLS for outgoing connections to the master
|
||||
if is_boolean_yes "$REDIS_TLS_ENABLED"; then
|
||||
redis_conf_set tls-replication yes
|
||||
fi
|
||||
if [[ -n "$DISABLE_COMMANDS" ]]; then
|
||||
app_disable_unsafe_commands
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测用户参数信息是否满足条件; 针对部分权限过于开放情况,打印提示信息
|
||||
redis_verify_minimum_env() {
|
||||
app_verify_minimum_env() {
|
||||
local error_code=0
|
||||
LOG_D "Validating settings in REDIS_* env vars..."
|
||||
|
||||
LOG_D "Validating settings in ENV vars..."
|
||||
|
||||
print_validation_error() {
|
||||
LOG_E "$1"
|
||||
@@ -218,75 +147,61 @@ redis_verify_minimum_env() {
|
||||
# Redis authentication validations
|
||||
if is_boolean_yes "$ALLOW_ANONYMOUS"; then
|
||||
LOG_W "You set the environment variable ALLOW_ANONYMOUS=${ALLOW_ANONYMOUS}. For safety reasons, do not use this flag in a production environment."
|
||||
elif [[ -z "$REDIS_PASSWORD" ]]; then
|
||||
print_validation_error "The REDIS_PASSWORD environment variable is empty or not set. Set the environment variable ALLOW_ANONYMOUS=yes to allow the container to be started with blank passwords. This is recommended only for development."
|
||||
elif [[ -z "$REDIS_CFG_REQUIREPASS" ]]; then
|
||||
print_validation_error "The REDIS_CFG_REQUIREPASS environment variable is empty or not set. Set the environment variable ALLOW_ANONYMOUS=yes to allow the container to be started with blank passwords. This is recommended only for development."
|
||||
fi
|
||||
|
||||
if [[ -n "$REDIS_REPLICATION_MODE" ]]; then
|
||||
if [[ "$REDIS_REPLICATION_MODE" =~ ^(slave|replica)$ ]]; then
|
||||
if [[ -n "$REDIS_MASTER_PORT_NUMBER" ]]; then
|
||||
if ! err=$(validate_port "$REDIS_MASTER_PORT_NUMBER"); then
|
||||
print_validation_error "An invalid port was specified in the environment variable REDIS_MASTER_PORT_NUMBER: $err"
|
||||
fi
|
||||
fi
|
||||
if ! is_boolean_yes "$ALLOW_ANONYMOUS" && [[ -z "$REDIS_MASTER_PASSWORD" ]]; then
|
||||
print_validation_error "The REDIS_MASTER_PASSWORD environment variable is empty or not set. Set the environment variable ALLOW_ANONYMOUS=yes to allow the container to be started with blank passwords. This is recommended only for development."
|
||||
fi
|
||||
elif [[ "$REDIS_REPLICATION_MODE" != "master" ]]; then
|
||||
print_validation_error "Invalid replication mode. Available options are 'master/replica'"
|
||||
fi
|
||||
fi
|
||||
|
||||
if is_boolean_yes "$REDIS_TLS_ENABLED"; then
|
||||
if [[ "$REDIS_PORT" == "$REDIS_TLS_PORT" ]] && [[ "$REDIS_PORT" != "6379" ]]; then
|
||||
# If both ports are assigned the same numbers and they are different to the default settings
|
||||
print_validation_error "Enviroment variables REDIS_PORT and REDIS_TLS_PORT point to the same port number (${REDIS_PORT}). Change one of them or disable non-TLS traffic by setting REDIS_PORT=0"
|
||||
fi
|
||||
if [[ -z "$REDIS_TLS_CERT_FILE" ]]; then
|
||||
if [[ -n "${REDIS_CFG_TLS_PORT:-}" ]]; then
|
||||
if [[ -z "${REDIS_CFG_TLS_CERT_FILE:-}" ]]; then
|
||||
print_validation_error "You must provide a X.509 certificate in order to use TLS"
|
||||
elif [[ ! -f "$REDIS_TLS_CERT_FILE" ]]; then
|
||||
print_validation_error "The X.509 certificate file in the specified path ${REDIS_TLS_CERT_FILE} does not exist"
|
||||
elif [[ ! -f "$REDIS_CFG_TLS_CERT_FILE" ]]; then
|
||||
print_validation_error "The X.509 certificate file in the specified path ${REDIS_CFG_TLS_CERT_FILE} does not exist"
|
||||
fi
|
||||
if [[ -z "$REDIS_TLS_KEY_FILE" ]]; then
|
||||
if [[ -z "${REDIS_CFG_TLS_KEY_FILE:-}" ]]; then
|
||||
print_validation_error "You must provide a private key in order to use TLS"
|
||||
elif [[ ! -f "$REDIS_TLS_KEY_FILE" ]]; then
|
||||
print_validation_error "The private key file in the specified path ${REDIS_TLS_KEY_FILE} does not exist"
|
||||
elif [[ ! -f "$REDIS_CFG_TLS_KEY_FILE" ]]; then
|
||||
print_validation_error "The private key file in the specified path ${REDIS_CFG_TLS_KEY_FILE} does not exist"
|
||||
fi
|
||||
if [[ -z "$REDIS_TLS_CA_FILE" ]]; then
|
||||
if [[ -z "${REDIS_CFG_TLS_CA_CERT_FILE:-}" ]]; then
|
||||
print_validation_error "You must provide a CA X.509 certificate in order to use TLS"
|
||||
elif [[ ! -f "$REDIS_TLS_CA_FILE" ]]; then
|
||||
print_validation_error "The CA X.509 certificate file in the specified path ${REDIS_TLS_CA_FILE} does not exist"
|
||||
elif [[ ! -f "$REDIS_CFG_TLS_CA_CERT_FILE" ]]; then
|
||||
print_validation_error "The CA X.509 certificate file in the specified path ${REDIS_CFG_TLS_CA_CERT_FILE} does not exist"
|
||||
fi
|
||||
if [[ -n "$REDIS_TLS_DH_PARAMS_FILE" ]] && [[ ! -f "$REDIS_TLS_DH_PARAMS_FILE" ]]; then
|
||||
print_validation_error "The DH param file in the specified path ${REDIS_TLS_DH_PARAMS_FILE} does not exist"
|
||||
if [[ -n "${REDIS_CFG_TLS_DH_PARAMS_FILE:-}" ]] && [[ ! -f "$REDIS_CFG_TLS_DH_PARAMS_FILE" ]]; then
|
||||
print_validation_error "The DH param file in the specified path ${REDIS_CFG_TLS_DH_PARAMS_FILE} does not exist"
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ "$error_code" -eq 0 ]] || exit "$error_code"
|
||||
}
|
||||
|
||||
# 更改默认监听地址为 "*" 或 "0.0.0.0",以对容器外提供服务;默认配置文件应当为仅监听 localhost(127.0.0.1)
|
||||
redis_enable_remote_connections() {
|
||||
LOG_D "Modify default config to enable all IP access"
|
||||
# 更改默认监听地址为 "*" 或 "0.0.0.0",以对容器外提供服务
|
||||
app_enable_remote_connections() {
|
||||
LOG_I "Modify default config to ENABLE external IP access"
|
||||
|
||||
redis_conf_set daemonize no
|
||||
redis_conf_set bind 0.0.0.0 # Allow remote connections
|
||||
app_conf_set bind "* -::*"
|
||||
}
|
||||
|
||||
# 更改默认监听地址为 "localhost" 或 "127.0.0.1",以禁止对容器外提供服务
|
||||
app_disable_remote_connections() {
|
||||
LOG_I "Modify default config to DISABLE external IP access"
|
||||
|
||||
app_conf_set bind "127.0.0.1 -::1"
|
||||
}
|
||||
|
||||
# 检测依赖的服务端口是否就绪;该脚本依赖系统工具 'netcat'
|
||||
# 参数:
|
||||
# $1 - host:port
|
||||
redis_wait_service() {
|
||||
local serviceport=${1:?Missing server info}
|
||||
local service=${serviceport%%:*}
|
||||
local port=${serviceport#*:}
|
||||
app_wait_service() {
|
||||
local serviceInfo=${1:?Missing server info}
|
||||
local service=${serviceInfo%%:*}
|
||||
local port=${serviceInfo#*:}
|
||||
local retry_seconds=5
|
||||
local max_try=100
|
||||
local max_try=6
|
||||
let i=1
|
||||
|
||||
if [[ -z "$(which nc)" ]]; then
|
||||
LOG_E "Nedd nc installed before, command: \"apt-get install netcat\"."
|
||||
exit 1
|
||||
install_pkg ncat
|
||||
fi
|
||||
|
||||
LOG_I "[0/${max_try}] check for ${service}:${port}..."
|
||||
@@ -296,13 +211,12 @@ redis_wait_service() {
|
||||
result=$?
|
||||
|
||||
until [ $result -eq 0 ]; do
|
||||
LOG_D " [$i/${max_try}] not available yet"
|
||||
if (( $i == ${max_try} )); then
|
||||
LOG_E "${service}:${port} is still not available; giving up after ${max_try} tries."
|
||||
exit 1
|
||||
fi
|
||||
LOG_D " [$i/${max_try}] not available yet, try in ${retry_seconds}'s latter ..."
|
||||
|
||||
LOG_I "[$i/${max_try}] try in ${retry_seconds}s once again ..."
|
||||
let "i++"
|
||||
sleep ${retry_seconds}
|
||||
|
||||
@@ -315,97 +229,89 @@ redis_wait_service() {
|
||||
}
|
||||
|
||||
# 以后台方式启动应用服务,并等待启动就绪
|
||||
redis_start_server_bg() {
|
||||
redis_is_server_running && return
|
||||
app_start_server_bg() {
|
||||
app_is_server_running && return
|
||||
|
||||
LOG_I "Starting ${APP_NAME} in background..."
|
||||
|
||||
local pass
|
||||
pass="$(cat /dev/urandom | head -n 24 | md5sum | head -c 24)"
|
||||
|
||||
export REDISCLI_AUTH="${pass}"
|
||||
|
||||
if is_boolean_yes "${ENV_DEBUG}"; then
|
||||
"redis-server" "${REDIS_CONF_FILE}" "--daemonize" "yes"
|
||||
"redis-server" "${REDIS_CONF_FILE}" "--daemonize" "yes" "--requirepass" "${pass}"
|
||||
else
|
||||
"redis-server" "${REDIS_CONF_FILE}" "--daemonize" "yes" >/dev/null 2>&1
|
||||
"redis-server" "${REDIS_CONF_FILE}" "--daemonize" "yes" "--requirepass" "${pass}" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
local counter=3
|
||||
while ! redis_is_server_running ; do
|
||||
LOG_D "Checking ${APP_NAME} ready status..."
|
||||
local counter=10
|
||||
while ! app_is_server_running ; do
|
||||
LOG_D "Waiting for ${APP_NAME} to ready ... $counter"
|
||||
if [[ "$counter" -ne 0 ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 1;
|
||||
counter=$((counter - 1))
|
||||
done
|
||||
|
||||
# 通过命令或特定端口检测应用是否就绪
|
||||
LOG_I "Checking ${APP_NAME} ready status..."
|
||||
#wait-for-port --timeout 60 "$REDIS_PORT"
|
||||
|
||||
LOG_D "${APP_NAME} is ready for service..."
|
||||
}
|
||||
|
||||
# 停止应用服务
|
||||
redis_stop_server() {
|
||||
redis_is_server_running || return
|
||||
app_stop_server() {
|
||||
if app_is_server_running ; then
|
||||
LOG_I "Stopping ${APP_NAME}..."
|
||||
|
||||
local pass
|
||||
local port
|
||||
local args
|
||||
LOG_I "Stopping ${APP_NAME}..."
|
||||
# 已通过环境变量设置了 REDISCLI_AUTH
|
||||
if is_boolean_yes "${ENV_DEBUG}"; then
|
||||
"redis-cli" shutdown
|
||||
else
|
||||
"redis-cli" shutdown >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
pass="$(redis_conf_get "requirepass")"
|
||||
is_boolean_yes "$REDIS_TLS_ENABLED" && port="$(redis_conf_get "tls-port")" || port="$(redis_conf_get "port")"
|
||||
|
||||
[[ -n "$pass" ]] && args+=("-a" "\"$pass\"")
|
||||
[[ "$port" != "0" ]] && args+=("-p" "$port")
|
||||
#args+=("--daemonize" "yes")
|
||||
|
||||
if is_boolean_yes "${ENV_DEBUG}"; then
|
||||
"redis-cli" "${args[@]}" shutdown
|
||||
else
|
||||
"redis-cli" "${args[@]}" shutdown >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# 检测停止是否完成
|
||||
local counter=5
|
||||
while [[ "$counter" -ne 0 ]] && is_app_server_running; do
|
||||
LOG_D "Waiting for ${APP_NAME} to stop..."
|
||||
sleep 1
|
||||
counter=$((counter - 1))
|
||||
done
|
||||
# 检测停止是否完成
|
||||
LOG_D "Checking ${APP_NAME} running status..."
|
||||
local counter=10
|
||||
while [[ "$counter" -ne 0 ]] && app_is_server_running; do
|
||||
LOG_D "Waiting for ${APP_NAME} to stop ... $counter"
|
||||
sleep 1
|
||||
counter=$((counter - 1))
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测应用服务是否在后台运行中
|
||||
redis_is_server_running() {
|
||||
app_is_server_running() {
|
||||
LOG_D "Check if ${APP_NAME} is running..."
|
||||
local pid
|
||||
pid="$(get_pid_from_file "${REDIS_PID_FILE}")"
|
||||
pid="$(get_pid_from_file '${REDIS_PID_FILE}')"
|
||||
LOG_D "${APP_NAME} PID: ${pid}"
|
||||
|
||||
if [[ -z "${pid}" ]]; then
|
||||
false
|
||||
else
|
||||
if [[ -n "${pid}" ]]; then
|
||||
is_service_running "${pid}"
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
redis_is_server_not_running() {
|
||||
! redis_is_server_running
|
||||
app_is_server_not_running() {
|
||||
if [[ app_is_server_running == false ]]; then
|
||||
true
|
||||
else
|
||||
flse
|
||||
fi
|
||||
}
|
||||
|
||||
# 清理初始化应用时生成的临时文件
|
||||
redis_clean_tmp_file() {
|
||||
app_clean_tmp_file() {
|
||||
LOG_D "Clean ${APP_NAME} tmp files for init..."
|
||||
|
||||
}
|
||||
|
||||
# 在重新启动容器时,删除标志文件及必须删除的临时文件 (容器重新启动)
|
||||
redis_clean_from_restart() {
|
||||
LOG_D "Clean ${APP_NAME} tmp files for restart..."
|
||||
local -r -a files=(
|
||||
"${REDIS_PID_FILE}"
|
||||
)
|
||||
|
||||
for file in ${files[@]}; do
|
||||
if [[ -f "$file" ]]; then
|
||||
LOG_I "Cleaning stale $file file"
|
||||
LOG_D " Remove $file"
|
||||
rm "$file"
|
||||
fi
|
||||
done
|
||||
@@ -413,86 +319,31 @@ redis_clean_from_restart() {
|
||||
|
||||
# 应用默认初始化操作
|
||||
# 执行完毕后,生成文件 ${APP_CONF_DIR}/.app_init_flag 及 ${APP_DATA_DIR}/.data_init_flag 文件
|
||||
redis_default_init() {
|
||||
redis_clean_from_restart
|
||||
LOG_D "Check init status of ${APP_NAME}..."
|
||||
app_default_init() {
|
||||
LOG_I "Process default init for ${APP_NAME}..."
|
||||
|
||||
# 检测配置文件是否存在
|
||||
if [[ ! -f "${APP_CONF_DIR}/.app_init_flag" ]]; then
|
||||
LOG_I "No injected configuration file found, creating default config files..."
|
||||
redis_generate_conf
|
||||
|
||||
# Configure Replication mode
|
||||
if [[ -n "$REDIS_REPLICATION_MODE" ]]; then
|
||||
redis_configure_replication
|
||||
fi
|
||||
|
||||
touch "${APP_CONF_DIR}/.app_init_flag"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_CONF_DIR}/.app_init_flag"
|
||||
else
|
||||
LOG_I "User injected custom configuration detected!"
|
||||
fi
|
||||
|
||||
if [[ ! -f "${APP_DATA_DIR}/.data_init_flag" ]]; then
|
||||
LOG_I "Deploying ${APP_NAME} from scratch..."
|
||||
|
||||
# 启动后台服务
|
||||
#redis_start_server_bg
|
||||
|
||||
|
||||
touch ${APP_DATA_DIR}/.data_init_flag
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> ${APP_DATA_DIR}/.data_init_flag
|
||||
else
|
||||
LOG_I "Deploying ${APP_NAME} with persisted data..."
|
||||
fi
|
||||
}
|
||||
|
||||
# 用户自定义的前置初始化操作,依次执行目录 preinitdb.d 中的初始化脚本
|
||||
# 执行完毕后,生成文件 ${APP_DATA_DIR}/.custom_preinit_flag
|
||||
redis_custom_preinit() {
|
||||
LOG_I "Check custom pre-init status of ${APP_NAME}..."
|
||||
|
||||
# 检测用户配置文件目录是否存在 preinitdb.d 文件夹,如果存在,尝试执行目录中的初始化脚本
|
||||
if [ -d "/srv/conf/${APP_NAME}/preinitdb.d" ]; then
|
||||
# 检测数据存储目录是否存在已初始化标志文件;如果不存在,检索可执行脚本文件并进行初始化操作
|
||||
if [[ -n $(find "/srv/conf/${APP_NAME}/preinitdb.d/" -type f -regex ".*\.\(sh\)") ]] && \
|
||||
[[ ! -f "${APP_DATA_DIR}/.custom_preinit_flag" ]]; then
|
||||
LOG_I "Process custom pre-init scripts from /srv/conf/${APP_NAME}/preinitdb.d..."
|
||||
|
||||
# 检索所有可执行脚本,排序后执行
|
||||
find "/srv/conf/${APP_NAME}/preinitdb.d/" -type f -regex ".*\.\(sh\)" | sort | process_init_files
|
||||
|
||||
touch "${APP_DATA_DIR}/.custom_preinit_flag"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_DATA_DIR}/.custom_preinit_flag"
|
||||
LOG_I "Custom preinit for ${APP_NAME} complete."
|
||||
else
|
||||
LOG_I "Custom preinit for ${APP_NAME} already done before, skipping initialization."
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检测依赖的服务是否就绪
|
||||
#for i in ${SERVICE_PRECONDITION[@]}; do
|
||||
# redis_wait_service "${i}"
|
||||
#done
|
||||
app_update_conf
|
||||
app_enable_remote_connections
|
||||
}
|
||||
|
||||
# 用户自定义的应用初始化操作,依次执行目录initdb.d中的初始化脚本
|
||||
# 执行完毕后,生成文件 ${APP_DATA_DIR}/.custom_init_flag
|
||||
redis_custom_init() {
|
||||
LOG_I "Check custom initdb status of ${APP_NAME}..."
|
||||
app_custom_init() {
|
||||
LOG_I "Process customer init ${APP_NAME}..."
|
||||
|
||||
# 检测用户配置文件目录是否存在 initdb.d 文件夹,如果存在,尝试执行目录中的初始化脚本
|
||||
if [ -d "/srv/conf/${APP_NAME}/initdb.d" ]; then
|
||||
if [ -d "${APP_CONF_DIR}/initdb.d" ]; then
|
||||
# 检测数据存储目录是否存在已初始化标志文件;如果不存在,检索可执行脚本文件并进行初始化操作
|
||||
if [[ -n $(find "/srv/conf/${APP_NAME}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)") ]] && \
|
||||
if [[ -n $(find "${APP_CONF_DIR}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)") ]] && \
|
||||
[[ ! -f "${APP_DATA_DIR}/.custom_init_flag" ]]; then
|
||||
LOG_I "Process custom init scripts from /srv/conf/${APP_NAME}/initdb.d..."
|
||||
LOG_I "Process custom init scripts from ${APP_CONF_DIR}/initdb.d..."
|
||||
|
||||
# 启动后台服务
|
||||
#redis_start_server_bg
|
||||
app_disable_remote_connections
|
||||
app_start_server_bg
|
||||
|
||||
# 检索所有可执行脚本,排序后执行
|
||||
find "/srv/conf/${APP_NAME}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do
|
||||
find "${APP_CONF_DIR}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do
|
||||
case "$f" in
|
||||
*.sh)
|
||||
if [[ -x "$f" ]]; then
|
||||
@@ -501,15 +352,7 @@ redis_custom_init() {
|
||||
LOG_D "Sourcing $f"; . "$f"
|
||||
fi
|
||||
;;
|
||||
*.sql)
|
||||
LOG_D "Executing $f";
|
||||
postgresql_execute "${PG_DATABASE}" "${PG_INITSCRIPTS_USERNAME}" "${PG_INITSCRIPTS_PASSWORD}" < "$f"
|
||||
;;
|
||||
*.sql.gz)
|
||||
LOG_D "Executing $f";
|
||||
gunzip -c "$f" | postgresql_execute "${PG_DATABASE}" "${PG_INITSCRIPTS_USERNAME}" "${PG_INITSCRIPTS_PASSWORD}"
|
||||
;;
|
||||
*)
|
||||
*)
|
||||
LOG_D "Ignoring $f" ;;
|
||||
esac
|
||||
done
|
||||
@@ -517,18 +360,49 @@ redis_custom_init() {
|
||||
touch "${APP_DATA_DIR}/.custom_init_flag"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_DATA_DIR}/.custom_init_flag"
|
||||
LOG_I "Custom init for ${APP_NAME} complete."
|
||||
|
||||
# 检测服务是否运行中;如果运行,则停止后台服务
|
||||
app_is_server_running && app_stop_server
|
||||
app_clean_tmp_file
|
||||
app_enable_remote_connections
|
||||
else
|
||||
LOG_I "Custom init for ${APP_NAME} already done before, skipping initialization."
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检测服务是否运行中;如果运行,则停止后台服务
|
||||
redis_is_server_running && redis_stop_server
|
||||
|
||||
# 删除第一次运行生成的临时文件
|
||||
redis_clean_tmp_file
|
||||
|
||||
# 绑定所有 IP ,启用远程访问
|
||||
redis_enable_remote_connections
|
||||
}
|
||||
|
||||
# 更新 redis.conf 配置文件中指定变量值,设置关键字及对应值
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
# $2 - 值(列表)
|
||||
app_conf_set() {
|
||||
app_common_conf_set "${REDIS_CONF_FILE}" "$@"
|
||||
}
|
||||
|
||||
# 获取配置文件中指定关键字对应的值
|
||||
# 变量:
|
||||
# $1 - 变量
|
||||
app_conf_get() {
|
||||
local key="${1:?missing key}"
|
||||
|
||||
grep -E "^$key " "${REDIS_CONF_FILE}" | awk '{print $2}'
|
||||
}
|
||||
|
||||
# 禁用 Redis 不安全的命令
|
||||
# 参数:
|
||||
# $1 - 待禁用的命令列表
|
||||
app_disable_unsafe_commands() {
|
||||
# The current syntax gets a comma(",") separated list of commands, we split them
|
||||
# before passing to redis_disable_unsafe_commands
|
||||
read -r -a disabledCommands <<< "$(tr ',' ' ' <<< "$DISABLE_COMMANDS")"
|
||||
LOG_D "Disabling commands: ${disabledCommands[*]}"
|
||||
echo "" >> "${REDIS_CONF_FILE}"
|
||||
for cmd in "${disabledCommands[@]}"; do
|
||||
if grep -E -q "^\s*rename-command\s+$cmd\s+\"\"\s*$" "${REDIS_CONF_FILE}"; then
|
||||
LOG_D "$cmd was already disabled"
|
||||
continue
|
||||
fi
|
||||
echo "rename-command $cmd \"\"" >> "${REDIS_CONF_FILE}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.3 by Endial Fang (endial@126.com)
|
||||
#!/usr/bin/dumb-init /bin/bash
|
||||
# Ver: 1.5 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 容器入口脚本
|
||||
# 容器入口脚本;当前脚本执行完毕时,使用默认用户执行镜像 CMD 定义的命令(默认为'/usr/local/bin/run.sh')
|
||||
|
||||
# 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用:
|
||||
# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错
|
||||
set -eu
|
||||
set -o pipefail
|
||||
set -euo pipefail
|
||||
|
||||
. /colovu/lib/libcommon.sh # 加载通用函数库
|
||||
. /colovu/lib/libcommon.sh # 加载通用函数库
|
||||
|
||||
. /usr/local/bin/environment.sh # 设置环境变量
|
||||
|
||||
LOG_I "** Processing entry.sh **"
|
||||
|
||||
if [[ "$*" = "/usr/local/bin/run.sh" ]]; then
|
||||
print_image_welcome
|
||||
# 优先处理'-'开始的版本信息、帮助信息显示命令,如果是该类命令,处理后退出容器
|
||||
[[ "${1:0:1}" == '-' ]] && set -- "${APP_EXEC:-/bin/bash}" "$@" && print_command_help "$@"
|
||||
|
||||
LOG_I "** Starting ${APP_NAME} setup **"
|
||||
# 处理 root 用户**且**使用默认启动脚本时的初始化
|
||||
if [[ "$(id -u)" == '0' ]] && [[ "$1" == "run.sh" ]]; then
|
||||
print_welcome_info
|
||||
/usr/local/bin/setup.sh
|
||||
/usr/local/bin/init.sh
|
||||
LOG_I "** ${APP_NAME} setup finished! **"
|
||||
|
||||
# 执行应用启动脚本并替换当前进程
|
||||
exec gosu "${APP_USER}" "$@"
|
||||
fi
|
||||
|
||||
# 检测是否仅打印帮助信息
|
||||
[ "${1:0:1}" = '-' ] && set -- "${APP_EXEC:-/bin/bash}" "$@"
|
||||
print_command_help "$@"
|
||||
|
||||
# 处理非以上情形的自定义命令
|
||||
LOG_I "Start container with command: $@"
|
||||
exec "$@"
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.1 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.2 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 应用环境变量定义及初始化
|
||||
|
||||
# 通用设置
|
||||
export ENV_DEBUG=${ENV_DEBUG:-false}
|
||||
export ALLOW_ANONYMOUS="${ALLOW_ANONYMOUS:-no}"
|
||||
|
||||
# 通过读取变量名对应的 *_FILE 文件,获取变量值;如果对应文件存在,则通过传入参数设置的变量值会被文件中对应的值覆盖
|
||||
# 通过读取变量名对应的`*_FILE`文件,获取变量值
|
||||
# 变量优先级: *_FILE > 传入变量 > 默认值
|
||||
app_env_file_lists=(
|
||||
REDIS_PASSWORD
|
||||
REDIS_MASTER_PASSWORD
|
||||
PASSWORD
|
||||
MASTER_PASSWORD
|
||||
)
|
||||
for env_var in "${app_env_file_lists[@]}"; do
|
||||
file_env_var="${env_var}_FILE"
|
||||
@@ -22,59 +21,43 @@ for env_var in "${app_env_file_lists[@]}"; do
|
||||
done
|
||||
unset app_env_file_lists
|
||||
|
||||
# 应用路径参数
|
||||
export APP_HOME_DIR="/usr/local/${APP_NAME}"
|
||||
export APP_DEF_DIR="/etc/${APP_NAME}"
|
||||
export APP_CONF_DIR="/srv/conf/${APP_NAME}"
|
||||
export APP_DATA_DIR="/srv/data/${APP_NAME}"
|
||||
export APP_DATA_LOG_DIR="/srv/datalog/${APP_NAME}"
|
||||
# 应用路径参数(Dockerfile 已定义:APP_NAME、APP_VER,可能定义 APP_USER、APP_EXEC)
|
||||
export APP_EXEC="${APP_EXEC:-${APP_NAME}}"
|
||||
export APP_USER="${APP_USER:-${APP_NAME}}"
|
||||
export APP_GROUP="${APP_USER:-${APP_NAME}}"
|
||||
export APP_HOME="${APP_HOME:-/srv/${APP_NAME}}"
|
||||
export APP_BASE="${APP_BASE:-/usr/local/${APP_NAME}}"
|
||||
|
||||
export APP_DEF_DIR="${APP_BASE}/etc/${APP_NAME}"
|
||||
export APP_CONF_DIR="/srv/${APP_NAME}/conf"
|
||||
export APP_DATA_DIR="/srv/${APP_NAME}/data"
|
||||
export APP_CERT_DIR="/srv/${APP_NAME}/cert"
|
||||
export APP_LOG_DIR="/srv/${APP_NAME}/log"
|
||||
export APP_CACHE_DIR="/var/cache/${APP_NAME}"
|
||||
export APP_RUN_DIR="/var/run/${APP_NAME}"
|
||||
export APP_LOG_DIR="/var/log/${APP_NAME}"
|
||||
export APP_CERT_DIR="/srv/cert/${APP_NAME}"
|
||||
|
||||
# Paths
|
||||
export REDIS_CONF_FILE="${APP_CONF_DIR}/redis.conf"
|
||||
export REDIS_SENTINEL_FILE="${APP_CONF_DIR}/sentinel.conf"
|
||||
export REDIS_PID_FILE="${APP_RUN_DIR}/redis.pid"
|
||||
# Config files
|
||||
export REDIS_CONF_FILE="${REDIS_CONF_FILE:-${APP_CONF_DIR}/redis.conf}"
|
||||
export REDIS_SENTINEL_FILE="${REDIS_SENTINEL_FILE:-${APP_CONF_DIR}/sentinel.conf}"
|
||||
export REDIS_PID_FILE="${REDIS_PID_FILE:-${APP_RUN_DIR}/redis.pid}"
|
||||
|
||||
# Redis settings
|
||||
export REDIS_PORT="${REDIS_PORT:-6379}"
|
||||
export REDIS_DISABLE_COMMANDS="${REDIS_DISABLE_COMMANDS:-}"
|
||||
export REDIS_AOF_ENABLED="${REDIS_AOF_ENABLED:-yes}"
|
||||
|
||||
# Cluster configuration
|
||||
export REDIS_SENTINEL_HOST="${REDIS_SENTINEL_HOST:-}"
|
||||
export REDIS_SENTINEL_MASTER_NAME="${REDIS_SENTINEL_MASTER_NAME:-}"
|
||||
export REDIS_SENTINEL_PORT_NUMBER="${REDIS_SENTINEL_PORT_NUMBER:-26379}"
|
||||
|
||||
export REDIS_MASTER_HOST="${REDIS_MASTER_HOST:-}"
|
||||
export REDIS_MASTER_PORT_NUMBER="${REDIS_MASTER_PORT_NUMBER:-6379}"
|
||||
export REDIS_MASTER_PASSWORD="${REDIS_MASTER_PASSWORD:-}"
|
||||
export REDIS_REPLICATION_MODE="${REDIS_REPLICATION_MODE:-}"
|
||||
# Redis Settings
|
||||
export DISABLE_COMMANDS=${DISABLE_COMMANDS:-}
|
||||
|
||||
# Redis TLS Settings
|
||||
export REDIS_TLS_ENABLED="${REDIS_TLS_ENABLED:-no}"
|
||||
export REDIS_TLS_PORT="${REDIS_TLS_PORT:-6379}"
|
||||
export REDIS_TLS_CERT_FILE="${REDIS_TLS_CERT_FILE:-}"
|
||||
export REDIS_TLS_KEY_FILE="${REDIS_TLS_KEY_FILE:-}"
|
||||
export REDIS_TLS_CA_FILE="${REDIS_TLS_CA_FILE:-}"
|
||||
export REDIS_TLS_DH_PARAMS_FILE="${REDIS_TLS_DH_PARAMS_FILE:-}"
|
||||
export REDIS_TLS_AUTH_CLIENTS="${REDIS_TLS_AUTH_CLIENTS:-yes}"
|
||||
|
||||
# Authentication
|
||||
export REDIS_PASSWORD="${REDIS_PASSWORD:-}"
|
||||
if [[ -n "${REDIS_CFG_TLS_PORT:-}" ]]; then
|
||||
[[ "${REDIS_CFG_TLS_PORT}" == "${REDIS_CFG_PORT:-}" ]] && export REDIS_CFG_PORT=0
|
||||
fi
|
||||
|
||||
# 应用配置参数
|
||||
|
||||
# 内部变量
|
||||
export APP_PID_FILE="${REDIS_PID_FILE:-${APP_RUN_DIR}/${APP_NAME}.pid}"
|
||||
|
||||
export APP_DAEMON_USER="${APP_NAME}"
|
||||
export APP_DAEMON_GROUP="${APP_NAME}"
|
||||
# Sentinel configuration
|
||||
export REDIS_SENTINEL_HOST="${REDIS_SENTINEL_HOST:-}"
|
||||
export REDIS_SENTINEL_QUORUM="${REDIS_SENTINEL_QUORUM:-2}"
|
||||
export REDIS_SENTINEL_MASTER_NAME="${REDIS_SENTINEL_MASTER_NAME:-cvmaster}"
|
||||
export REDIS_SENTINEL_PORT_NUMBER="${REDIS_SENTINEL_PORT_NUMBER:-26379}"
|
||||
|
||||
# 个性化变量
|
||||
# 如果设置了用户密码,设置环境变量 REDISCLI_AUTH,用于 `redis-cli` 登录时使用;不显示输入,保证安全
|
||||
if [[ -n "${REDIS_PASSWORD}" ]]; then
|
||||
export REDISCLI_AUTH="${REDIS_PASSWORD:-}"
|
||||
if [[ -n "${REDIS_CFG_REQUIREPASS:-}" ]]; then
|
||||
export REDISCLI_AUTH="${REDIS_CFG_REQUIREPASS:-}"
|
||||
fi
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.2 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.3 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 应用初始化脚本
|
||||
|
||||
# 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用:
|
||||
# -e: 命令执行错误则报错; -u: 变量未定义则报错; -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错
|
||||
set -eu
|
||||
set -o pipefail
|
||||
set -euo pipefail
|
||||
|
||||
. /usr/local/bin/common.sh # 应用专用函数库
|
||||
. /usr/local/bin/environment.sh # 设置环境变量
|
||||
. /usr/local/bin/common.sh # 应用专用函数库
|
||||
|
||||
LOG_I "** Processing init.sh **"
|
||||
trap "app_stop_server" EXIT
|
||||
|
||||
trap "${APP_NAME}_stop_server" EXIT
|
||||
|
||||
${APP_NAME}_verify_minimum_env
|
||||
|
||||
# 执行应用预初始化操作
|
||||
${APP_NAME}_custom_preinit
|
||||
app_verify_minimum_env
|
||||
|
||||
# 执行应用初始化操作
|
||||
${APP_NAME}_default_init
|
||||
app_default_init
|
||||
|
||||
# 执行用户自定义初始化脚本
|
||||
${APP_NAME}_custom_init
|
||||
|
||||
LOG_I "** Processing init.sh finished! **"
|
||||
app_custom_init
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.5 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.6 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 应用启动脚本
|
||||
# 应用启动脚本;组合默认的配置参数及容器启动时传入的 CMD 参数,启动应用
|
||||
|
||||
# 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用:
|
||||
# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错
|
||||
set -eu
|
||||
set -o pipefail
|
||||
set -euo pipefail
|
||||
|
||||
. /colovu/lib/liblog.sh # 日志输出函数库
|
||||
|
||||
. /usr/local/bin/common.sh # 应用专用函数库
|
||||
. /usr/local/bin/environment.sh # 设置环境变量
|
||||
|
||||
LOG_I "** Processing run.sh **"
|
||||
|
||||
readonly START_COMMAND="$(command -v ${APP_EXEC})"
|
||||
readonly START_COMMAND="$(command -v ${APP_EXEC:-${APP_NAME}})"
|
||||
|
||||
# 配置默认启动参数(应用配置文件、前台方式启动)
|
||||
flags=("${REDIS_CONF_FILE:-}" "--daemonize" "no")
|
||||
# 将启动时使用 REDIS_EXTRA_FLAGS 指定的参数附加在启动参数中
|
||||
[[ -z "${REDIS_EXTRA_FLAGS:-}" ]] || flags+=("${REDIS_EXTRA_FLAGS[@]}")
|
||||
# 增加 "@" 以使用用户在命令行添加的扩展标识
|
||||
flags=("${REDIS_CONF_FILE}" "--daemonize" "no")
|
||||
[[ -n "${APP_EXTRA_FLAGS:-}" ]] && flags+=("${APP_EXTRA_FLAGS[@]}")
|
||||
flags+=("$@")
|
||||
|
||||
LOG_I "** Starting ${APP_NAME} **"
|
||||
#is_root && flags=("-u" "$APP_DAEMON_USER" "${flags[@]}")
|
||||
|
||||
LOG_I "Command: ${START_COMMAND[@]} ${flags[@]}"
|
||||
LOG_I "Start ${APP_NAME} with command: ${START_COMMAND[@]} ${flags[@]}"
|
||||
exec "${START_COMMAND[@]}" "${flags[@]}"
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Ver: 1.2 by Endial Fang (endial@126.com)
|
||||
# Ver: 1.3 by Endial Fang (endial@126.com)
|
||||
#
|
||||
# 应用环境及依赖文件设置脚本
|
||||
# 应用环境及依赖文件设置脚本;当前脚本以‘root’用户执行
|
||||
|
||||
# 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用:
|
||||
# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错
|
||||
set -eu
|
||||
set -o pipefail
|
||||
set -euo pipefail
|
||||
|
||||
. /colovu/lib/libcommon.sh # 加载通用函数库
|
||||
. /colovu/lib/libfs.sh # 加载文件操作函数库
|
||||
. /colovu/lib/libos.sh # 加载系统管理函数库
|
||||
|
||||
. /usr/local/bin/environment.sh # 设置环境变量
|
||||
. /usr/local/bin/common.sh # 应用专用函数库
|
||||
|
||||
LOG_I "** Processing setup.sh **"
|
||||
|
||||
APP_DIRS="${APP_CONF_DIR:-} ${APP_DATA_DIR:-} ${APP_LOG_DIR:-} ${APP_CERT_DIR:-} ${APP_DATA_LOG_DIR:-}"
|
||||
APP_DIRS=(/var/log/${APP_NAME} /var/run/${APP_NAME} /var/cache/${APP_NAME} ${APP_HOME})
|
||||
APP_DIRS+=(${APP_HOME}/conf ${APP_HOME}/data ${APP_HOME}/cert ${APP_HOME}/log)
|
||||
|
||||
LOG_I "Ensure directory exists: ${APP_DIRS}"
|
||||
for dir in ${APP_DIRS}; do
|
||||
LOG_I "Ensure directory exists: ${APP_DIRS[@]}"
|
||||
for dir in ${APP_DIRS[@]}; do
|
||||
ensure_dir_exists ${dir}
|
||||
done
|
||||
|
||||
# 检测指定文件是否在配置文件存储目录存在,如果不存在则拷贝(新挂载数据卷、手动删除都会导致不存在)
|
||||
LOG_I "Check config files in: ${APP_CONF_DIR}"
|
||||
if [[ ! -z "$(ls -A "${APP_DEF_DIR}")" ]]; then
|
||||
ensure_config_file_exist "${APP_DEF_DIR}" $(ls -A "${APP_DEF_DIR}")
|
||||
if [[ -z "$(ls -A "${APP_CONF_DIR}")" ]]; then
|
||||
app_ensure_config_file_exist "${APP_CONF_DIR}" "${APP_DEF_DIR}" $(ls -A "${APP_DEF_DIR}")
|
||||
fi
|
||||
|
||||
is_root && ensure_user_exists "$APP_DAEMON_USER" -g "$APP_DAEMON_GROUP"
|
||||
|
||||
LOG_I "** Processing setup.sh finished! **"
|
||||
# 解决使用non-root后,[emerg] open() "/dev/stdout" failed (13: Permission denied)
|
||||
LOG_D "Change permissions of stdout/stderr to 0662"
|
||||
chmod 0662 /dev/stdout /dev/stderr
|
||||
|
||||
@@ -4,14 +4,20 @@
|
||||
# 在安装完应用后,使用该脚本修改默认配置文件中部分配置项; 如果相应的配置项已经定义为容器环境变量,则不需要在这里修改
|
||||
|
||||
# 定义要修改的文件
|
||||
CONF_FILE="${APP_DEF_DIR}/redis.conf"
|
||||
CONF_FILE="/usr/local/${APP_NAME}/etc/${APP_NAME}/redis.conf"
|
||||
echo "Process overrides for: ${CONF_FILE}"
|
||||
# 修改默认配置信息
|
||||
sed -i -E 's/^#?pidfile .*/pidfile \/var\/run\/redis\/redis.pid/g' "${CONF_FILE}"
|
||||
sed -i -E 's/^#?logfile .*/logfile \"\/var\/log\/redis\/redis.log\"/g' "${CONF_FILE}"
|
||||
sed -i -E 's/^#?logfile .*/logfile \"\/srv\/redis\/log\/redis.log\"/g' "${CONF_FILE}"
|
||||
sed -i -E 's/^#?protected-mode .*/protected-mode no/g' "${CONF_FILE}"
|
||||
sed -i -E 's/^#?daemonize .*/daemonize no/g' "${CONF_FILE}"
|
||||
sed -i -E 's/^#?dir .*/dir \/srv\/'${APP_NAME}'\/data/g' "${CONF_FILE}"
|
||||
|
||||
SENTINEL_FILE="${APP_DEF_DIR}/sentinel.conf"
|
||||
SENTINEL_FILE="/usr/local/${APP_NAME}/etc/${APP_NAME}/sentinel.conf"
|
||||
echo "Process overrides for: ${SENTINEL_FILE}"
|
||||
# 修改 Sentinel 默认配置信息
|
||||
sed -i -E 's/^#?pidfile .*/pidfile \/var\/run\/redis\/redis-sentinel.pid/g' "${SENTINEL_FILE}"
|
||||
sed -i -E 's/^#?logfile .*/logfile \"\/var\/log\/redis\/redis-sentinel.log\"/g' "${SENTINEL_FILE}"
|
||||
sed -i -E 's/^#?logfile .*/logfile \"\/srv\/redis\/log\/redis-sentinel.log\"/g' "${SENTINEL_FILE}"
|
||||
sed -i -E 's/^#?protected-mode .*/protected-mode no/g' "${SENTINEL_FILE}"
|
||||
sed -i -E 's/^#?daemonize .*/daemonize no/g' "${SENTINEL_FILE}"
|
||||
sed -i -E 's/^#?dir .*/dir \/srv\/'${APP_NAME}'\/data/g' "${CONF_FILE}"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,342 @@
|
||||
# Example sentinel.conf
|
||||
# 本文件经过变更,删除了配置项前的前置空格(“#”与关键字之间),以便后续可以使用 sed 进行处理
|
||||
|
||||
# By default protected mode is disabled in sentinel mode. Sentinel is reachable
|
||||
# from interfaces different than localhost. Make sure the sentinel instance is
|
||||
# protected from the outside world via firewalling or other means.
|
||||
protected-mode no
|
||||
|
||||
# port <sentinel-port>
|
||||
# The port that this sentinel instance will run on
|
||||
port 26379
|
||||
|
||||
# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
|
||||
# Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
|
||||
# daemonized.
|
||||
daemonize no
|
||||
|
||||
# When running daemonized, Redis Sentinel writes a pid file in
|
||||
# /var/run/redis-sentinel.pid by default. You can specify a custom pid file
|
||||
# location here.
|
||||
pidfile /var/run/redis-sentinel.pid
|
||||
|
||||
# Specify the log file name. Also the empty string can be used to force
|
||||
# Sentinel to log on the standard output. Note that if you use standard
|
||||
# output for logging but daemonize, logs will be sent to /dev/null
|
||||
logfile ""
|
||||
|
||||
# sentinel announce-ip <ip>
|
||||
# sentinel announce-port <port>
|
||||
#
|
||||
# The above two configuration directives are useful in environments where,
|
||||
# because of NAT, Sentinel is reachable from outside via a non-local address.
|
||||
#
|
||||
# When announce-ip is provided, the Sentinel will claim the specified IP address
|
||||
# in HELLO messages used to gossip its presence, instead of auto-detecting the
|
||||
# local address as it usually does.
|
||||
#
|
||||
# Similarly when announce-port is provided and is valid and non-zero, Sentinel
|
||||
# will announce the specified TCP port.
|
||||
#
|
||||
# The two options don't need to be used together, if only announce-ip is
|
||||
# provided, the Sentinel will announce the specified IP and the server port
|
||||
# as specified by the "port" option. If only announce-port is provided, the
|
||||
# Sentinel will announce the auto-detected local IP and the specified port.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
#sentinel announce-ip 1.2.3.4
|
||||
#sentinel announce-port 26379
|
||||
|
||||
# dir <working-directory>
|
||||
# Every long running process should have a well-defined working directory.
|
||||
# For Redis Sentinel to chdir to /tmp at startup is the simplest thing
|
||||
# for the process to don't interfere with administrative tasks such as
|
||||
# unmounting filesystems.
|
||||
dir /tmp
|
||||
|
||||
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
|
||||
#
|
||||
# Tells Sentinel to monitor this master, and to consider it in O_DOWN
|
||||
# (Objectively Down) state only if at least <quorum> sentinels agree.
|
||||
#
|
||||
# Note that whatever is the ODOWN quorum, a Sentinel will require to
|
||||
# be elected by the majority of the known Sentinels in order to
|
||||
# start a failover, so no failover can be performed in minority.
|
||||
#
|
||||
# Replicas are auto-discovered, so you don't need to specify replicas in
|
||||
# any way. Sentinel itself will rewrite this configuration file adding
|
||||
# the replicas using additional configuration options.
|
||||
# Also note that the configuration file is rewritten when a
|
||||
# replica is promoted to master.
|
||||
#
|
||||
# Note: master name should not include special characters or spaces.
|
||||
# The valid charset is A-z 0-9 and the three characters ".-_".
|
||||
sentinel monitor mymaster 127.0.0.1 6379 2
|
||||
|
||||
# sentinel auth-pass <master-name> <password>
|
||||
#
|
||||
# Set the password to use to authenticate with the master and replicas.
|
||||
# Useful if there is a password set in the Redis instances to monitor.
|
||||
#
|
||||
# Note that the master password is also used for replicas, so it is not
|
||||
# possible to set a different password in masters and replicas instances
|
||||
# if you want to be able to monitor these instances with Sentinel.
|
||||
#
|
||||
# However you can have Redis instances without the authentication enabled
|
||||
# mixed with Redis instances requiring the authentication (as long as the
|
||||
# password set is the same for all the instances requiring the password) as
|
||||
# the AUTH command will have no effect in Redis instances with authentication
|
||||
# switched off.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
#sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
|
||||
|
||||
#sentinel auth-user <master-name> <username>
|
||||
#
|
||||
# This is useful in order to authenticate to instances having ACL capabilities,
|
||||
# that is, running Redis 6.0 or greater. When just auth-pass is provided the
|
||||
# Sentinel instance will authenticate to Redis using the old "AUTH <pass>"
|
||||
# method. When also an username is provided, it will use "AUTH <user> <pass>".
|
||||
# In the Redis servers side, the ACL to provide just minimal access to
|
||||
# Sentinel instances, should be configured along the following lines:
|
||||
#
|
||||
# user sentinel-user >somepassword +client +subscribe +publish \
|
||||
# +ping +info +multi +slaveof +config +client +exec on
|
||||
|
||||
# sentinel down-after-milliseconds <master-name> <milliseconds>
|
||||
#
|
||||
# Number of milliseconds the master (or any attached replica or sentinel) should
|
||||
# be unreachable (as in, not acceptable reply to PING, continuously, for the
|
||||
# specified period) in order to consider it in S_DOWN state (Subjectively
|
||||
# Down).
|
||||
#
|
||||
# Default is 30 seconds.
|
||||
sentinel down-after-milliseconds mymaster 30000
|
||||
|
||||
# IMPORTANT NOTE: starting with Redis 6.2 ACL capability is supported for
|
||||
# Sentinel mode, please refer to the Redis website https://redis.io/topics/acl
|
||||
# for more details.
|
||||
|
||||
# Sentinel's ACL users are defined in the following format:
|
||||
#
|
||||
# user <username> ... acl rules ...
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# user worker +@admin +@connection ~* on >ffa9203c493aa99
|
||||
#
|
||||
# For more information about ACL configuration please refer to the Redis
|
||||
# website at https://redis.io/topics/acl and redis server configuration
|
||||
# template redis.conf.
|
||||
|
||||
# ACL LOG
|
||||
#
|
||||
# The ACL Log tracks failed commands and authentication events associated
|
||||
# with ACLs. The ACL Log is useful to troubleshoot failed commands blocked
|
||||
# by ACLs. The ACL Log is stored in memory. You can reclaim memory with
|
||||
# ACL LOG RESET. Define the maximum entry length of the ACL Log below.
|
||||
acllog-max-len 128
|
||||
|
||||
# Using an external ACL file
|
||||
#
|
||||
# Instead of configuring users here in this file, it is possible to use
|
||||
# a stand-alone file just listing users. The two methods cannot be mixed:
|
||||
# if you configure users here and at the same time you activate the external
|
||||
# ACL file, the server will refuse to start.
|
||||
#
|
||||
# The format of the external ACL user file is exactly the same as the
|
||||
# format that is used inside redis.conf to describe users.
|
||||
#
|
||||
#aclfile /etc/redis/sentinel-users.acl
|
||||
|
||||
#requirepass <password>
|
||||
#
|
||||
# You can configure Sentinel itself to require a password, however when doing
|
||||
# so Sentinel will try to authenticate with the same password to all the
|
||||
# other Sentinels. So you need to configure all your Sentinels in a given
|
||||
# group with the same "requirepass" password. Check the following documentation
|
||||
# for more info: https://redis.io/topics/sentinel
|
||||
#
|
||||
# IMPORTANT NOTE: starting with Redis 6.2 "requirepass" is a compatibility
|
||||
# layer on top of the ACL system. The option effect will be just setting
|
||||
# the password for the default user. Clients will still authenticate using
|
||||
# AUTH <password> as usually, or more explicitly with AUTH default <password>
|
||||
# if they follow the new protocol: both will work.
|
||||
#
|
||||
# New config files are advised to use separate authentication control for
|
||||
# incoming connections (via ACL), and for outgoing connections (via
|
||||
# sentinel-user and sentinel-pass)
|
||||
#
|
||||
# The requirepass is not compatible with aclfile option and the ACL LOAD
|
||||
# command, these will cause requirepass to be ignored.
|
||||
|
||||
#sentinel sentinel-user <username>
|
||||
#
|
||||
# You can configure Sentinel to authenticate with other Sentinels with specific
|
||||
# user name.
|
||||
|
||||
#sentinel sentinel-pass <password>
|
||||
#
|
||||
# The password for Sentinel to authenticate with other Sentinels. If sentinel-user
|
||||
# is not configured, Sentinel will use 'default' user with sentinel-pass to authenticate.
|
||||
|
||||
# sentinel parallel-syncs <master-name> <numreplicas>
|
||||
#
|
||||
# How many replicas we can reconfigure to point to the new replica simultaneously
|
||||
# during the failover. Use a low number if you use the replicas to serve query
|
||||
# to avoid that all the replicas will be unreachable at about the same
|
||||
# time while performing the synchronization with the master.
|
||||
sentinel parallel-syncs mymaster 1
|
||||
|
||||
# sentinel failover-timeout <master-name> <milliseconds>
|
||||
#
|
||||
# Specifies the failover timeout in milliseconds. It is used in many ways:
|
||||
#
|
||||
# - The time needed to re-start a failover after a previous failover was
|
||||
# already tried against the same master by a given Sentinel, is two
|
||||
# times the failover timeout.
|
||||
#
|
||||
# - The time needed for a replica replicating to a wrong master according
|
||||
# to a Sentinel current configuration, to be forced to replicate
|
||||
# with the right master, is exactly the failover timeout (counting since
|
||||
# the moment a Sentinel detected the misconfiguration).
|
||||
#
|
||||
# - The time needed to cancel a failover that is already in progress but
|
||||
# did not produced any configuration change (SLAVEOF NO ONE yet not
|
||||
# acknowledged by the promoted replica).
|
||||
#
|
||||
# - The maximum time a failover in progress waits for all the replicas to be
|
||||
# reconfigured as replicas of the new master. However even after this time
|
||||
# the replicas will be reconfigured by the Sentinels anyway, but not with
|
||||
# the exact parallel-syncs progression as specified.
|
||||
#
|
||||
# Default is 3 minutes.
|
||||
sentinel failover-timeout mymaster 180000
|
||||
|
||||
# SCRIPTS EXECUTION
|
||||
#
|
||||
# sentinel notification-script and sentinel reconfig-script are used in order
|
||||
# to configure scripts that are called to notify the system administrator
|
||||
# or to reconfigure clients after a failover. The scripts are executed
|
||||
# with the following rules for error handling:
|
||||
#
|
||||
# If script exits with "1" the execution is retried later (up to a maximum
|
||||
# number of times currently set to 10).
|
||||
#
|
||||
# If script exits with "2" (or an higher value) the script execution is
|
||||
# not retried.
|
||||
#
|
||||
# If script terminates because it receives a signal the behavior is the same
|
||||
# as exit code 1.
|
||||
#
|
||||
# A script has a maximum running time of 60 seconds. After this limit is
|
||||
# reached the script is terminated with a SIGKILL and the execution retried.
|
||||
|
||||
# NOTIFICATION SCRIPT
|
||||
#
|
||||
# sentinel notification-script <master-name> <script-path>
|
||||
#
|
||||
# Call the specified notification script for any sentinel event that is
|
||||
# generated in the WARNING level (for instance -sdown, -odown, and so forth).
|
||||
# This script should notify the system administrator via email, SMS, or any
|
||||
# other messaging system, that there is something wrong with the monitored
|
||||
# Redis systems.
|
||||
#
|
||||
# The script is called with just two arguments: the first is the event type
|
||||
# and the second the event description.
|
||||
#
|
||||
# The script must exist and be executable in order for sentinel to start if
|
||||
# this option is provided.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
#sentinel notification-script mymaster /var/redis/notify.sh
|
||||
|
||||
# CLIENTS RECONFIGURATION SCRIPT
|
||||
#
|
||||
# sentinel client-reconfig-script <master-name> <script-path>
|
||||
#
|
||||
# When the master changed because of a failover a script can be called in
|
||||
# order to perform application-specific tasks to notify the clients that the
|
||||
# configuration has changed and the master is at a different address.
|
||||
#
|
||||
# The following arguments are passed to the script:
|
||||
#
|
||||
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
|
||||
#
|
||||
# <state> is currently always "start"
|
||||
# <role> is either "leader" or "observer"
|
||||
#
|
||||
# The arguments from-ip, from-port, to-ip, to-port are used to communicate
|
||||
# the old address of the master and the new address of the elected replica
|
||||
# (now a master).
|
||||
#
|
||||
# This script should be resistant to multiple invocations.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
#sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
|
||||
|
||||
# SECURITY
|
||||
#
|
||||
# By default SENTINEL SET will not be able to change the notification-script
|
||||
# and client-reconfig-script at runtime. This avoids a trivial security issue
|
||||
# where clients can set the script to anything and trigger a failover in order
|
||||
# to get the program executed.
|
||||
sentinel deny-scripts-reconfig yes
|
||||
|
||||
# REDIS COMMANDS RENAMING (DEPRECATED)
|
||||
#
|
||||
# WARNING: avoid using this option if possible, instead use ACLs.
|
||||
#
|
||||
# Sometimes the Redis server has certain commands, that are needed for Sentinel
|
||||
# to work correctly, renamed to unguessable strings. This is often the case
|
||||
# of CONFIG and SLAVEOF in the context of providers that provide Redis as
|
||||
# a service, and don't want the customers to reconfigure the instances outside
|
||||
# of the administration console.
|
||||
#
|
||||
# In such case it is possible to tell Sentinel to use different command names
|
||||
# instead of the normal ones. For example if the master "mymaster", and the
|
||||
# associated replicas, have "CONFIG" all renamed to "GUESSME", I could use:
|
||||
#
|
||||
# SENTINEL rename-command mymaster CONFIG GUESSME
|
||||
#
|
||||
# After such configuration is set, every time Sentinel would use CONFIG it will
|
||||
# use GUESSME instead. Note that there is no actual need to respect the command
|
||||
# case, so writing "config guessme" is the same in the example above.
|
||||
#
|
||||
# SENTINEL SET can also be used in order to perform this configuration at runtime.
|
||||
#
|
||||
# In order to set a command back to its original name (undo the renaming), it
|
||||
# is possible to just rename a command to itself:
|
||||
#
|
||||
#SENTINEL rename-command mymaster CONFIG CONFIG
|
||||
|
||||
# HOSTNAMES SUPPORT
|
||||
#
|
||||
# Normally Sentinel uses only IP addresses and requires SENTINEL MONITOR
|
||||
# to specify an IP address. Also, it requires the Redis replica-announce-ip
|
||||
# keyword to specify only IP addresses.
|
||||
#
|
||||
# You may enable hostnames support by enabling resolve-hostnames. Note
|
||||
# that you must make sure your DNS is configured properly and that DNS
|
||||
# resolution does not introduce very long delays.
|
||||
#
|
||||
SENTINEL resolve-hostnames no
|
||||
|
||||
# When resolve-hostnames is enabled, Sentinel still uses IP addresses
|
||||
# when exposing instances to users, configuration files, etc. If you want
|
||||
# to retain the hostnames when announced, enable announce-hostnames below.
|
||||
#
|
||||
SENTINEL announce-hostnames no
|
||||
|
||||
# When master_reboot_down_after_period is set to 0, Sentinel does not fail over
|
||||
# when receiving a -LOADING response from a master. This was the only supported
|
||||
# behavior before version 7.0.
|
||||
#
|
||||
# Otherwise, Sentinel will use this value as the time (in ms) it is willing to
|
||||
# accept a -LOADING response after a master has been rebooted, before failing
|
||||
# over.
|
||||
SENTINEL master-reboot-down-after-period mymaster 0
|
||||
Reference in New Issue
Block a user