Docker容器中OpenResty Lua脚本无法读取环境变量的解决方法
解决OpenResty容器中Lua脚本无法读取环境变量的问题
问题根源在于OpenResty的Nginx运行机制:Nginx主进程启动时会清除大部分环境变量,仅保留少数内置变量,导致运行在worker进程中的Lua代码无法通过os.getenv()获取容器层面定义的环境变量。你之前用envsubst处理nginx.conf模板只是替换了配置文件中的占位符,但并没有让这些环境变量暴露给Lua运行时。
下面提供两种可行的解决方案:
方案一:通过Nginx env 指令暴露环境变量
让Nginx主动将指定的环境变量传递给worker进程,这样Lua就能直接用os.getenv()读取。
操作步骤:
- 修改
nginx.conf.template模板,添加env指令声明需要暴露的环境变量:
# nginx.conf.template env REDIS_HOST; env REDIS_PORT; http { server { listen 80; location /test { content_by_lua_file /usr/local/openresty/nginx/lua/test.lua; } } }
- 调整Dockerfile,确保
envsubst处理模板时保留env指令(不需要替换这些指令,仅处理配置中其他需要替换的占位符):
FROM openresty/openresty:alpine # 安装依赖工具 RUN apk add --no-cache bash gettext # 复制配置模板和Lua脚本到容器内 COPY nginx.conf.template /etc/nginx/nginx.conf.template COPY test.lua /usr/local/openresty/nginx/lua/test.lua # 启动脚本:处理配置模板并启动Nginx CMD ["/bin/bash", "-c", "envsubst '${REDIS_HOST} ${REDIS_PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]
- 在
test.lua中直接使用os.getenv()读取变量:
-- test.lua local redis_host = os.getenv("REDIS_HOST") or "default-redis" local redis_port = os.getenv("REDIS_PORT") or "6379" ngx.say("Redis Host: ", redis_host) ngx.say("Redis Port: ", redis_port)
方案二:将环境变量写入Lua配置文件
在容器启动时把环境变量写入一个Lua配置文件,业务Lua脚本通过require加载配置,避免直接依赖环境变量。
操作步骤:
- 修改Dockerfile,添加生成Lua配置模板并替换变量的步骤:
FROM openresty/openresty:alpine RUN apk add --no-cache bash gettext COPY nginx.conf.template /etc/nginx/nginx.conf.template COPY test.lua /usr/local/openresty/nginx/lua/test.lua # 生成Lua配置模板文件 RUN cat > /usr/local/openresty/nginx/lua/lua-config.lua.template <<EOF return { redis_host = "${REDIS_HOST}", redis_port = "${REDIS_PORT}" } EOF # 启动脚本:先生成Lua配置,再处理Nginx配置,最后启动Nginx CMD ["/bin/bash", "-c", "envsubst '${REDIS_HOST} ${REDIS_PORT}' < /usr/local/openresty/nginx/lua/lua-config.lua.template > /usr/local/openresty/nginx/lua/lua-config.lua && envsubst '${REDIS_HOST} ${REDIS_PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]
- 修改
test.lua,通过require加载配置:
-- test.lua local config = require("lua-config") ngx.say("Redis Host: ", config.redis_host or "default-redis") ngx.say("Redis Port: ", config.redis_port or "6379")
Docker Compose 配置(两种方案通用)
version: '3' services: openresty: build: . environment: - REDIS_HOST=redis-server - REDIS_PORT=6379 ports: - "8080:80"
方案对比
- 方案一适合多脚本共享环境变量的场景,无需额外生成配置文件,直接通过Nginx指令传递变量。
- 方案二更灵活,支持统一管理配置,还能添加默认值、复杂配置逻辑,降低Lua脚本对环境变量的直接依赖。
内容的提问来源于stack exchange,提问作者deroccha
相关产品推荐
相关产品推荐

