aio-libs / aiodocker

Python Docker API client based on asyncio and aiohttp
Other
427 stars 97 forks source link

is it possible to start the container in detached mode and attach to print the output in a loop? #830

Closed dberardo-com closed 3 months ago

dberardo-com commented 1 year ago

i mean somethings like this:

await container.start(detach=True)  # this line should return immediately
async for chunk in container.log(stdout=True, stderr=os.environ.get("PRINT_WARNINGS",0), follow=True):
    print(chunk, end='')
error_log=[]

container cmd is "sleep 1 && echo 1 && sleep 20 && echo 20"

this means that the async loop will output 2 echo messages, one after 1 second and one after 20 seconds.

dberardo-com commented 1 year ago

the problem is that running with detached lead to this error: https://stackoverflow.com/questions/44515097/starting-container-using-docker-api

naufalafif commented 1 year ago

hi @dberardo-com

in docker-sdk / library, container is running in detached mode by default. so you dont have to specify it.

the problem is that running with detached lead to this error: https://stackoverflow.com/questions/44515097/starting-container-using-docker-api

this issue is happened because container.start is to start created container & doesn't accept any argument, the config should be provided in container.create. you can refer it to API doc https://docs.docker.com/engine/api/v1.42/#tag/Container/operation/ContainerStart

naufalafif commented 1 year ago

if you want to print the output in a loop, you can use container.attach or container.websocket

naufalafif commented 1 year ago

you can also do it using container exec

dberardo-com commented 1 year ago

thanks for the reply, i had already tried adding these params to the config object i pass to the create method, here:

await docker.containers.create(
          config={
              "Detach": True,
          },
      )

but then when i call the .start method, the python script awaits till the whole execution of the start command is finished, before proceeding ... which is exactly what i want to avoid.

any guess?


INFO: i was looking here and could not find any option to set the detached flag while creating the container: https://aiodocker.readthedocs.io/en/latest/_modules/aiodocker/containers.html#DockerContainers.create

btw the reason why i need to do this, is that i have to use the "docker copy" command equivalent before starting the container to copy files inside it upfront. if there is a way to do this all in one command, that would be welcome, otherwise my current approach was:

naufalafif commented 1 year ago

Hi @dberardo-com

there's no need to put detached when creating container, it is running detached by default.

here's some example code that print the logs in a loop

import aiodocker

docker = aiodocker.Docker()
print('== Running a hello-world container ==')
container = await docker.containers.create_or_replace(
    config={
        'Cmd': ['/bin/bash', '-c', 'sleep 3600'],
        'Image': 'ubuntu:latest',
    },
    name='testing',
)
await container.start()

try:
    # code here
    socket = await container.exec(
        stdout=True,
        stderr=True,
        tty=True,
        cmd=["/bin/echo", '"hello world"'],
    )
    socket_stream = socket.start(detach=False)
    await socket_stream._init()

    while True:
        output = await socket_stream.read_out()
        if output:
            print(output)
        else:
            break
except Exception as e:
    print(e)

await container.delete(force=True)
await docker.close()
dberardo-com commented 1 year ago

i am totally sorry ... i have just realised that both your solution and mine from above were working .. but that i was not seeing any output because of this env variable not being set:

PYTHONUNBUFFERED=1

so the issue was related to the buffered output ...

thanks again for your support

naufalafif commented 1 year ago

Hi @dberardo-com , glad to hear that. i think you can close this issue

achimnol commented 3 months ago

Closing the issue as resolved.