如何定义使用docker-compose构建的镜像名称

419

我正在使用docker-compose创建我的开发环境。我想要构建一个特定的镜像,但是我不知道如何为该镜像设置名称。

wildfly:
  build: /path/to/dir/Dockerfile
  container_name: wildfly_server
  ports:
   - 9990:9990
   - 80:8080
  environment:
   - MYSQL_HOST=mysql_server
   - MONGO_HOST=mongo_server
   - ELASTIC_HOST=elasticsearch_server
  volumes:
   - /Volumes/CaseSensitive/development/wildfly/deployments/:/opt/jboss/wildfly/standalone/deployments/
  links:
   - mysql:mysql_server
   - mongo:mongo_server
   - elasticsearch:elasticsearch_server

我执行docker-compose时一切正常,但新镜像的名称是随机的。是否可以为构建的镜像设置名称?


49
如果你使用docker-compose构建镜像,那么镜像名称始终将是<project>_<service>,其中<service>在此示例中为“wildfly”,而项目默认为您所在的目录名称。您可以使用-pCOMPOSE_PROJECT_NAME环境变量更改它。但是无法设置自定义镜像名称。 - dnephin
2
没有可接受的答案吗? - AmanicA
https://docs.docker.com/docker-cloud/apps/service-links/ - 关于此主题的官方文档 - Ivan Aracki
10
您可以在.env文件中设置COMPOSE_PROJECT_NAME=x,这样您的容器将被命名为{x}_{service}_{#} - eMPee584
1
注意:由于 Docker 容器名称必须唯一,如果您指定自定义名称,则无法将服务扩展到超过 1 个容器。尝试这样做会导致错误。文档链接 - aderchox
12个回答

305

对于docker-compose 2版本的文件格式,您可以为一个服务构建和标记一个镜像,然后将该构建好的镜像用于另一个服务。

对于我的情况,我想设置一个有两个节点的elasticsearch集群,它们都需要使用相同的镜像,但配置不同。我还想从自己的Dockerfile构建自己的自定义elasticsearch镜像。所以我做了以下操作(docker-compose.yml):

version: '2'

services:
  es-master:
    build: ./elasticsearch
    image: porter/elasticsearch
    ports:
      - "9200:9200"
    container_name: es_master

  es-node:
    image: porter/elasticsearch
    depends_on:
      - es-master
    ports:
      - "9200"
    command: elasticsearch --discovery.zen.ping.unicast.hosts=es_master

在第一个服务定义es-master中,您可以看到我使用build选项从./elasticsearch的Dockerfile构建映像。我使用image选项将该映像命名为porter/elasticsearch
然后,在es-node服务定义中,我使用image选项引用了这个构建好的映像,并使用depends_on确保先构建和运行另一个容器es-master


98
container_name: 选项确实很有帮助。 - Bruno Bieri
4
你确定这个可行吗?buildimage是相互排斥的。我收到了"Service xxx has both an image and build path specified. A service can either be built to image or use an existing image, not both."的错误提示。 - Burhan Ali
5
哦,没事了。在v2格式及以后的版本中,这两个可以一起使用。我当时测试的东西没有指定版本,所以大概默认是v1。 - Burhan Ali
4
"container_name" 这个选项确实帮了我,谢谢。 - lanni654321
3
@BrunoBieri depends_ondocker-compose 文件中使用服务的名称,不需要指定容器名称。即使示例也是这样显示的:depends_on: es-master 而不是 depends_on: es_master - blueFast
显示剩余7条评论

108
根据 docker-compose 1.6.0 版本更新:

如果你使用新的文件格式,现在可以同时指定构建和映像键。 docker-compose build 将构建镜像并打上你指定的名称标签,而 docker-compose pull 将会尝试拉取它。

因此,你的 docker-compose.yml 文件应该是:

version: '2'
services:
  wildfly:
      build: /path/to/dir/Dockerfile
      image: wildfly_server
      ports:
       - 9990:9990
       - 80:8080

更新docker-compose

sudo pip install -U docker-compose==1.6.0

1
错误:验证失败,原因: cornsoup同时指定了图像和构建路径。服务可以构建为镜像或使用现有镜像,但不能同时存在。(docker-compose 1.6.2) - zx1986
@zx1986,你需要使用新版本的docker-compose.yml文件,请参考此链接https://docs.docker.com/compose/compose-file/#upgrading。根据更新内容修改我的答案。 - arulraj.net

80

选项1:指定默认图像名称

docker-compose生成的镜像名称默认使用文件夹名称,但您可以通过使用 --project-name 参数来覆盖它:

$ docker-compose --project-name foo build bar
$ docker images foo_bar

选项2:指定镜像名称

一旦docker-compose 1.6.0发布,您可以指定build:image:来设置显式的镜像名称(请参见arulraj.net的答案)。

选项3:从容器创建镜像

第三种方法是从容器中创建一个镜像:

$ docker-compose up -d bar
$ docker commit $(docker-compose ps -q bar) foo_bar
$ docker-compose rm -f bar

3
“--project-name” 似乎不再被接受。正在使用1.23.2版本。 - Steven Vachon
1
根据文档,--project-name 应该可以工作,但他们的示例使用 -p:https://docs.docker.com/compose/reference/overview/#use--p-to-specify-a-project-name - James Douglas
2
--project-name已被移除。您可以使用env COMPOSE_PROJECT_NAME=foo docker-compose up - viphak
我最近更新了docker-compose(从1.25.0到2.14.0),名称从PROJECT_NAME_IMAGE更改为PROJECT_NAME-IMAGE。下划线变成连字符可能很难看出来(这也解释了为什么只有旧镜像在启动...)。 - lesurp

36

1
没错,只要你有一个构建语句,这就可以工作。很遗憾,你不能只说镜像:nginx:latest 镜像名称:fred。 - blissweb

33
根据您的使用情况,您可以使用已创建的图像,并在docker-compose中指定其名称。我们有一个生产用例,其中CI服务器构建了一个命名的Docker镜像(docker build -t <specific_image_name> .)。一旦指定了命名的镜像,我们的docker-compose始终从特定镜像构建。这允许几种不同的可能性:1- 您可以确保无论从哪里运行您的docker-compose,您始终使用该特定图像的最新版本。2- 您可以在docker-compose文件中指定多个命名图像,并让它们通过上一个构建步骤自动连接。因此,如果您的图像已经构建完成,您可以使用docker-compose为其命名。删除build并指定image:
wildfly:
  image: my_custom_wildfly_image
  container_name: wildfly_server
  ports:
   - 9990:9990
   - 80:8080
  environment:
   - MYSQL_HOST=mysql_server
   - MONGO_HOST=mongo_server
   - ELASTIC_HOST=elasticsearch_server
  volumes:
   - /Volumes/CaseSensitive/development/wildfly/deployments/:/opt/jboss/wildfly/standalone/deployments/
  links:
   - mysql:mysql_server
   - mongo:mongo_server
   - elasticsearch:elasticsearch_server

14

构建完镜像,执行以下操作:

docker tag <镜像id> mynewtag:版本号

然后您会发现当您执行 docker images 时,您的镜像将不再显示为 <none>


7
可以使用docker-compose指定标签吗? - Robert
目前看起来不支持标签。 - GHETTO.CHiLD
2
那么我必须先构建这个镜像,然后重新打标签吗?这并不是很方便,希望docker-compose能够快速解决这个问题。 - Robert
1
如果您正在构建多容器环境,则是的。如果您正在构建单容器环境,则可以始终使用 docker build -t mytag:version . - GHETTO.CHiLD

3

在docker-compose up期间你可以自定义镜像名称和容器名称,你需要在docker-compose.yml文件中如下指定以生成带有自定义命名的镜像和容器。

version: '3'
services:
  frontend_dev:
    stdin_open: true
    environment:
      - CHOKIDAR_USEPOLLING=true
    build:
      context: .
      dockerfile: Dockerfile.dev
    image: "mycustomname/sample:v1"
    container_name: mycustomname_sample_v1
    ports:
      - '3000:3000'
    volumes:
      - /app/node_modules
      - .:/app

container_name 是我正在寻找的。 - Florent

2
在 docker-compose.yml 文件中,在你的服务下面添加 image: "YOUR-DESIRED-NAME" 行,例如,如果你的服务名为 wildfly,并且你想将你的镜像命名为 wildfly_img
wildfly:
  image: wildfly_img

2

1
我做了这个:
version: '3.8'
services:
  app:
    build: .
    depends_on:
      - postgres
    ports:
      - "8080:8080"
    volumes:
      - ./:/usr/src/app/
    container_name: docker-compose-employees
    image: [Docker-Hub-Username]/docker-compose:latest

docker-compose 应用程序以容器名称 docker-compose-employees 运行。

并使用名为 [Docker-Hub-Username]/docker-compose:latest 的镜像。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接