Repository: mlflow/mlflow

Issue:
[BUG] Pulling docker image fails when skipping image build
### Issues Policy acknowledgement

- [X] I have read and agree to submit bug reports in accordance with the [issues policy](https://www.github.com/mlflow/mlflow/blob/master/ISSUE_POLICY.md)

### Willingness to contribute

Yes. I can contribute a fix for this bug independently.

### MLflow version

- Client: 1.30.0


### System information

- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Linux Ubuntu 20.04
- **Python version**: 3.8.10
- **yarn version, if running the dev UI**: N/A


### Describe the problem

The `mlflow run --skip-image-build ...` will fail when a specified docker image has not already been pulled before running the command.
This is because an incorrect URI is used for downloading the image.
For concrete, we should refer to `base_image` rather than `image_uri` at https://github.com/mlflow/mlflow/blob/v1.30.0/mlflow/projects/docker.py#L84.

### Tracking information

_No response_

### Code to reproduce issue


```bash
#! /bin/bash

IMAGE=${1:-"python:3.6"}
echo "Log: Use $IMAGE for reproducing the bug."

ret=`docker images ${IMAGE} --format "{{.ID}}"`

if [ -n "$ret" ]; then
  echo "Error: $IMAGE has already pulled (image-id: $ret)"
  echo "This bug only occurs when the specfied image has not pulled yet."
  echo "Please run: docker rmi <the printed id> and rerun this script."
  echo "Or, specify another image that you have not downloaded yet."
  exit 1
fi

cat <<EOF > MLproject
name: mlflow-project-debug

docker_env:
  image: ${IMAGE}

entry_points:
  main:
    command: "echo Hi"
EOF

echo "Log: === MLproject ==="
cat MLproject
echo "Log: === End of MLproject ==="

mlflow run --skip-image-build .
```

### Stack trace

```
2022/11/08 10:18:16 INFO mlflow.projects.docker: Pulling python:3.9
Traceback (most recent call last):
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/docker/api/client.py", line 268, in _raise_for_status
    response.raise_for_status()
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http+docker://localhost/v1.41/images/create?tag=latest&fromImage=mlflow-project-debug

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/takafumi.kubota/.local/bin/mlflow", line 8, in <module>
    sys.exit(cli())
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/takafumi.kubota/.pyenv/versions/3.8.10/lib/python3.8/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/mlflow/cli.py", line 195, in run
    projects.run(
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/mlflow/projects/__init__.py", line 344, in run
    submitted_run_obj = _run(
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/mlflow/projects/__init__.py", line 103, in _run
    submitted_run = backend.run(
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/mlflow/projects/backend/local.py", line 116, in run
    image = build_docker_image(
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/mlflow/projects/docker.py", line 84, in build_docker_image
    image = client.images.pull(image_uri)
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/docker/models/images.py", line 465, in pull
    pull_log = self.client.api.pull(
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/docker/api/image.py", line 429, in pull
    self._raise_for_status(response)
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/docker/api/client.py", line 270, in _raise_for_status
    raise create_api_error_from_http_exception(e) from e
  File "/home/takafumi.kubota/.local/lib/python3.8/site-packages/docker/errors.py", line 39, in create_api_error_from_http_exception
    raise cls(e, response=response, explanation=explanation) from e
docker.errors.ImageNotFound: 404 Client Error for http+docker://localhost/v1.41/images/create?tag=latest&fromImage=mlflow-project-debug: Not Found ("pull access denied for mlflow-project-debug, repository does not exist or may require 'docker login': denied: requested access to the resource is denied")

```

### Other info / logs

_No response_

### What component(s) does this bug affect?

- [ ] `area/artifacts`: Artifact stores and artifact logging
- [ ] `area/build`: Build and test infrastructure for MLflow
- [ ] `area/docs`: MLflow documentation pages
- [ ] `area/examples`: Example code
- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry
- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors
- [ ] `area/recipes`: Recipes, Recipe APIs, Recipe configs, Recipe Templates
- [X] `area/projects`: MLproject format, project running backends
- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs
- [ ] `area/server-infra`: MLflow Tracking server backend
- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging

### What interface(s) does this bug affect?

- [ ] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server
- [X] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry
- [ ] `area/windows`: Windows support

### What language(s) does this bug affect?

- [ ] `language/r`: R APIs and clients
- [ ] `language/java`: Java APIs and clients
- [ ] `language/new`: Proposals for new client languages

### What integration(s) does this bug affect?

- [ ] `integrations/azure`: Azure and Azure ML integrations
- [ ] `integrations/sagemaker`: SageMaker integrations
- [ ] `integrations/databricks`: Databricks integrations


Discussion:
@tk1012 Thanks for reporting the issue!

> For concrete, we should refer to base_image rather than image_uri at https://github.com/mlflow/mlflow/blob/v1.30.0/mlflow/projects/docker.py#L84.

Sounds good. Could you file a PR to make the change?

Resolving patch:
diff --git a/mlflow/projects/docker.py b/mlflow/projects/docker.py
--- a/mlflow/projects/docker.py
+++ b/mlflow/projects/docker.py
@@ -81,7 +81,7 @@ def build_docker_image(work_dir, repository_uri, base_image, run_id, build_image
     if not build_image:
         if not client.images.list(name=base_image):
             _logger.info(f"Pulling {base_image}")
-            image = client.images.pull(image_uri)
+            image = client.images.pull(base_image)
         else:
             _logger.info(f"{base_image} already exists")
             image = client.images.get(base_image)


Test patch: