#!/bin/sh # Select nginx config based on APP_ENV (staging/production). # # 两种运行模式: # 1. CI/CD 部署(staging/production):部署脚本通过 `-v 宿主机文件:/etc/nginx/conf.d/default.conf:ro` # 把宿主机生成的带 resolver/docker upstream 的配置 bind mount 进来,entrypoint 不应改动。 # bind mount 的文件是 readonly 的,rm 会报 EBUSY ("Resource busy"),直接 exec nginx 即可。 # 2. 本地 docker-compose / 直接 `docker run`(无外部挂载):镜像烤入了 nginx-staging.conf 与 # nginx-production.conf 到 /etc/nginx/,entrypoint 根据 APP_ENV 把 default.conf 换成正确的 symlink。 # # 策略: # - 如果 /etc/nginx/conf.d/default.conf 已经是指向目标 conf 的 symlink,什么都不做; # - 否则尝试 rm -f 再 ln -s;rm 失败说明是外部 bind mount(已有正确配置),不阻塞启动; # - 兜底:只要 conf.d 目录里有 .conf 文件(含 bind mount 来的),就直接启动 nginx。 set -e NGINX_CONF_DIR="/etc/nginx/conf.d" TARGET_CONF="" case "${APP_ENV:-production}" in staging) TARGET_CONF="/etc/nginx/nginx-staging.conf" ;; *) TARGET_CONF="/etc/nginx/nginx-production.conf" ;; esac DEFAULT_CONF="$NGINX_CONF_DIR/default.conf" # 1. 已经是正确的 symlink:直接启动 if [ -L "$DEFAULT_CONF" ] && [ "$(readlink "$DEFAULT_CONF" 2>/dev/null)" = "$TARGET_CONF" ]; then exec nginx -g "daemon off;" fi # 2. 尝试替换为目标 symlink(无 bind mount 的场景) # 若 rm 失败(bind mount readonly,EBUSY/EPERM),则认为外部已注入配置,不阻塞。 rm -f "$DEFAULT_CONF" 2>/dev/null || true if [ -f "$TARGET_CONF" ] && [ ! -e "$DEFAULT_CONF" ]; then ln -s "$TARGET_CONF" "$DEFAULT_CONF" 2>/dev/null || true fi # 3. 兜底:至少要有一个 .conf 文件,否则 nginx 起不来 if ! ls "$NGINX_CONF_DIR"/*.conf >/dev/null 2>&1; then echo "ERROR: no nginx config found in $NGINX_CONF_DIR (tried $TARGET_CONF and external bind mount)" >&2 exit 1 fi exec nginx -g "daemon off;"