diff --git a/Dockerfile b/Dockerfile index 71dde40..8ac0654 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,8 @@ -# Ver: 1.9 by Endial Fang (endial@126.com) +# Ver: 1.10 by Endial Fang (endial@126.com) # -# 默认变量 ======================================================================== +# 系统默认变量 ==================================================================== # 该部分变量为系统根据编译命令默认设置 - # `TARGETPLATFORM`:构建后的目标平台信息。如 `linux/amd64`,`linux/arm/v7`,`windows/amd64` # `TARGETOS`:目标平台信息(TARGETPLATFORM)中的操作系统部分,如:`linux`、`windows` # `TARGETARCH`:目标平台信息(TARGETPLATFORM)中的平台架构部分,如:`amd64`、`arm` @@ -16,18 +15,11 @@ # 可变参数 ======================================================================== # 该部分变量,在编译命令中通过 `--build-arg` 传入;如果未设置,则使用下面对应的默认值 -# 设置当前应用名称及版本 -ARG APP_NAME=nginx -ARG APP_VER=1.24.0 - -# 设置默认仓库地址,默认为本地仓库;定义时需要包含末尾的`/` -ARG REGISTRY_URL="docker.colovu.com/" - -# 设置 apt-get 源:default / ustc / aliyun -ARG APT_SOURCE=aliyun - -# 编译镜像时指定用于加速的本地软件包存储服务器地址 -ARG LOCAL_URL="http://local.colovu.com/dist" +ARG APP_NAME=nginx # 设置当前应用名称 +ARG APP_VER=1.24.0 # 设置当前应用版本 +ARG REGISTRY_URL="docker.colovu.com/" # 设置默认仓库地址,默认为本地仓库;定义时需要包含末尾的`/` +ARG APT_SOURCE=aliyun # 设置 apt-get 源:default / ustc / aliyun +ARG LOCAL_URL="http://local.colovu.com/dist" # 编译镜像时指定用于加速的本地软件包存储服务器地址 # 0. 预处理 ====================================================================== FROM --platform=${TARGETPLATFORM:-linux/amd64} ${REGISTRY_URL}colovu/dbuilder:12 as builder @@ -38,10 +30,10 @@ ARG APP_VER ARG APT_SOURCE ARG LOCAL_URL -# 选择软件包源(Optional),以加速后续软件包安装 +# 选择软件包源,加速后续软件包安装 RUN select_source ${APT_SOURCE}; -# 安装依赖的软件包及库(Optional) +# 安装依赖的软件包及库 RUN install_pkg libpcre3 libpcre3-dev \ zlib1g zlib1g-dev \ libxslt1.1 libxslt1-dev \ @@ -49,13 +41,10 @@ RUN install_pkg libpcre3 libpcre3-dev \ libxml2 libxml2-dev \ geoip-bin geoip-database libgeoip-dev -# 设置工作目录 -WORKDIR /tmp - # 下载并解压软件包 nginx RUN set -eux; \ appName="${APP_NAME}-${APP_VER}.tar.gz"; \ - [ ! -z ${LOCAL_URL} ] && localURL=${LOCAL_URL}/nginx; \ + [ -n ${LOCAL_URL} ] && localURL=${LOCAL_URL}/${APP_NAME}; \ appUrls="${localURL:-} \ http://nginx.org/download \ "; \ @@ -66,20 +55,21 @@ RUN set -eux; \ APP_ARCH=`arch` \ APP_SRC="/tmp/${APP_NAME}-${APP_VER}"; \ cd ${APP_SRC}; \ - LDFLAGS="-L/usr/local/lib -L/usr/lib/${APP_ARCH}-linux-gnu" ./configure \ - --prefix=/usr/local/nginx \ - --sbin-path=/usr/local/nginx/sbin/nginx \ - --conf-path=/usr/local/nginx/etc/nginx/nginx.conf \ - --pid-path=/var/run/nginx/nginx.pid \ - --lock-path=/var/run/nginx/nginx.lock \ - --http-log-path=/var/log/nginx/access.log \ - --error-log-path=/var/log/nginx/error.log \ - --modules-path=/usr/local/nginx/modules \ - --http-client-body-temp-path=/var/cache/nginx/client_temp \ - --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ - --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ - --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ - --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ + LDFLAGS="-L/usr/local/lib -L/usr/lib/${APP_ARCH}-linux-gnu" \ + ./configure \ + --prefix=/usr/local/${APP_NAME} \ + --sbin-path=/usr/local/${APP_NAME}/sbin/nginx \ + --conf-path=/usr/local/${APP_NAME}/etc/nginx/nginx.conf \ + --pid-path=/var/run/${APP_NAME}/nginx.pid \ + --lock-path=/var/run/${APP_NAME}/nginx.lock \ + --http-log-path=/var/log/${APP_NAME}/access.log \ + --error-log-path=/var/log/${APP_NAME}/error.log \ + --modules-path=/usr/local/${APP_NAME}/modules \ + --http-client-body-temp-path=/var/cache/${APP_NAME}/client_temp \ + --http-proxy-temp-path=/var/cache/${APP_NAME}/proxy_temp \ + --http-fastcgi-temp-path=/var/cache/${APP_NAME}/fastcgi_temp \ + --http-uwsgi-temp-path=/var/cache/${APP_NAME}/uwsgi_temp \ + --http-scgi-temp-path=/var/cache/${APP_NAME}/scgi_temp \ \ --with-pcre \ --with-pcre-jit \ @@ -105,28 +95,24 @@ RUN set -eux; \ --with-mail \ ; \ make -j "$(nproc)" && make install; \ - strip /usr/local/nginx/sbin/nginx; + strip /usr/local/${APP_NAME}/sbin/nginx; # 生成默认 PHP 首页文件 RUN set -eux; \ - echo "/usr/local/nginx/html/index.php; \ - echo "phpinfo();" >>/usr/local/nginx/html/index.php; \ - echo "?>" >>/usr/local/nginx/html/index.php; + echo "/usr/local/${APP_NAME}/html/index.php; \ + echo "phpinfo();" >>/usr/local/${APP_NAME}/html/index.php; \ + echo "?>" >>/usr/local/${APP_NAME}/html/index.php; # 检测并生成依赖文件记录 RUN set -eux; \ find /usr/local/${APP_NAME} -type f -executable -exec ldd '{}' ';' | \ - awk '/=>/ { print $(NF-1) }' | \ - sort -u | \ - xargs -r readlink -f | \ - xargs -r dpkg-query --search 2>/dev/null | \ - cut -d: -f1 | \ - sort -u >>/usr/local/${APP_NAME}/runDeps; + awk '/=>/ { print $(NF-1) }' | xargs -r basename -a | sort -u | \ + xargs -r dpkg-query --search 2>/dev/null | cut -d: -f1 | sort -u \ + >>/usr/local/${APP_NAME}/runDeps; # 1. 生成镜像 ===================================================================== FROM --platform=${TARGETPLATFORM:-linux/amd64} ${REGISTRY_URL}colovu/debian:12 - # 声明需要使用的全局可变参数(ARG声明的变量仅编译打包阶段有效) ARG APP_NAME ARG APP_VER @@ -136,12 +122,9 @@ ARG APT_SOURCE ENV APP_NAME=${APP_NAME} \ APP_VER=${APP_VER} \ APP_EXEC=${APP_NAME} \ - APP_HOME_DIR=/usr/local/${APP_NAME} \ - APP_DEF_DIR=/etc/${APP_NAME} - -# 增加应用可执行文件及库文件搜索路径 -ENV PATH="${APP_HOME_DIR}/sbin:${APP_HOME_DIR}/bin:${PATH}" \ - LD_LIBRARY_PATH="${APP_HOME_DIR}/lib" + APP_USER=${APP_NAME} \ + \ + PATH="${PATH}:/usr/local/${APP_NAME}/sbin" LABEL \ "Version"="v${APP_VER}" \ @@ -149,54 +132,44 @@ LABEL \ "Github"="https://github.com/colovu/docker-${APP_NAME}" \ "Vendor"="Endial Fang (endial@126.com)" -# 从预处理过程中拷贝软件包(Optional),可以使用阶段编号或阶段命名定义来源 -COPY --from=0 /usr/local/${APP_NAME} /usr/local/${APP_NAME} +# 配置容器的数据卷、工作目录及服务端口(必须保证端口在1024之上) +VOLUME ["/srv/${APP_NAME}/conf", "/srv/${APP_NAME}/data", "/srv/${APP_NAME}/cert", "/srv/${APP_NAME}/log"] +WORKDIR /srv/${APP_NAME} +EXPOSE 8080 8443 -# 拷贝应用使用的客制化脚本 +# 拷贝多阶段构建结果输出及客制化脚本 +COPY --from=builder /usr/local/${APP_NAME} /usr/local/${APP_NAME} COPY customer / RUN set -eux; \ \ # 创建对应的用户及数据存储目录 - prepare_env; \ + useradd -U -u 996 -d /srv/${APP_NAME} -s /usr/sbin/nologin -r ${APP_USER}; \ + mkdir -p /var/log/${APP_NAME} /var/run/${APP_NAME} /var/cache/${APP_NAME}; \ + mkdir -p /srv/${APP_NAME}/conf /srv/${APP_NAME}/data /srv/${APP_NAME}/cert /srv/${APP_NAME}/log; \ + chown -R ${APP_USER}:${APP_USER} /var/log/${APP_NAME} /var/run/${APP_NAME} /var/cache/${APP_NAME}; \ + chown -R ${APP_USER}:${APP_USER} /usr/local/${APP_NAME} /srv/${APP_NAME}; \ + \ /bin/bash -c "ln -sf /usr/local/${APP_NAME}/etc/${APP_NAME} /etc/"; \ \ - # 选择软件包源(Optional),以加速后续软件包安装 + # 选择软件包源,以加速后续软件包安装 select_source ${APT_SOURCE}; \ \ - # 安装依赖的软件包及库(Optional) + # 安装应用依赖的软件包及库 install_pkg `cat /usr/local/${APP_NAME}/runDeps`; \ \ - # 执行后处理脚本,并验证安装的应用 - override_file="/usr/local/overrides/overrides-${APP_VER}.sh"; \ - [ -e "${override_file}" ] && /bin/bash "${override_file}"; \ + # 执行后处理脚本 + overrideShell="/usr/local/overrides/overrides-${APP_VER}.sh"; \ + [ -e "${overrideShell}" ] && /bin/bash "${overrideShell}"; \ + \ + # 验证安装的应用 ${APP_EXEC} -V ; -# 默认提供的数据卷 -VOLUME ["/srv/conf", "/srv/data", "/srv/cert", "/var/log"] - -# 默认使用gosu切换为新建用户启动,必须保证端口在1024之上 -EXPOSE 8080 8443 - -# 关闭基础镜像的健康检查 #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 8080 -# 应用健康状态检查(需要使用 EXPOSE 定义的端口) -#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 8080 - -# 使用 non-root 用户运行后续的命令 -USER 1001 - -# 设置工作目录 -WORKDIR /srv/conf - -# 容器入口命令脚本,'/usr/local/bin/entry.sh' -ENTRYPOINT ["entry.sh"] - -# 应用程序的启动命令,可为应用程序可执行命令或脚本 -# 必须使用非守护进程方式运行,'/usr/local/bin/run.sh' -CMD ["run.sh"] +# 使用 dumb-init 启动入口 Shell,确保容器可以接收控制信号;并使用前台方式启动应用程序 +ENTRYPOINT ["dumb-init", "entry.sh"] +CMD ["run.sh"] diff --git a/customer/usr/local/bin/common.sh b/customer/usr/local/bin/common.sh index 20a3fad..4f333f8 100644 --- a/customer/usr/local/bin/common.sh +++ b/customer/usr/local/bin/common.sh @@ -1,9 +1,8 @@ #!/bin/bash -# Ver: 1.1 by Endial Fang (endial@126.com) +# Ver: 1.3 by Endial Fang (endial@126.com) # # 应用通用业务处理函数 -# 加载依赖脚本 . /colovu/lib/libcommon.sh # 通用函数库 . /colovu/lib/libfile.sh @@ -13,423 +12,31 @@ . /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="" -# 使用环境变量中以 "" 开头的的全局变量更新指定配置文件中对应项(以"."分隔) -# 如果需要全部转换为小写,可使用命令: tr '[:upper:]' '[:lower:]' -# 全局变量: -# _* : -# 替换规则(变量中字符 ==> 替换后全局变量中字符): -# - "." ==> "_" -# - "_" ==> "__" -# - "-" ==> "___" -# -# 变量: -# $1 - 配置文件 -# $2 - 前缀(不含结束的"_") -# -# 举例: -# CORE_CONF_fs_defaultFS 对应配置文件中的配置项:fs.defaultFS -nginx_configure_from_environment() { - # 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:]')" - value="${!var}" - nginx_conf_set "$key" "$value" - done - - local path="${1:?missing file}" - local envPrefix="${2:?missing parameters}" - - LOG_D " File: ${path}" - # Map environment variables to config properties - #for var in `printenv | grep ${envPrefix} | "${!${envPrefix}_@}"`; do - # LOG_D " Process: ${var}" - # key="$(echo "${var}" | sed -e 's/^${envPrefix}_//g' -e 's/___/-/g' -e 's/__/_/g' -e 's/_/\./g')" - # value="${!var}" - # hadoop_common_xml_set "${path}" "${key}" "${value}" - #done - #for var in $(printenv | grep ${envPrefix}); do - # LOG_D " Process: ${var}" - # key="$(echo "${var}" | sed -e 's/^${envPrefix}_//g' -e 's/___/-/g' -e 's/__/_/g' -e 's/_/\./g' )" - # value="${!var}" - # hadoop_common_xml_set "${path}" "${key}" "${value}" - #done - for c in `printenv | perl -sne 'print "$1 " if m/^${envPrefix}_(.+?)=.*/' -- -envPrefix=${envPrefix}`; do - name=`echo ${c} | perl -pe 's/___/-/g; s/__/_/g; s/_/./g;'` - key="${envPrefix}_${c}" - #LOG_D " Process: ${key} => ${!key}" - value="${!key}" - hadoop_common_xml_set "${path}" "${name}" "${value}" - done -} - -# 将变量配置更新至配置文件 -# 参数: -# $1 - 文件 -# $2 - 变量 -# $3 - 值(列表) -nginx_common_conf_set() { - local file="${1:?missing file}" - local key="${2:?missing key}" - shift - shift - local values=("$@") - - if [[ "${#values[@]}" -eq 0 ]]; then - LOG_E "missing value" - return 1 - elif [[ "${#values[@]}" -ne 1 ]]; then - for i in "${!values[@]}"; do - nginx_common_conf_set "$file" "${key[$i]}" "${values[$i]}" - done - else - value="${values[0]}" - # Check if the value was set before - if grep -q "^[#\\s]*$key\s*=.*" "$file"; then - # Update the existing key - replace_in_file "$file" "^[#\\s]*${key}\s*=.*" "${key}=${value}" false + 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 - # 增加一个新的配置项;如果在其他位置有类似操作,需要注意换行 - printf "%s=%s" "$key" "$value" >>"$file" - fi - fi -} - -# 更新 server.properties 配置文件中指定变量值 -# 变量: -# $1 - 变量 -# $2 - 值(列表) -nginx_conf_set() { - nginx_common_conf_set "${APP_CONF_DIR}/zoo.cfg" "$@" -} - -# 更新 log4j.properties 配置文件中指定变量值 -# 变量: -# $1 - 变量 -# $2 - 值(列表) -nginx_log4j_set() { - nginx_common_conf_set "${APP_CONF_DIR}/log4j.properties" "$@" -} - -# 使用环境变量中配置,更新配置文件 -nginx_update_conf() { - LOG_I "Update configure files..." - -} - -# 生成默认配置文件 -nginx_generate_conf() { - # 准备原始默认配置文件或生成空文件 - cp "${APP_CONF_DIR}/zoo_sample.cfg" "$APP_CONF_FILE" - - echo "">> "$APP_CONF_FILE" - - # 根据容器参数,设置配置文件 - nginx_log4j_set "zookeeper.console.threshold" "${ZOO_LOG_LEVEL}" - nginx_log4j_set "zookeeper.log.dir" "${APP_LOG_DIR}" - - nginx_update_conf -} - -# 设置环境变量 JVMFLAGS -# 参数: -# $1 - value -nginx_export_jvmflags() { - local -r value="${1:?value is required}" - - export JVMFLAGS="${JVMFLAGS} ${value}" - echo "export JVMFLAGS=\"${JVMFLAGS}\"" > "${APP_CONF_DIR}/java.env" -} - -# 配置 HEAP 大小 -# 参数: -# $1 - HEAP 大小 -nginx_configure_heap_size() { - local -r heap_size="${1:?heap_size is required}" - - if [[ "${JVMFLAGS}" =~ -Xm[xs].*-Xm[xs] ]]; then - LOG_D "Using specified values (JVMFLAGS=${JVMFLAGS})" - else - LOG_D "Setting '-Xmx${heap_size}m -Xms${heap_size}m' heap options..." - nginx_export_jvmflags "-Xmx${heap_size}m -Xms${heap_size}m" - fi -} - -# 检测用户参数信息是否满足条件; 针对部分权限过于开放情况,打印提示信息 -nginx_verify_minimum_env() { - local error_code=0 - - LOG_D "Validating settings in NGINX_* env vars..." - - print_validation_error() { - LOG_E "$1" - error_code=1 - } - - # 检测认证设置。如果不允许匿名登录,检测登录用户名及密码是否设置 -# if is_boolean_yes "$ALLOW_ANONYMOUS_LOGIN"; then -# LOG_W "You have set the environment variable ALLOW_ANONYMOUS_LOGIN=${ALLOW_ANONYMOUS_LOGIN}. For safety reasons, do not use this flag in a production environment." -# elif ! is_boolean_yes "$ZOO_ENABLE_AUTH"; then -# print_validation_error "The ZOO_ENABLE_AUTH environment variable does not configure authentication. Set the environment variable ALLOW_ANONYMOUS_LOGIN=yes to allow unauthenticated users to connect to ZooKeeper." -# fi - - # TODO: 其他参数检测 - - [[ "$error_code" -eq 0 ]] || exit "$error_code" -} - -# 更改默认监听地址为 "*" 或 "0.0.0.0",以对容器外提供服务;默认配置文件应当为仅监听 localhost(127.0.0.1) -nginx_enable_remote_connections() { - LOG_D "Modify default config to enable all IP access" - -} - -# 检测依赖的服务端口是否就绪;该脚本依赖系统工具 'netcat' -# 参数: -# $1 - host:port -nginx_wait_service() { - local serviceport=${1:?Missing server info} - local service=${serviceport%%:*} - local port=${serviceport#*:} - local retry_seconds=5 - local max_try=100 - let i=1 - - if [[ -z "$(which nc)" ]]; then - LOG_E "Nedd nc installed before, command: \"apt-get install netcat\"." - exit 1 - fi - - LOG_I "[0/${max_try}] check for ${service}:${port}..." - - set +e - nc -z ${service} ${port} - 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_I "[$i/${max_try}] try in ${retry_seconds}s once again ..." - let "i++" - sleep ${retry_seconds} - - nc -z ${service} ${port} - result=$? - done - - set -e - LOG_I "[$i/${max_try}] ${service}:${port} is available." -} - -# 以后台方式启动应用服务,并等待启动就绪 -nginx_start_server_bg() { - nginx_is_server_running && return - - LOG_I "Starting ${APP_NAME} in background..." - - # 使用内置脚本启动服务 - #local start_command="zkServer.sh start" - #if is_boolean_yes "${ENV_DEBUG}"; then - # $start_command & - #else - # $start_command >/dev/null 2>&1 & - #fi - - # 使用内置命令启动服务 - # if [[ "${ENV_DEBUG:-false}" = true ]]; then - # debug_execute "rabbitmq-server" & - #else - # debug_execute "rabbitmq-server" >/dev/null 2>&1 & - #fi - - # 通过命令或特定端口检测应用是否就绪 - LOG_I "Checking ${APP_NAME} ready status..." - # wait-for-port --timeout 60 "$ZOO_PORT_NUMBER" - - LOG_D "${APP_NAME} is ready for service..." -} - -# 停止应用服务 -nginx_stop_server() { - if nginx_is_server_running ; then - LOG_I "Stopping ${APP_NAME}..." - - # 使用 PID 文件 kill 进程 - stop_service_using_pid "$APP_PID_FILE" - - # 使用内置命令停止服务 - #debug_execute "rabbitmqctl" stop - - # 使用内置脚本关闭服务 - #if [[ "$ENV_DEBUG" = true ]]; then - # "zkServer.sh" stop - #else - # "zkServer.sh" stop >/dev/null 2>&1 - #fi - - # 检测停止是否完成 - local counter=10 - while [[ "$counter" -ne 0 ]] && nginx_is_server_running; do - LOG_D "Waiting for ${APP_NAME} to stop..." - sleep 1 - counter=$((counter - 1)) - done - fi -} - -# 检测应用服务是否在后台运行中 -nginx_is_server_running() { - LOG_D "Check if ${APP_NAME} is running..." - local pid - pid="$(get_pid_from_file '/var/run/${APP_NAME}/${APP_NAME}.pid')" - - if [[ -z "${pid}" ]]; then - false - else - is_service_running "${pid}" - fi -} - -# 清理初始化应用时生成的临时文件 -nginx_clean_tmp_file() { - LOG_D "Clean ${APP_NAME} tmp files for init..." - -} - -# 在重新启动容器时,删除标志文件及必须删除的临时文件 (容器重新启动) -nginx_clean_from_restart() { - LOG_D "Clean ${APP_NAME} tmp files for restart..." - local -r -a files=( - "/var/run/${APP_NAME}/${APP_NAME}.pid" - ) - - for file in ${files[@]}; do - if [[ -f "$file" ]]; then - LOG_I "Cleaning stale $file file" - rm "$file" + [[ ! -e "${dist_path}/${f}" ]] && LOG_D " Copy: ${base_path}/${f} to ${dist_path}" && cp "${base_path}/${f}" "${dist_path}" fi + shift done } - -# 应用默认初始化操作 -# 执行完毕后,生成文件 ${APP_CONF_DIR}/.app_init_flag 及 ${APP_DATA_DIR}/.data_init_flag 文件 -nginx_default_init() { - nginx_clean_from_restart - LOG_D "Check init status of ${APP_NAME}..." - - # 检测配置文件是否存在 - if [[ ! -f "${APP_CONF_DIR}/.app_init_flag" ]]; then - LOG_I "No injected configuration file found, creating default config files..." - - # TODO: 生成配置文件,并按照容器运行参数进行相应修改 - - # 修改默认 index.html 文件,增加限制主机名信息,用于集群测试验证 - HostInfo="

Welcome to nginx!


Served by host: ${HOSTNAME}

" - sed -i -e "s#^

Welcome to nginx!

*#

Welcome to nginx!


Served by host: ${HOSTNAME}

#g" "/usr/local/nginx/html/index.html" - - 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!" - - LOG_D "Update configure files from environment..." - nginx_update_conf - fi - - if [[ ! -f "${APP_DATA_DIR}/.data_init_flag" ]]; then - LOG_I "Deploying ${APP_NAME} from scratch..." - - # 启动后台服务 - nginx_start_server_bg - - # TODO: 根据需要生成相应初始化数据 - - 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 -nginx_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 - # nginx_wait_service "${i}" - #done -} - -# 用户自定义的应用初始化操作,依次执行目录initdb.d中的初始化脚本 -# 执行完毕后,生成文件 ${APP_DATA_DIR}/.custom_init_flag -nginx_custom_init() { - LOG_I "Check custom initdb status of ${APP_NAME}..." - - # 检测用户配置文件目录是否存在 initdb.d 文件夹,如果存在,尝试执行目录中的初始化脚本 - if [ -d "/srv/conf/${APP_NAME}/initdb.d" ]; then - # 检测数据存储目录是否存在已初始化标志文件;如果不存在,检索可执行脚本文件并进行初始化操作 - if [[ -n $(find "/srv/conf/${APP_NAME}/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..." - - # 启动后台服务 - nginx_start_server_bg - - # 检索所有可执行脚本,排序后执行 - find "/srv/conf/${APP_NAME}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do - case "$f" in - *.sh) - if [[ -x "$f" ]]; then - LOG_D "Executing $f"; "$f" - else - 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 - - 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." - else - LOG_I "Custom init for ${APP_NAME} already done before, skipping initialization." - fi - fi - -} - diff --git a/customer/usr/local/bin/entry.sh b/customer/usr/local/bin/entry.sh index a9e0dcf..6d16961 100755 --- a/customer/usr/local/bin/entry.sh +++ b/customer/usr/local/bin/entry.sh @@ -1,29 +1,30 @@ -#!/bin/bash -# Ver: 1.2 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}" == '-' ]] && 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 "$@" diff --git a/customer/usr/local/bin/environment.sh b/customer/usr/local/bin/environment.sh index 722f302..b5a95ae 100644 --- a/customer/usr/local/bin/environment.sh +++ b/customer/usr/local/bin/environment.sh @@ -1,13 +1,12 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.2 by Endial Fang (endial@126.com) # # 应用环境变量定义及初始化 -# 通用设置 export ENV_DEBUG=${ENV_DEBUG:-false} -export ALLOW_ANONYMOUS_LOGIN="${ALLOW_ANONYMOUS_LOGIN:-no}" +export ALLOW_ANONYMOUS="${ALLOW_ANONYMOUS:-no}" -# 通过读取变量名对应的 *_FILE 文件,获取变量值;如果对应文件存在,则通过传入参数设置的变量值会被文件中对应的值覆盖 +# 通过读取变量名对应的`*_FILE`文件,获取变量值 # 变量优先级: *_FILE > 传入变量 > 默认值 app_env_file_lists=( APP_PASSWORD @@ -21,26 +20,23 @@ 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}" - # 应用配置参数 export APP_CONF_FILE=${APP_CONF_DIR}/nginx.conf - -# 内部变量 -export APP_PID_FILE="${APP_PID_FILE:-${APP_RUN_DIR}/${APP_NAME}.pid}" - -export APP_DAEMON_USER="${APP_NAME}" -export APP_DAEMON_GROUP="${APP_NAME}" +export APP_PID_FILE="${APP_PID_FILE:-/var/run/${APP_NAME}/${APP_NAME}.pid}" # 个性化变量 - diff --git a/customer/usr/local/bin/init.sh b/customer/usr/local/bin/init.sh deleted file mode 100755 index 24cd936..0000000 --- a/customer/usr/local/bin/init.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Ver: 1.2 by Endial Fang (endial@126.com) -# -# 应用初始化脚本 - -# 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用: -# -e: 命令执行错误则报错; -u: 变量未定义则报错; -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 -set -eu -set -o pipefail - -. /usr/local/bin/common.sh # 应用专用函数库 -. /usr/local/bin/environment.sh # 设置环境变量 - -LOG_I "** Processing init.sh **" - -trap "${APP_NAME}_stop_server" EXIT - -${APP_NAME}_verify_minimum_env - -# 执行应用预初始化操作 -${APP_NAME}_custom_preinit - -# 执行应用初始化操作 -${APP_NAME}_default_init - -# 执行用户自定义初始化脚本 -${APP_NAME}_custom_init - -LOG_I "** Processing init.sh finished! **" diff --git a/customer/usr/local/bin/run.sh b/customer/usr/local/bin/run.sh index 67a2d22..91a0cdc 100755 --- a/customer/usr/local/bin/run.sh +++ b/customer/usr/local/bin/run.sh @@ -1,29 +1,24 @@ #!/bin/bash -# Ver: 1.3 by Endial Fang (endial@126.com) +# Ver: 1.5 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:-${APP_NAME}})" +# 配置默认启动参数(应用配置文件、前台方式启动) +flags=() +[[ -n "${APP_CONF_FILE:-}" ]] && flags+=("-c" "${APP_CONF_FILE}") +[[ -n "${APP_EXTRA_FLAGS:-}" ]] && flags+=("${APP_EXTRA_FLAGS[@]}") +flags+=("$@") -readonly START_COMMAND="$(command -v ${APP_EXEC})" - -# 确保应用运行在前台 -flags=("-c" "${APP_CONF_FILE:-}") -[[ -z "${APP_EXTRA_FLAGS:-}" ]] || flags=("${flags[@]}" "${APP_EXTRA_FLAGS[@]}") -# 增加 "@" 以使用用户在命令行添加的扩展标识 -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[@]}" diff --git a/customer/usr/local/bin/setup.sh b/customer/usr/local/bin/setup.sh index dae4a3b..065da69 100755 --- a/customer/usr/local/bin/setup.sh +++ b/customer/usr/local/bin/setup.sh @@ -1,38 +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" - -# 解决使用non-root后,nginx: [emerg] open() "/dev/stdout" failed (13: Permission denied) -LOG_D "Change permissions of stdout/stderr to 0622" +# 解决使用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 - -LOG_I "** Processing setup.sh finished! **" diff --git a/customer/usr/local/nginx/etc/nginx/conf.d/default.conf b/customer/usr/local/nginx/etc/nginx/conf.d/default.conf index dbc72ed..47ab384 100644 --- a/customer/usr/local/nginx/etc/nginx/conf.d/default.conf +++ b/customer/usr/local/nginx/etc/nginx/conf.d/default.conf @@ -2,13 +2,15 @@ server { listen 8080; server_name localhost; - #access_log /var/log/nginx/default.access.log main; - #error_log /var/log/nginx/default.access.log warn; + charset utf-8; + + access_log /srv/nginx/log/default.access.log main; + error_log /srv/nginx/log/default.error.log warn; location / { root /usr/local/nginx/html; index index.html index.htm index.php; - autoindex on; + autoindex on; } #error_page 404 /404.html; diff --git a/customer/usr/local/nginx/etc/nginx/nginx.conf b/customer/usr/local/nginx/etc/nginx/nginx.conf index 184b974..62814fa 100644 --- a/customer/usr/local/nginx/etc/nginx/nginx.conf +++ b/customer/usr/local/nginx/etc/nginx/nginx.conf @@ -1,26 +1,30 @@ # /etc/nginx/nginx.conf -# 针对当前已使用 nginx 用户的 Docker 镜像使用时,不需要定义用户 -#user nginx; +# 针对 Docker 镜像使用时,使用预定义的用户 +# user nginx; # 关闭守护进程模式。如果设置为后台守护进程模式,容器在启动应用后会退出 daemon off; -# 根据 CPU 核心数设置进程数量 +# 根据 CPU 核心数设置进程数量并开启CPU亲和机制 worker_processes auto; +worker_cpu_affinity auto; # 手动设置进程数量。子进程个数最好跟CPU的核心数一样 -#worker_processes 8; +# worker_processes 8; # 手动绑定子进程与 CPU 核心,避免进程切换造成性能损失 -#worker_cpu_affinity 0001 0010 0100 1000 0011 0110 1100 1001; +# worker_cpu_affinity 0001 0010 0100 1000 0011 0110 1100 1001; -# Enables the use of JIT for regular expressions to speed-up their processing. +# 启用 JIT 以加速正则表达式处理 pcre_jit on; # 配置默认的日志输出方式。可以为日志文件或标准输出设备,日志文件路径固定不可修改 # 输出级别:notice / info / warn / error / 为空 -#error_log /var/log/nginx/error.log warn; -#error_log /dev/stdout warn; +# error_log /srv/nginx/log/error.log warn; +# error_log /srv/nginx/log/error.log info; +# error_log /srv/nginx/log/error.log notice; +# error_log /srv/nginx/log/error.log; +# error_log /dev/stdout warn; # 包含配置文件,以加载动态模块 include /usr/local/nginx/modules/*.conf; @@ -31,50 +35,57 @@ pid /var/run/nginx/nginx.pid; worker_rlimit_nofile 32767; events { + # 使用 epoll 模型 use epoll; # 设置一个进程可以打开的最大并发链接数量 - worker_connections 10240; + worker_connections 20480; } http { # 如果启用Ruby支持,需要编译支持Ruby的版本,在这里配置启用对应版本的Passenger - #passenger_root /usr/local/rvm/gems/ruby-2.1.3/gems/passenger-4.0.57; - #passenger_ruby /usr/local/rvm/gems/ruby-2.1.3/wrappers/ruby; + # passenger_root /usr/local/rvm/gems/ruby-2.1.3/gems/passenger-4.0.57; + # passenger_ruby /usr/local/rvm/gems/ruby-2.1.3/wrappers/ruby; # 包含扩展名与类型映射定义 MIME 文件,并定义默认使用的类型 - include /srv/conf/nginx/mime.types; + include /srv/nginx/conf/mime.types; default_type application/octet-stream; charset UTF-8; - # Sendfile copies data between one FD and other from within the kernel, - # which is more efficient than read() + write(). + # 开启零拷贝机制 sendfile on; - # Don't buffer data-sends (disable Nagle algorithm). - # Good for sending frequent small bursts of data in real time. + # 不缓存直接发送(禁用Nagle算法),一般用于开启了长连接的情况下使用 + # 用于对响应速度要求较高的场景,如IM、金融等 tcp_nodelay on; - # Causes nginx to attempt to send its HTTP response head in one packet, - # instead of using partial frames. - #tcp_nopush on; + # 拼包后发送(一个MTU或超时),与 tcp_nodelay 互斥,且需要配合 sendfile 使用 + # 用于对吞吐量要求比较高的场景,如调度、报表等 + # tcp_nopush on; - # Don't tell nginx version to clients. + # 对客户端隐藏服务器版本 server_tokens off; - # Specifies the maximum accepted body size of a client request, as - # indicated by the request header Content-Length. If the stated content - # length is greater than this size, then the client receives the HTTP - # error code 413. Set to 0 to disable. + # 客户端上传文件大小限制,超出时返回错误代码 413。 + # 默认值:1m;设置为 0 时禁用该限制 client_max_body_size 1024m; # Name servers used to resolve names of upstream servers into addresses. # It's also needed when using tcpsocket and udpsocket in Lua modules. - #resolver 208.67.222.222 208.67.220.220; + # resolver 208.67.222.222 208.67.220.220; - # Timeout for keep-alive connections. Server will close connections after - # this time. - keepalive_timeout 65; + # 优化服务器域名散列表 + server_names_hash_bucket_size 64; + server_names_hash_max_size 2048; + + # 连接超时时间,默认值:65秒 + keepalive_timeout 60; + + # 读取客户端请求头超时时间,默认值:60秒 + client_header_timeout 15; + + # 读取客户端请求体超时时间,默认值:60秒 + client_body_timeout 30; proxy_buffer_size 128k; proxy_buffering on; @@ -86,7 +97,7 @@ http { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Path of the file with Diffie-Hellman parameters for EDH ciphers. - #ssl_dhparam /etc/ssl/nginx/dh2048.pem; + # ssl_dhparam /etc/ssl/nginx/dh2048.pem; # Specifies that our cipher suits should be preferred over client ciphers. ssl_prefer_server_ciphers on; @@ -110,10 +121,10 @@ http { gzip_types text/plain text/css text/xml application/javascript application/json application/rss+xml; # Enable checking the existence of precompressed files. - #gzip_static on; + # gzip_static on; # 定义日志格式 - #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; log_format main '{"time_local": "$time_local", ' @@ -129,20 +140,16 @@ http { '"body_bytes_sent": "$body_bytes_sent", ' '"request_time": "$request_time", ' '"http_referrer": "$http_referer" }'; - - # 设置日志输出的路径、格式 - #access_log /var/log/nginx/access.log main; - #error_log /var/log/nginx/error.log warn; - access_log /dev/stdout main; - #error_log /dev/stdout warn; - - # 关闭日志输出,提升性能 - #access_log /dev/null; - #error_log /dev/null; + # 设置日志输出的路径、格式 + # access_log /srv/nginx/log/access.log main; + # error_log /srv/nginx/log/error.log warn; + access_log /dev/stdout main; + error_log /dev/stdout warn; + # 包含虚拟服务器定义配置文件 - include /srv/conf/nginx/conf.d/*.conf; + include /srv/nginx/conf/conf.d/*.conf; } # 包含其它类型服务配置文件,如 RTMP -include /srv/conf/nginx/services/*.conf; +include /srv/nginx/conf/services/*.conf; diff --git a/customer/usr/local/nginx/etc/nginx/services/readme.md b/customer/usr/local/nginx/etc/nginx/services/readme.md index 03b2878..a5c14d2 100644 --- a/customer/usr/local/nginx/etc/nginx/services/readme.md +++ b/customer/usr/local/nginx/etc/nginx/services/readme.md @@ -1,2 +1,13 @@ # 其他类型的服务定义文件 -# 文件名默认为:.conf \ No newline at end of file +# 文件名默认为:.conf + +# 优化作为代理服务时的长连接配置,减少握手次数,降低服务器损耗 + +upstream xxx { + # 长连接数 + keepalive 32; + # 每个长连接提供的最大请求数 + keepalived_requests 100; + # 每个长连接没有新的请求时,保持的最长时间 + keepalive_timeout 60s; +} \ No newline at end of file