How do I define the name of image built with docker-compose
Asked Answered
L

12

427

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?

Lightheaded answered 26/8, 2015 at 15:21 Comment(5)
If you're using docker-compose to build the image, the image name is always going to be <project>_<service>, where <service> 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.Chloral
are there no acceptable answers?Detection
docs.docker.com/docker-cloud/apps/service-links - official document about this subjectPinkston
you can also set COMPOSE_PROJECT_NAME=x in .env and your containers will be called {x}_{service}_{#}Fecund
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. documentationLoar
C
311

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.

Setting the name constrains scaling.

Conductive answered 26/2, 2016 at 21:35 Comment(12)
The option container_name: really helped.Moneylender
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."Gurley
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.Gurley
The option container_name: really helped me thksEmasculate
container_name: you_win :)Dogmatist
@BrunoBieri what is with container_name? What does that have to do with one service reusing the image of another?Gawky
@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: docs.docker.com/compose/compose-file/#container_nameMoneylender
@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_masterGawky
It seems the environment is not inheriting to the sub-services (version: '3.8')Whitcomb
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?Sapir
@Sapir did you manage to fix this error? i am getting the same oneLeeuwenhoek
@Leeuwenhoek No, just leave it, it doesn't affect normal use, maybe that's normal action.Sapir
J
108

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
Judgeship answered 27/11, 2015 at 6:49 Comment(2)
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)Glomerule
@Glomerule for that you have to use new version of docker-compose.yml file refer this docs.docker.com/compose/compose-file/#upgrading Based on that updated my answerJudgeship
G
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
Gat answered 2/2, 2016 at 16:26 Comment(4)
--project-name does not seem to be accepted anymore. Using 1.23.2Strophanthus
@StevenVachon According to the docs, --project-name should work, but their examples use -p: docs.docker.com/compose/reference/overview/…Stander
--project-name was removed. You can use the env COMPOSE_PROJECT_NAME=foo docker-compose upBoito
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...)Kaycekaycee
R
39

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/

Rosenarosenbaum answered 29/1, 2021 at 19:48 Comment(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: fredMiyokomizar
H
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
Hassett answered 27/8, 2015 at 22:18 Comment(0)
B
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.

Broody answered 26/8, 2015 at 15:55 Comment(4)
Is possible to specify the tags with docker-compose?Lightheaded
tags do not look to be supported at this time.Broody
So I have to build the image and later re-tag it? Is not really useful, I hope the docker-compose fix this problem quickly?Lightheaded
if you are building a multi container environment yes. if you are building a single container environment you can always go docker build -t mytag:version .Broody
P
4

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
Photoelectrotype answered 24/1, 2022 at 19:58 Comment(1)
container_name is what i was looking forHeadword
A
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/

Ahmedahmedabad answered 18/6, 2021 at 6:35 Comment(0)
S
2

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
Straphanger answered 10/11, 2022 at 16:38 Comment(0)
L
1

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
Lanneret answered 30/11, 2021 at 11:30 Comment(0)
W
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

Wheal answered 11/3, 2022 at 6:0 Comment(0)
T
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.

Tole answered 30/3, 2022 at 7:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.