Docker Compose does not allow to use local images

DockerDocker Compose

Docker Problem Overview


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

Docker Solutions


Solution 1 - Docker

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 - Docker

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 - Docker

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 4 - Docker

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][1] with docker-compose

I finally got it working by [running the local registry][2], 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. [1]: https://github.com/docker/compose/issues/1568 [2]: https://docs.docker.com/registry/deploying/

Solution 5 - Docker

You have a DOCKER_HOST entry in your .env 

From the looks of your .env file you seem to have configured docker-compose to use a remote docker host:

DOCKER_HOST=tcp://***.***.**.**:2376

Moreover, this .env is only loaded by docker-compose, but not docker. So in this situation your docker images output doesn't represent what images are available when running docker-compose.

When running docker-compose you're actually running Docker on the remote host tcp://***.***.**.**:2376, yet when running docker by itself you're running Docker locally.

When you run docker images, you're indeed seeing a list of the images that are stored locally on your machine. But docker-compose up -d is going to attempt to start the containers not on your local machine, but on ***.***.**.**:2376. docker images won't show you what images are available on the remote Docker host unless you set the DOCKER_HOST environment variable, like this for example:

DOCKER_HOST=tcp://***.***.**.**:2376 docker images

Evidently the remote Docker host doesn't have the web-server:staging image stored there, nor is the image available on Docker hub. That's why Docker complains it can't find the image.

Solutions

Run the container locally

If your intention was to run the container locally, then simply remove the DOCKER_HOST=... line from your .env and try again.

Push the image to a repository.

However if you plan on running the image remotely on the given DOCKER_HOST, then you should probably push it to a repository. You can create a free repository at Docker Hub, or you can host your own repository somewhere, and use docker push to push the image there, then make sure your docker-compose.yml referenced the correct repository.

Save the image, load it remotely.

If you don't want to push the image to Docker Hub or host your own repository you can also transfer the image using a combination of docker image save and docker image load:

docker image save web-server:staging | DOCKER_HOST=tcp://***.***.**.**:2376 docker image load

Note that this can take a while for big images, especially on a slow connection.

Solution 6 - Docker

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.

Solution 7 - Docker

For me putting "build: ." did the trick. My working docker compose file looks like this,

version: '3.0'
services:
  terraform:
    build: .
    image: tf:staging
    env_file: .env
    working_dir: /opt
    volumes:
      - ~/.aws:/.aws

Solution 8 - Docker

In my tests, for this to work you must specify a numeric tag otherwise docker will try to check for the latest version remotely.

Rename your local image to something like 'web-server:1' instead of 'web-server:staging' and change your compose file accordingly.

Solution 9 - Docker

One can reference the local image name without a tag as well

docker build -t imagename .

can be referenced as:

version: "3"
services:
  web:
    image: imagename

in the docker-compose yaml.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVictor DombrovskyView Question on Stackoverflow
Solution 1 - Dockern2oView Answer on Stackoverflow
Solution 2 - DockerDenis TsoiView Answer on Stackoverflow
Solution 3 - DockerBen WindingView Answer on Stackoverflow
Solution 4 - DockerMinjeong ChoiView Answer on Stackoverflow
Solution 5 - DockerYogarineView Answer on Stackoverflow
Solution 6 - DockerTom SaleebaView Answer on Stackoverflow
Solution 7 - DockerShantanuView Answer on Stackoverflow
Solution 8 - DockerAlisio MenesesView Answer on Stackoverflow
Solution 9 - DockerNaeView Answer on Stackoverflow