EC2执行docker compose up -d报错,手动构建镜像后可正常运行
在EC2实例中使用以下docker-compose.yaml启动容器时,Redis服务构建阶段报错:
version: "3.9" services: redis: build: context: . ports: - 6379:6379 database: container_name: postgres image: postgres:14.2 ports: - 5432:5432 volumes: - postgres:/var/lib/postgresql/data env_file: - .env volumes: postgres:
Redis对应的Dockerfile:
FROM redis:alpine COPY ./redis.conf /etc/redis.conf CMD ["redis-server", "/etc/redis.conf"]
执行docker compose up -d时出现错误:
=> [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 31B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => ERROR [internal] load metadata for docker.io/library/redis:alpine 0.0s ------ > [internal] load metadata for docker.io/library/redis:alpine: ------ failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to authorize: rpc error: code = Unknown desc = failed to fetch anonymous token: Get "https://auth.docker.io/token?scope=repository%3Alibrary%2Fredis%3Apull&service=registry.docker.io": dial tcp: lookup auth.docker.io on [::1]:53: read udp [::1]:58421->[::1]:53: read: connection refused
但手动执行docker image build -t redis-local .后,再运行docker compose up -d即可正常启动,且该配置在本地机器完全正常。
错误核心是Docker在构建Redis镜像时,无法解析Docker Hub的认证服务器auth.docker.io的域名,请求被发到了本地DNS服务器([::1]:53)但连接被拒绝。而手动执行docker build能成功,说明docker build命令使用的DNS配置与docker-compose构建阶段的DNS配置不一致;手动构建后本地已存在redis:alpine基础镜像,后续docker compose无需再拉取镜像,因此能正常运行。
1. 修复EC2实例的系统DNS配置
检查EC2实例的/etc/resolv.conf文件,确保其中配置的DNS服务器可用。AWS VPC默认提供的DNS服务器是VPC网段的第二个IP(例如VPC网段为10.0.0.0/16时,DNS为10.0.0.2),也可以替换为公共DNS:
nameserver 8.8.8.8 nameserver 8.8.4.4
2. 配置Docker Daemon使用固定DNS
创建或修改/etc/docker/daemon.json文件,添加自定义DNS服务器:
{ "dns": ["8.8.8.8", "8.8.4.4"] }
重启Docker服务使配置生效:
sudo systemctl restart docker
3. 在Docker Compose中指定服务DNS
直接在docker-compose.yaml的Redis服务中添加DNS配置,强制构建阶段使用指定DNS:
services: redis: build: context: . ports: - 6379:6379 dns: - 8.8.8.8 - 8.8.4.4
4. 预拉取基础镜像规避构建问题
如果只是临时解决,可以先手动拉取Redis基础镜像,再执行docker compose up -d:
docker pull redis:alpine
内容的提问来源于stack exchange,提问作者Nullndr

