How do I define the name of image built with docker-compose
DockerDocker ComposeOrchestrationDocker Problem Overview
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?
Docker Solutions
Solution 1 - Docker
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.
Solution 2 - Docker
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
Solution 3 - Docker
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
Solution 4 - Docker
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
Solution 5 - Docker
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/
Solution 6 - Docker
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
.
Solution 7 - Docker
sudo docker-compose -p
assigns project name
Note: '-p' option comes before 'build' in the command
Solution 8 - Docker
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
Solution 9 - Docker
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
Solution 10 - Docker
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
Solution 11 - Docker
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
.