Can I use Prefect 2.0 with docker-compose setup including Orion server and a Postgres database?

I’m trying to spin up a local prefect orion server for testing/development.

here’s the compose file I’ve come up with:

version: "3.7"

services:
  postgres-orion:
    image: "postgres:11"
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres-orion-volume:/var/lib/postgresql/data
    networks:
      - prefect-orion
    restart: "always"
    command:
      - "postgres"
      - "-c"
      - "max_connections=150"

  orion:
    build: .
    command: bash -c "prefect orion start"
    ports:
      - "4500:4200"
    environment:
        PREFECT_ORION_DATABASE_CONNECTION_URL: ${DB_CONNECTION_URL}
    networks:
      - prefect-orion
    restart: "always"
    depends_on:
      - postgres-orion

volumes:
  postgres-orion-volume:

networks:
  prefect-orion:
    name: prefect-orion

The local build is a simple pull from prefecthq/orion, installing psycopg2 and asyncpg. Mapped port 4500 on localhost since 4200 is already in use.

However, the application does not respond when I navigate to localhost:4500, the logs show the stack below.

Since I intended the agent to run in a separate container anyway, I went ahead and tried the --no-agent flag for the server, and this time the logs are stuck with a single message: “Starting Orion API server…”

Still no response on localhost. (ERR_EMPTY_RESPONSE)

Any ideas what I’m doing wrong?


**stack**

`INFO:     127.0.0.1:55446 - "POST /api/flow_runs/filter HTTP/1.1" 500 Internal Server Error`

`Traceback (most recent call last):`

`  File "/usr/local/bin/prefect", line 8, in <module>`

`    sys.exit(app())`

`  File "/usr/local/lib/python3.8/site-packages/typer/main.py", line 214, in __call__`

`    return get_command(self)(*args, **kwargs)`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1128, in __call__`

`    return self.main(*args, **kwargs)`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1053, in main`

`    rv = self.invoke(ctx)`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1659, in invoke`

`    return _process_result(sub_ctx.command.invoke(sub_ctx))`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1659, in invoke`

`    return _process_result(sub_ctx.command.invoke(sub_ctx))`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1395, in invoke`

`    return ctx.invoke(self.callback, **ctx.params)`

`  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 754, in invoke`

`    return __callback(*args, **kwargs)`

`  File "/usr/local/lib/python3.8/site-packages/typer/main.py", line 500, in wrapper`

`    return callback(**use_params)  # type: ignore`

`  File "/usr/local/lib/python3.8/site-packages/prefect/utilities/asyncio.py", line 120, in wrapper`

`    return run_async_in_new_loop(async_fn, *args, **kwargs)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/utilities/asyncio.py", line 67, in run_async_in_new_loop`

`    return anyio.run(partial(__fn, *args, **kwargs))`

`  File "/usr/local/lib/python3.8/site-packages/anyio/_core/_eventloop.py", line 56, in run`

`    return asynclib.run(func, *args, **backend_options)  # type: ignore`

`  File "/usr/local/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 233, in run`

`    return native_run(wrapper(), debug=debug)`

`  File "/usr/local/lib/python3.8/asyncio/runners.py", line 44, in run`

`    return loop.run_until_complete(main)`

`  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete`

`    return future.result()`

`  File "/usr/local/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 228, in wrapper`

`    return await func(*args)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/cli/agent.py", line 32, in start`

`    await agent.get_and_submit_flow_runs()`

`  File "/usr/local/lib/python3.8/site-packages/prefect/agent.py", line 53, in get_and_submit_flow_runs`

`    submittable_runs = await self.client.read_flow_runs(`

`  File "/usr/local/lib/python3.8/site-packages/prefect/client.py", line 599, in read_flow_runs`

`    response = await self.post(f"/flow_runs/filter", json=body)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/client.py", line 124, in post`

`    response.raise_for_status()`

`  File "/usr/local/lib/python3.8/site-packages/httpx/_models.py", line 1508, in raise_for_status`

`    raise HTTPStatusError(message, request=request, response=self)`

`httpx.HTTPStatusError: Server error '500 Internal Server Error' for url 'http://127.0.0.1:4200/api/flow_runs/filter'`

`For more information check: https://httpstatuses.com/500`

`ERROR:    Exception in ASGI application`

`Traceback (most recent call last):`

`  File "/usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi`

`    result = await app(self.scope, self.receive, self.send)`

`  File "/usr/local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__`

`    return await self.app(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__`

`    await super().__call__(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__`

`    await self.middleware_stack(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__`

`    raise exc`

`  File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__`

`    await self.app(scope, receive, _send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/middleware/cors.py", line 84, in __call__`

`    await self.app(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__`

`    raise exc`

`  File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__`

`    await self.app(scope, receive, sender)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 656, in __call__`

`    await route.handle(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 408, in handle`

`    await self.app(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__`

`    await super().__call__(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__`

`    await self.middleware_stack(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__`

`    raise exc`

`  File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__`

`    await self.app(scope, receive, _send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__`

`    raise exc`

`  File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__`

`    await self.app(scope, receive, sender)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 656, in __call__`

`    await route.handle(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 259, in handle`

`    await self.app(scope, receive, send)`

`  File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 61, in app`

`    response = await func(request)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/orion/utilities/server.py", line 87, in handle_response_scoped_depends`

`    response = await default_handler(request)`

`  File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 226, in app`

`    raw_response = await run_endpoint_function(`

`  File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 159, in run_endpoint_function`

`    return await dependant.call(**values)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/orion/api/flow_runs.py", line 175, in read_flow_runs`

`    return await models.flow_runs.read_flow_runs(`

`  File "/usr/local/lib/python3.8/site-packages/prefect/orion/database/dependencies.py", line 112, in async_wrapper`

`    return await fn(*args, **kwargs)`

`  File "/usr/local/lib/python3.8/site-packages/prefect/orion/models/flow_runs.py", line 260, in read_flow_runs`

`    result = await session.execute(query)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/ext/asyncio/session.py", line 211, in execute`

`    return await greenlet_spawn(`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 134, in greenlet_spawn`

`    result = context.throw(*sys.exc_info())`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1691, in execute`

`    conn = self._connection_for_bind(bind)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1532, in _connection_for_bind`

`    return self._transaction._connection_for_bind(`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 747, in _connection_for_bind`

`    conn = bind.connect()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/future/engine.py", line 406, in connect`

`    return super(Engine, self).connect()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3204, in connect`

`    return self._connection_cls(self, close_with_result=close_with_result)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 96, in __init__`

`    else engine.raw_connection()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3283, in raw_connection`

`    return self._wrap_pool_connect(self.pool.connect, _connection)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3250, in _wrap_pool_connect`

`    return fn()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 310, in connect`

`    return _ConnectionFairy._checkout(self)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 868, in _checkout`

`    fairy = _ConnectionRecord.checkout(pool)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 476, in checkout`

`    rec = pool._do_get()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 146, in _do_get`

`    self._dec_overflow()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__`

`    compat.raise_(`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 207, in raise_`

`    raise exception`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 143, in _do_get`

`    return self._create_connection()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 256, in _create_connection`

`    return _ConnectionRecord(self)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 371, in __init__`

`    self.__connect()`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 666, in __connect`

`    pool.logger.debug("Error on connect(): %s", e)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__`

`    compat.raise_(`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 207, in raise_`

`    raise exception`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 661, in __connect`

`    self.dbapi_connection = connection = pool._invoke_creator(self)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 590, in connect`

`    return dialect.connect(*cargs, **cparams)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 597, in connect`

`    return self.dbapi.connect(*cargs, **cparams)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 755, in connect`

`    await_only(self.asyncpg.connect(*arg, **kw)),`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 76, in await_only`

`    return current.driver.switch(awaitable)`

`  File "/usr/local/lib/python3.8/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 129, in greenlet_spawn`

`    value = await result`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connection.py", line 2085, in connect`

`    return await connect_utils._connect(`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 895, in _connect`

`    raise last_error`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 881, in _connect`

`    return await _connect_addr(`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 781, in _connect_addr`

`    return await __connect_addr(params, timeout, True, *args)`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 825, in __connect_addr`

`    tr, pr = await compat.wait_for(connector, timeout=timeout)`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/compat.py", line 66, in wait_for`

`    return await asyncio.wait_for(fut, timeout)`

`  File "/usr/local/lib/python3.8/asyncio/tasks.py", line 494, in wait_for`

`    return fut.result()`

`  File "/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 691, in _create_ssl_connection`

`    tr, pr = await loop.create_connection(`

`  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 986, in create_connection`

`    infos = await self._ensure_resolved(`

`  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1365, in _ensure_resolved`

`    return await loop.getaddrinfo(host, port, family=family, type=type,`

`  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 825, in getaddrinfo`

`    return await self.run_in_executor(`

`  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run`

`    result = self.fn(*self.args, **self.kwargs)`

`  File "/usr/local/lib/python3.8/socket.py", line 918, in getaddrinfo`

`    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):`

`socket.gaierror: [Errno -2] Name or service not known`

Why do you want to do it this way via docker-compose? We haven’t released any official docker-compose setup yet, so it would be difficult to provide you with guidance on best practices in this regard.

Orion works well without Docker, and if you don’t want to manage the backend database, you can sign up for Cloud 2.0 beta, which is available for free (no credit card required): https://beta.prefect.io/

Regarding using Postgres with Orion, check out this documentation page that explains how you can use Orion with Postgres instance running in Docker:

Hello Anna, the reason is simply because I’m on a windows machine, and couldn’t make the appliction run natively. Our server is a windows server instance, and as far as I understand, the only way I could make this work would be though docker.
As for the back end issue, for now I need to use this local postgres, but maybe later I would be able to move to cloud.
Nevertheless, due to some earlier misconfiguration which caused issues with the database, I’m pretty sure now that the application can connect correctly to it, so I don’t really think the issue is related to that.

2 Likes