加载.env文件失败但环境变量仍可用的原因排查
问题
在Go项目中通过godotenv加载.env文件时,出现了“open .env: no such file or directory”的错误,但执行docker-compose up --build server命令后服务仍能正常运行,环境变量也已正确设置。请问该现象的原因是什么?
加载环境变量的代码片段
// init executes the initial configuration. func init() { // loads the file for env. variables if err := godotenv.Load(".env"); err != nil { log.Printf("failed to load env file: %v\n", err) } // env variables are set based values within the .env file. os.Setenv("dbname", os.Getenv("DB_NAME")) os.Setenv("username", os.Getenv("DB_USERNAME")) os.Setenv("pw", os.Getenv("DB_PASSWORD")) os.Setenv("dbport", os.Getenv("DB_PORT")) os.Setenv("server_port", os.Getenv("SERVER_PORT")) os.Setenv("hostname", os.Getenv("DB_CONTAINER_NAME")) }
运行时错误信息
server_1 | 2022/09/07 11:44:06 failed to load env file: open .env: no such file or directory
docker-compose.yml配置
version: '3.8' services: db: image: postgres:14.1-alpine container_name: ${DB_CONTAINER_NAME} restart: always environment: - POSTGRES_DB=${DB_NAME} - POSTGRES_USER=${DB_USERNAME} - POSTGRES_PASSWORD=${DB_PASSWORD} ports: - ${DB_PORT}:${DB_PORT} env_file: - .env volumes: - db:/var/lib/postgresql/data - ./psql/statements/create-tables.sql:/docker-entrypoint-initdb.d/create_table.sql server: build: context: . dockerfile: Dockerfile env_file: .env depends_on: - ${DB_CONTAINER_NAME} networks: - default ports: - ${SERVER_PORT}:${SERVER_PORT} volumes: db: driver: local
Dockerfile内容
FROM golang:1.18 WORKDIR /src COPY go.sum go.mod ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o /bin/app . FROM alpine COPY --from=0 /bin/app /bin/app ENTRYPOINT ["/bin/app"]
原因分析
- 容器内不存在.env文件:你的Dockerfile采用多阶段构建,最终的alpine镜像只复制了编译好的二进制文件
/bin/app,没有将项目根目录的.env文件复制到容器中。godotenv尝试加载当前路径下的.env时自然找不到文件,因此抛出错误。 - docker-compose已提前注入环境变量:在
docker-compose.yml的server服务中配置了env_file: .env,docker-compose会自动将宿主机上的.env文件中的变量注入到容器的环境变量中。所以即使godotenv加载失败,os.Getenv("DB_NAME")这类调用依然能读取到已经存在的环境变量值。 - 加载失败不终止程序执行:代码中仅用
log.Printf打印了godotenv加载失败的错误,没有触发panic或终止程序的逻辑。后续的os.Setenv操作能正常获取到docker-compose注入的变量,因此服务可以正常启动并运行。
内容的提问来源于stack exchange,提问作者tassador
相关产品推荐
相关产品推荐

