411

I'm using docker-compose to create my development environment. I want to build a specific image, but I don't know how to set a name for that image.

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

When I execute docker-compose everything is ok, but I get a random name for the new image. Is it possible to set a name to the build image?

NikolaiDante
  • 18,469
  • 14
  • 77
  • 117
Robert
  • 10,403
  • 14
  • 67
  • 117
  • 49
    If you're using docker-compose to build the image, the image name is always going to be `_`, where `` in this example is `wildfly` and project defaults to the directory name you're in. You can change that with `-p` or `COMPOSE_PROJECT_NAME` environment variable. There is no way to set a custom image name. – dnephin Aug 27 '15 at 17:16
  • 2
    are there no acceptable answers? – AmanicA Mar 09 '16 at 05:00
  • https://docs.docker.com/docker-cloud/apps/service-links/ - official document about this subject – Ivan Aracki Jun 14 '18 at 10:56
  • 10
    you can also set `COMPOSE_PROJECT_NAME=x` in `.env` and your containers will be called `{x}_{service}_{#}` – eMPee584 Dec 19 '18 at 16:07
  • 1
    __NOTICE:__ Because Docker container names must be unique, you cannot scale a service beyond 1 container if you have specified a custom name. Attempting to do so results in an error. [documentation](https://docs.docker.com/compose/compose-file/compose-file-v3/#container_name) – aderchox Nov 10 '21 at 05:59

12 Answers12

297

For docker-compose version 2 file format, you can build and tag an image for one service and then use that same built image for another service.

For my case, I want to set up an elasticsearch cluster with 2 nodes, they both need to use the same image, but configured to run differently. I also want to build my own custom elasticsearch image from my own Dockerfile. So this is what I did (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

You can see that in the first service definition es-master, I use the build option to build an image from the Dockerfile in ./elasticsearch. I tag the image with the name porter/elasticsearch with the image option.
Then, I reference this built image in the es-node service definition with the image option, and also use a depends_on to make sure the other container es-master is built and run first.

Nickofthyme
  • 3,032
  • 23
  • 40
Jason White
  • 4,462
  • 4
  • 23
  • 23
  • 96
    The option `container_name:` really helped. – Bruno Bieri Oct 07 '16 at 08:21
  • 4
    Are you sure this works? `build` and `image` are mutually exclusive. I get "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 Mar 01 '17 at 15:21
  • 5
    Oh, never mind. Those two can be used together in the v2 format and onwards. The thing I was testing didn't specify a version so I guess was assumed to be v1. – Burhan Ali Mar 01 '17 at 15:37
  • 4
    The option container_name: really helped me thks – lanni654321 Jun 01 '17 at 09:36
  • 1
    container_name: you_win :) – Muzafar Ali Sep 12 '17 at 20:43
  • @BrunoBieri what is with `container_name`? What does that have to do with one service reusing the image of another? – blueFast Mar 15 '18 at 05:54
  • @dangonfast with the `container_name` you can specify a containers name within a docker compose file and influence how the named. This allows you to use it as `depends_on` names. For more information read here: https://docs.docker.com/compose/compose-file/#container_name – Bruno Bieri Mar 15 '18 at 10:20
  • 3
    @BrunoBieri the `depends_on` uses the name of the service in the `doker-compose` file, no need to specify a container name. Even the example shows it `depends_on: es-master` and not `depends_on: es_master` – blueFast Mar 15 '18 at 10:31
  • It seems the `environment` is not inheriting to the *sub-services* (***`version: '3.8'`***) – JPG Nov 12 '20 at 19:17
  • 1
    indeed we can use `build` and `image` together, docker compose will name the new image with the value of `image` option. but there's a side effect --> it always trying to "pull" the image first(which doesn't exists because it's a custom name), then print error, I tried to remove the `image` option, the "pull" action is gone and there's no error anymore. do you guys met this error too? – Willis Sep 26 '22 at 17:04
  • @Willis did you manage to fix this error? i am getting the same one – liam Nov 18 '22 at 09:53
  • @liam No, just leave it, it doesn't affect normal use, maybe that's normal action. – Willis Nov 20 '22 at 08:04
105

As per docker-compose 1.6.0:

You can now specify both a build and an image key if you're using the new file format. docker-compose build will build the image and tag it with the name you've specified, while docker-compose pull will attempt to pull it.

So your docker-compose.yml would be

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

To update docker-compose

sudo pip install -U docker-compose==1.6.0
Gediminas Masaitis
  • 3,172
  • 14
  • 35
arulraj.net
  • 4,579
  • 3
  • 36
  • 37
  • 1
    ERROR: Validation failed, reason(s): cornsoup has both an image and build path specified. A service can either be built to image or use an existing image, not both. (docker-compose 1.6.2) – zx1986 Mar 16 '16 at 06:55
  • @zx1986 for that you have to use new version of docker-compose.yml file refer this https://docs.docker.com/compose/compose-file/#upgrading Based on that updated my answer – arulraj.net Mar 16 '16 at 07:23
80

Option 1: Hinting default image name

The name of the image generated by docker-compose depends on the folder name by default but you can override it by using --project-name argument:

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

Option 2: Specifying image name

Once docker-compose 1.6.0 is out, you may specify build: and image: to have an explicit image name (see arulraj.net's answer).

Option 3: Create image from container

A third is to create an image from the container:

$ docker-compose up -d bar
$ docker commit $(docker-compose ps -q bar) foo_bar
$ docker-compose rm -f bar
Community
  • 1
  • 1
Wernight
  • 36,122
  • 25
  • 118
  • 131
  • 3
    `--project-name` does not seem to be accepted anymore. Using 1.23.2 – Steven Vachon May 28 '19 at 13:12
  • 1
    @StevenVachon According to the docs, `--project-name` should work, but their examples use `-p`: https://docs.docker.com/compose/reference/overview/#use--p-to-specify-a-project-name – James Douglas Oct 08 '20 at 09:39
  • 2
    --project-name was removed. You can use the env ```COMPOSE_PROJECT_NAME=foo docker-compose up``` – viphak Mar 16 '21 at 18:12
  • I recently updated docker-compose (from 1.25.0 to 2.14.0) and the name changed from `PROJECT_NAME_IMAGE` to `PROJECT_NAME-IMAGE`. The underscore -> hyphen can be tricky to see (and explains why only old images are starting...) – lesurp Dec 14 '22 at 12:51
36

According to 3.9 version of Docker compose, you can use image: myapp:tag to specify name and tag.

version: "3.9"
services:
  webapp:
    build:
      context: .
      dockerfile: Dockerfile
    image: webapp:tag

Reference: https://docs.docker.com/compose/compose-file/compose-file-v3/

Muhammad Tariq
  • 3,318
  • 5
  • 38
  • 42
  • 1
    Yep, this works as long as you have a build statement. It kinda sucks that you just can't say image: nginx:latest image-name: fred – blissweb Dec 05 '21 at 06:44
33

Depending on your use case, you can use an image which has already been created and specify it's name in docker-compose.

We have a production use case where our CI server builds a named Docker image. (docker build -t <specific_image_name> .). Once the named image is specified, our docker-compose always builds off of the specific image. This allows a couple of different possibilities:

1- You can ensure that where ever you run your docker-compose from, you will always be using the latest version of that specific image.

2- You can specify multiple named images in your docker-compose file and let them be auto-wired through the previous build step.

So, if your image is already built, you can name the image with docker-compose. Remove build and specify 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
meoww-
  • 1,892
  • 2
  • 21
  • 29
14

after you build your image do the following:

docker tag <image id> mynewtag:version

after that you will see your image is no longer named <none> when you go docker images.

GHETTO.CHiLD
  • 3,267
  • 1
  • 22
  • 34
3

you can customize the image name to build & container name during docker-compose up for this, you need to mention like below in the docker-compose.yml file. It will create an image & container with custom names.

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
2

sudo docker-compose -p <project_name> build

assigns project name

Note: '-p' option comes before 'build' in the command

Ref: https://docs.docker.com/compose/reference/

mira
  • 27
  • 7
1

I did this:

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

The docker-compose app runs with a container name: docker-compose-employees

And an image called [Docker-Hub-Username]/docker-compose:latest

Cyebukayire
  • 795
  • 7
  • 14
1

in docker-compose.yml, add image: "YOUR-DESIRED-NAME" line in your service e.g. if your service name is wildfly and you want to name your image as wildfly_img

wildfly:
  image: wildfly_img
ajay_full_stack
  • 494
  • 7
  • 13
0

If you specify image as well as build, then Compose names the built image with the webapp and optional tag specified in image:

image: webapp:tag

in the docker-compose file, it looks like.

version: '3.9'
services:
  
  node-ecom:
    build: .
    image: "webapp:tag"
    container_name: node-ecom
    ports:
      - "4000:3000"
    volumes:
      - ./:/app:ro
      - /app/node_modules
      - /config/.env
    env_file:
      - ./config/.env
MD SHAYON
  • 7,001
  • 45
  • 38
0

If Jenkins is used the project-name can be defined using stackName = prefix.

jenkins:

stackName = 'foo'

docker:

services:
  bar:

So the name becomes foo_bar.

kometen
  • 6,536
  • 6
  • 41
  • 51