#Run python server in dagger (gunicorn)

1 messages · Page 1 of 1 (latest)

prime stag
#

Hi,

I'm trying to start a Python server to run some tests on it, and I would like to do with dagger.
However, when I ran exec for the server, it blocks the pipeline forever.
Is there any way to execute in the background? Or do I need to run in k8s or a compose somehow?
If I ran the server as a daemon, it doesn't stay working, it just dies. As I can't curl the port in the container.
I tried to run with nohup and & but doesn't like that either.
Tried to use sync() or with and without stdout but no luck either.
Is stuck with the info

stray coral
prime stag
#

Hmm I am using as a service the issue it doesn't reach the exposed_port part. When I run the server it takes control of the terminal and stops the execution there, it doesn't reach the exposed port part. And I have another container with await and the service binding for it.

stray coral
#

I see a mismatch in ports. Gunicorn running on 8000 but wget fetching on 8080.

prime stag
#

Yeah, but it doesn't get past starting the server, it just sits there with the server info. It doesn't go any further than that.

lone marsh
#

@prime stag the reason this happens is because gunicorn by default listens in 127.0.0.1 and not 0.0.0.0. If you add --bind 0.0.0.0:$port that should work

prime stag
lone marsh
#

Oh! I missed that. I have an example working in my local. I'll share in a second

prime stag
#

Cool thanks appreciate that.

lone marsh
#

this is the pipeline I have:

import sys

import anyio
import dagger


async def main():
    # create Dagger client
    async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as client:
        # create HTTP service container with exposed port 8080
        http_srv = (
            client.container()
            .from_("python")
            .with_workdir("/srv")
            .with_file("app.py", client.host().file("app.py"))
            .with_exec(["pip", "install", "gunicorn"])
            .with_exec(["gunicorn", "-w", "4", "app:app", "--bind", "0.0.0.0:8000"])
            .with_exposed_port(8000)
        )

        # create client container with service binding
        # access HTTP service and print result
        val = await (
            client.container()
            .from_("alpine")
            .with_service_binding("www", http_srv)
            .with_exec(["wget", "-O-", "http://www:8000"])
            .stdout()
        )

    print(val)


anyio.run(main)
#

and this the app.py file:

def app(environ, start_response):
    """Simplest possible application object"""
    data = b'Hello, World!\n'
    status = '200 OK'
    response_headers = [
        ('Content-type', 'text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])
#

that works in dagger v0.8.4

prime stag
#

I see that could it be because the dagger checkpoint tries / the bare path? And my app is not listening to that. If I try that path it gives 404 not found and I guess it expects 200? Is there a way to specify another path?

lone marsh
#

The Dagger health check is port based, it doesn't do http. Do you have an example to repro your issue?

prime stag
#

Re writing it again seems to be fine now, I must've been executing something wrong then. Thanks for the example it probably steered me to the right direction.
Sorry for probably missing something obvious there. And thanks for the help