<@ULVA73B9P> - I want to start a prefect docker im...
# ask-marvin
k
@Marvin - I want to start a prefect docker image in github CI, and set the necessary environment variables to point it at a postgres service container. Can you tell me how to do that?
m
thought for 884.0 seconds
Great question — you can run Prefect Server in a GitHub Actions job as a service container and point it at a Postgres service container using environment variables. Below is a minimal, working example workflow that: - Starts Postgres as a service - Starts Prefect Server from the official
prefecthq/prefect:3-latest
image as another service - Wires Prefect to Postgres via
PREFECT_SERVER_DATABASE_CONNECTION_URL
- Waits until the API is ready Assumes Prefect 3.x.
Copy code
name: Prefect Server in CI

on:
  push:
  pull_request:

jobs:
  prefect-server:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_USER: prefect
          POSTGRES_PASSWORD: prefect
          POSTGRES_DB: prefect
        ports:
          - 5432:5432
        options: >-
          --health-cmd="pg_isready -U prefect"
          --health-interval=5s
          --health-timeout=5s
          --health-retries=20

      prefect:
        image: prefecthq/prefect:3-latest
        # Expose the API/UI port to the job runner
        ports:
          - 4200:4200
        env:
          # Bind API inside the container to all interfaces so the job can reach it
          PREFECT_SERVER_API_HOST: 0.0.0.0

          # Point Prefect at the Postgres service.
          # Note: use the service name "postgres" as the hostname.
          PREFECT_SERVER_DATABASE_CONNECTION_URL: <postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>

          # Optional: enable UI in CI if you intend to hit it (usually not needed)
          PREFECT_UI_ENABLED: "true"

          # Optional: make migrations more forgiving in slow CI environments
          # PREFECT_SERVER_DATABASE_CONNECTION_TIMEOUT: "10"
          # PREFECT_SERVER_DATABASE_TIMEOUT: "30"
        # Start Prefect Server
        command:
          [
            "prefect", "server", "start",
            "--host", "0.0.0.0",
            "--analytics-off"
          ]

    steps:
      - uses: actions/checkout@v4

      # Wait for Prefect API to become ready
      - name: Wait for Prefect API
        run: |
          echo "Waiting for Prefect API on <http://localhost:4200>..."
          for i in {1..60}; do
            if curl -sf <http://localhost:4200/api/health> > /dev/null; then
              echo "Prefect API is up!"
              exit 0
            fi
            sleep 2
          done
          echo "Timed out waiting for Prefect API"
          exit 1

      # Example: prove it works
      - name: Hit Prefect API
        run: curl -sSf <http://localhost:4200/api/health> | jq .
Key points: - Use the async SQLAlchemy driver in your URL:
postgresql+asyncpg://...
- In GitHub Actions, service containers can talk to each other via their service name (e.g.,
postgres
) as the hostname. - Binding
PREFECT_SERVER_API_HOST=0.0.0.0
(and/or
--host 0.0.0.0
) ensures the API is reachable from the job via the mapped port. - Default API port is 4200; the example maps it so the job can poll
/api/health
. Useful references: - Prefect 3 settings reference (env vars): Settings reference - Self-hosted via Docker: Server in Docker - Docker Compose examples: Docker Compose guide If you prefer component-wise env vars instead of a full URL, you can set: -
PREFECT_SERVER_DATABASE_DRIVER=postgresql+asyncpg
-
PREFECT_SERVER_DATABASE_HOST=postgres
-
PREFECT_SERVER_DATABASE_PORT=5432
-
PREFECT_SERVER_DATABASE_USER=prefect
-
PREFECT_SERVER_DATABASE_PASSWORD=prefect
-
PREFECT_SERVER_DATABASE_NAME=prefect
Do you also need the UI during CI, or just the API for tests? I can tailor the workflow accordingly.