Docker Compose does not allow to use local images

The following command fails, trying to pull image from the Docker Hub:

$ docker-compose up -d
Pulling web-server (web-server:staging)...
ERROR: repository web-server not found: does not exist or no pull access

But I just want to use a local version of the image, which exists:

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
web-server           staging             b94573990687        7 hours ago         365MB

Why Docker doesn't search among locally stored images?


This is my Docker Compose file:

version: '3'
services:
  chat-server:
    image: chat-server:staging
    ports:
      - "8110:8110"
  web-server:
    image: web-server:staging
    ports:
      - "80:80"
      - "443:443"
      - "8009:8009"
      - "8443:8443"

and my .env file:

DOCKER_HOST=tcp://***.***.**.**:2376
DOCKER_TLS_VERIFY=true 
DOCKER_CERT_PATH=/Users/Victor/Documents/Development/projects/.../target/docker

Solution 1:

In general, this should work as you describe it. Tried to reproduce it, but it simply worked...

Folder structure:

.
├── docker-compose.yml
└── Dockerfile

Content of Dockerfile:

FROM alpine
CMD ["echo", "i am groot"]

Build and tag image:

docker build -t groot .
docker tag groot:latest groot:staging

with docker-compose.yml:

version: '3.1'
services:
  groot:
    image: groot:staging

and start docker-compose:

$ docker-compose up
Creating groot_groot ... 
Creating groot_groot_1 ... done
Attaching to groot_groot_1
groot_1  | i am groot
groot_groot_1 exited with code 0

Solution 2:

In your docker-compose.yml, you can specify build: . instead of build: <username>/repo> for local builds (rather than pulling from docker-hub) - I can't verify this yet, but I believe you may be able to do relative paths for multiple services to the docker-compose file.

services:
  app:
    build: .

Reference: https://github.com/gvilarino/docker-workshop

Solution 3:

March-09-2020 EDIT:

(docker version 18.09.9-ce build 039a7df, dockercompose version 1.24.0, build 0aa59064)

I found that to just create a docker container, you can just docker-compose 'up -d' after tagging the container with a fake local registry server tag (localhost:5000/{image}).

$ docker tag {imagename}:{imagetag} localhost:5000/{imagename}:{imagetag}

You don't need to run the local registry server, but need to change the image url in dockercompose yaml file with the fake local registry server url:

version: '3'
services:
web-server:
  image: localhost:5000/{your-image-name} #change from {imagename}:{imagetag} to localhost:5000/{imagename}:{imagetag}
  ports:
    - "80:80"

from {imagename}:{imagetag} to localhost:5000/{imagename}:{imagetag}

and just up -d

$ docker-compose -f {yamlfile}.yaml up -d 

This creates the container if you already have the image (localhost:5000/{imagename}) in your local machine.


Adding to @Tom Saleeba's response,

I still got errors after tagging the container with "/" (for ex: victor-dombrovsky/docker-image:latest) It kept looking for the image from remote docker.io server.

registry_address/docker-image

It seems the url before "/" is the registry address and after "/" is the image name. and without "/" provided, docker-compose by default looks for the image from the remote docker.io.

It guess it's a known bug with docker-compose

I finally got it working by running the local registry, pushing the image to the local registry with the registry tag, and pulling the image from the local registry.

$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
$ docker tag your-image-name:latest localhost:5000/your-image-name
$ docker push localhost:5000/your-image-name

and then change the image url in the dockerfile:

version: '3'
services:
  chat-server:
    image: chat-server:staging
    ports:
      - "8110:8110"
  web-server:
    image: localhost:5000/{your-image-name} #####change here
    ports:
      - "80:80"
      - "443:443"
      - "8009:8009"
      - "8443:8443"

Similarly for the chat-server image.

Solution 4:

Version >1.23 (2019 and newer)

Easiest way is to change image to build: and reference the Dockerfile in the relative directory, as shown below:

version: '3.0'
services:
  custom_1:
    build:
      context: ./my_dir
      dockerfile: Dockerfile

This allows docker-compose to manage the entire build and image orchestration in a single command.

# Rebuild all images
docker-compose build
# Run system
docker-compose up

Solution 5:

You might need to change your image tag to have two parts separated by a slash /. So instead of

chat-server:staging

do something like:

victor-dombrovsky/chat-server:staging

I think there's some logic behind Docker tags and "one part" tags are interpreted as official images coming from DockerHub.