How to Install psycopg2 in CI Without libpq Errors
psycopg2 links against libpq. CI fails when it builds from source without libpq-dev and pg_config - which the binary package sidesteps.
The psycopg2 package compiles against PostgreSQL client headers; psycopg2-binary bundles them. In CI, prefer the binary package for tests, or install libpq-dev for the source build.
Why it fails in CI
- Building
psycopg2(not -binary) withoutpg_config→ "pg_config executable not found". - Missing libpq dev headers → compile error.
- Tests run before a Postgres service is reachable → connection refused.
Install it reliably
Use psycopg2-binary for CI tests to skip the build entirely, or add libpq-dev and a compiler for a real source build. Connect to a Postgres service container.
# easiest in CI: no build
pip install psycopg2-binary
# source build (Debian)
apt-get update && apt-get install -y libpq-dev gcc
pip install psycopg2
# Alpine source build
apk add --no-cache postgresql-dev gcc musl-devCache & speed
Cache ~/.cache/pip keyed on requirements. Run a Postgres service container and gate connection on its health check.
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('**/requirements*.txt') }}Common errors
Error: pg_config executable not found→ installlibpq-devor usepsycopg2-binary.fatal error: libpq-fe.h→ missing libpq headers; installlibpq-dev/postgresql-dev.could not connect to server→ wait for the Postgres service health check.
Verify it actually works
- Assert on the restored content, not on the step succeeding. A cache or download step commonly reports success while producing an empty directory.
- Key any cache to the exact tool and dataset version. A cache restored across a version boundary is worse than a cold start.
- Check the size against the runner disk budget; GitHub-hosted runners ship roughly 14 GB free and a large dataset exhausts it as unrelated write errors.
Key takeaways
- Use
psycopg2-binaryin CI to skip the libpq build. - For a source build, install
libpq-devand a compiler. - Gate connections on a Postgres service health check.