Docker部署Elixir应用无法连接AWS Aurora Postgres求助
部署Docker容器化的Elixir应用后,调用API返回如下错误:
{ errors: { detail: "Internal Server Error" } }
查看容器日志docker logs [CONTAINER_ID],发现核心数据库连接异常:
18:21:26.695 [error] Postgrex.Protocol (#PID<0.487.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (postgres:5432): non-existing domain - :nxdomain
同时伴随连接池耗尽的提示,但根源为无法解析数据库域名。已知AWS Aurora可通过pgAdmin正常连接,相关Docker配置及启动命令如下:
Dockerfile
# base image elixer to start with FROM elixir:1.13.4 # install hex package manager RUN mix local.hex --force RUN curl -o phoenix_new.ez https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez RUN mix archive.install ./phoenix_new.ez RUN mkdir /app COPY . /app WORKDIR /app ENV MIX_ENV=prod ENV PORT=4000 ENV DATABASE_URL=postgres://[URL] RUN mix local.rebar --force RUN mix deps.get --only prod RUN mix compile RUN mix phx.digest CMD mix phx.server
构建&启动命令
docker build . -t [name] docker run --name [name] -p 4000:4000 -d [name]
从日志的nxdomain错误可明确:容器内无法解析数据库域名(日志显示尝试连接postgres:5432,说明实际生效的数据库地址并非预期的AWS Aurora端点),按以下步骤排查修复:
1. 验证容器内实际生效的DATABASE_URL
Dockerfile中硬编码的ENV DATABASE_URL可能存在配置错误,或被代码内其他配置覆盖。通过以下命令确认容器内的环境变量:
docker exec -it [CONTAINER_NAME] env | grep DATABASE_URL
若输出不是AWS Aurora的完整端点(格式类似xyz.cluster-xxxx.us-east-1.rds.amazonaws.com),说明环境变量未正确设置。
2. 动态传递数据库配置,避免镜像硬编码
镜像应保持通用性,不要将敏感/动态配置写入镜像。删除Dockerfile中的ENV DATABASE_URL=postgres://[URL]行,改为在启动容器时通过-e参数传递:
docker run --name [name] -p 4000:4000 -e DATABASE_URL=postgres://your-aurora-endpoint:5432/dbname?user=xxx&password=xxx -d [name]
3. 检查网络连通性
即使DATABASE_URL正确,容器可能因网络策略无法访问AWS Aurora:
- 确认AWS Aurora的安全组规则,允许容器所在IP(公网IP或VPC内网IP,依部署环境而定)访问5432端口
- 在容器内测试连通性:
# 测试域名解析 docker exec -it [CONTAINER_NAME] ping your-aurora-endpoint # 测试端口连通性 docker exec -it [CONTAINER_NAME] nc -zv your-aurora-endpoint 5432
若测试失败,重点排查AWS安全组、NACLs,以及容器网络模式(默认桥接模式是否具备公网访问权限)。
4. 修复DNS解析问题
若本地可访问Aurora但容器内无法解析,说明容器DNS配置异常:
- 查看容器DNS配置:
docker exec -it [CONTAINER_NAME] cat /etc/resolv.conf
- 启动容器时指定可靠DNS服务器(如公共DNS或AWS VPC DNS):
docker run --name [name] -p 4000:4000 --dns 8.8.8.8 -e DATABASE_URL=... -d [name]
5. 连接池配置优化(次要)
日志中的连接池耗尽提示是因数据库连接失败导致池内无有效连接,解决上述核心问题后,可根据业务需求调整config/prod.exs中的连接池参数:
config :your_app, YourApp.Repo, pool_size: 10, queue_target: 5000, queue_interval: 1000
内容的提问来源于stack exchange,提问作者Wasif Khalil

