Docker Compose镜像命名规则及forum-example-graphql拉取失败咨询
我参考《Running PostGraphile in Docker》教程编写了docker-compose.yml文件,执行docker-compose pull && docker-compose up -d命令更新镜像时出现错误:
WARNING: Some service image(s) must be built from source by running:
docker compose build graphql
Error response from daemon: pull access denied for forum-example-graphql, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
但直接执行docker-compose up -d则一切正常。我有以下疑问:
- 以下配置片段中
forum-example-graphql镜像的来源是什么(是否来自Docker Hub)?
graphql: container_name: forum-example-graphql restart: always image: forum-example-graphql build: context: ./graphql env_file: - ./.env depends_on: - db networks: - network ports: - 5433:5433 command: ["--connection", "${DATABASE_URL}", "--port", "5433", "--schema", "public", "--append-plugins", "postgraphile-plugin-connection-filter"]
- 我了解到compose文件中的镜像名基于创建的镜像名,但我并未将本地镜像命名为
forum-example-graphql,本地镜像的命名规则是什么?它与service中image字段的值有何关联? - 另一个postgres服务配置如下,其中
image: postgres:latest无build字段,可直接从Docker Hub拉取镜像,这与上述graphql服务的情况有何差异?
postgres: container_name: postgres image: postgres:latest restart: always volumes: - "./postgres-data:/var/lib/postgresql/data" networks: - network ports: - "5432:5432"
1. forum-example-graphql镜像的来源
这个镜像不是来自Docker Hub。因为你的graphql服务同时配置了image和build字段,Docker Compose的逻辑是:先尝试从镜像仓库拉取image指定的镜像,如果拉取失败(比如这个镜像在Docker Hub不存在),就会使用build字段的配置,从本地./graphql目录的Dockerfile构建镜像,构建完成后会把这个本地镜像打上forum-example-graphql的标签。
你执行docker-compose pull时,Compose会尝试拉取所有服务的镜像,而forum-example-graphql在Docker Hub上不存在,所以会报错;但直接docker-compose up -d时,Compose发现拉取失败,会自动触发构建流程,所以能正常启动。
2. 本地镜像的命名规则与image字段的关联
当你同时配置image和build字段时:
- Docker Compose构建镜像后,会自动给镜像打上
image字段指定的名称作为标签,不需要你手动命名。 - 只要执行过
docker-compose up -d或者docker-compose build graphql,本地就会生成一个名为forum-example-graphql的镜像(就是image字段的值)。 - 你可以用
docker images命令查看本地镜像,就能找到这个标签的镜像。
简单说:image字段在这里就是构建后本地镜像的名称/标签,Compose会自动帮你完成打标操作。
3. postgres服务与graphql服务的差异
两者的核心差异在于是否配置了build字段:
- postgres服务:只有
image: postgres:latest,没有build字段。Compose会直接从Docker Hub拉取官方的postgres:latest镜像,因为这个镜像在公共仓库存在,所以docker-compose pull能正常拉取。 - graphql服务:同时有
image和build字段。Compose优先尝试拉取image指定的镜像,但这个镜像不存在于公共仓库,所以pull失败;而up命令会自动 fallback 到本地构建,所以能正常运行。
内容的提问来源于stack exchange,提问作者Lerner Zhang

