question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pulling an image for run much slower than commandline

See original GitHub issue

Running the same command on an image that hasn’t been downloaded is much slower with the SDK than with the CLI. Does the CLI have access to some other cache than the SDK? Are the two tests not really comparable? I’m new with this, so apologies if I’m not using it correctly.

Context:

$ pip freeze | grep docker && python --version && docker version
docker==2.1.0
docker-pycreds==0.2.1
Python 2.7.13 :: Continuum Analytics, Inc.
Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   60ccb22
 Built:        Thu Feb 23 10:40:59 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: true
$ sw_vers -productVersion
10.11.6 # MacOS

Reproducer:

import docker
import unittest
from subprocess import Popen, PIPE

class DockerTests(unittest.TestCase):
    def test_hello_world_sdk(self):
        # Slow if image not already downloaded
        client = docker.from_env()
        output = client.containers.run("ubuntu", "echo hello world")
        self.assertEqual(output, 'hello world\n')

    def test_hello_world_popen(self):
        # Even if download is necessary, runs in a couple seconds
        p = Popen(['docker', 'run', 'ubuntu', 'echo', 'hello', 'world'],
                  stdout=PIPE)
        output = p.stdout.read()
        self.assertEqual(output, 'hello world\n')

Using the SDK is fast if the image has already been downloaded:

$ python -m unittest -v docker_engine_app.tests.DockerTests.test_hello_world_sdk
test_hello_world_sdk (docker_engine_app.tests.DockerTests) ... ok

----------------------------------------------------------------------
Ran 1 test in 1.557s

OK

But much slower starting from scratch:

$ docker rmi ubuntu
Untagged: ubuntu:latest
$ python -m unittest -v docker_engine_app.tests.DockerTests.test_hello_world_sdk
test_hello_world_sdk (docker_engine_app.tests.DockerTests) ... ok

----------------------------------------------------------------------
Ran 1 test in 57.183s

OK

But if the CLI needs to download the image, it isn’t anywhere near as slow.

$ docker rmi ubuntu
Untagged: ubuntu:latest
$ python -m unittest -v docker_engine_app.tests.DockerTests.test_hello_world_popen
test_hello_world_popen (docker_engine_app.tests.DockerTests) ... Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
Digest: sha256:dd7808d8792c9841d0b460122f1acf0a2dd1f56404f8d1e56298048885e45535
Status: Downloaded newer image for ubuntu:latest
ok

----------------------------------------------------------------------
Ran 1 test in 2.298s

OK

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
shin-commented, Mar 13, 2017

docker pull ubuntu is actually translated into docker pull ubuntu:latest. Same thing for your rmi command which only untags the ubuntu:latest image (you probably have ubuntu:16.04 tagged as well which prevents the CLI for actually removing the associated layers). So your CLI command is very fast because it’s not actually downloading any new data, just checking that the tag matches the version you already have locally and re-tagging it accordingly.

On the other hand, the API (and the Python API client) when asked to pull ubuntu, actually pulls the entire repository (all images tagged in the official ubuntu repository, of which there are a lot).

If you change your code to use equivalent pull commands, I believe you will see comparable execution times:

    def test_hello_world_sdk_with_cli_pull(self):
        client = docker.from_env()
        call(['docker', 'pull', 'ubuntu'])
        output = client.containers.run("ubuntu", "echo hello world")
        self.assertEqual(output, 'hello world\n')

    def test_hello_world_sdk_with_sdk_pull(self):
        client = docker.from_env()
        client.images.pull('ubuntu:latest')
        output = client.containers.run("ubuntu", "echo hello world")
        self.assertEqual(output, 'hello world\n')
0reactions
tjerkwcommented, Jan 8, 2019

I still see docker pull in bash running much faster than the python code. I guess its multithreaded?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cell detection from command line / script slower than when ...
In this specific case I'm running a script to: use watershed cell detection; classify images using a legacy classifier ...
Read more >
5 Tips to Speed up Your Docker Image Build - vsupalov.com
This article will walk you through frequent sources of slowness when building Docker images for Python projects, and ways how you can avoid...
Read more >
Slow rendering - Android Developers
If your app suffers from slow UI rendering, then the system is forced to skip frames and the user will perceive stuttering in...
Read more >
Docker is extremely slow when running Laravel on Nginx ...
to open the project folder from visual studio : CTRL + P, >Remote-WSL : Open folder in WSL... to open the project folder...
Read more >
Slow Docker on Windows WSL2? Fast and easy fix to improve ...
Why is Docker so slow? The root of the issue is that Windows 10 is (was) using WSL (Windows Subsystem for Linux), which...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found