What you need

Already have Postgres?

Skip ahead to Create the database and role. You only need to install the pgvector extension and create one fresh database — there is no need to re-install Postgres itself.

Install PostgreSQL

macOS — Postgres.app (easiest)

  1. Download Postgres.app and drag it to /Applications.
  2. Open it, click Initialize to create a default cluster.
  3. Add the CLI tools to your PATH:
    sudo mkdir -p /etc/paths.d
    echo /Applications/Postgres.app/Contents/Versions/latest/bin \
      | sudo tee /etc/paths.d/postgresapp
    Open a new terminal so the change takes effect.
  4. Verify:
    psql --version
    psql -l       # lists databases

macOS — Homebrew

brew install postgresql@16 pgvector
brew services start postgresql@16

Linux — Debian / Ubuntu

sudo apt update
sudo apt install postgresql postgresql-contrib postgresql-16-pgvector
sudo systemctl enable --now postgresql

Older releases (Ubuntu 22.04 and earlier) may not have a postgresql-16-pgvector package. Use the PostgreSQL APT repository to pull a current version, or build pgvector from source (see below).

Linux — Fedora / RHEL

sudo dnf install postgresql-server postgresql-contrib pgvector
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql

Docker (any OS)

If you would rather not install Postgres on your host, use the official pgvector image. The example below matches the DSN in config.example.toml exactly, so you can copy-paste through the rest of the manual:

docker run -d \
  --name localmail-postgres \
  --restart unless-stopped \
  -e POSTGRES_USER=localmail \
  -e POSTGRES_PASSWORD='local@@mail' \
  -e POSTGRES_DB=localmail \
  -p 5532:5432 \
  -v localmail-pgdata:/var/lib/postgresql/data \
  pgvector/pgvector:pg16

The container exposes Postgres on host port 5532 (note the non-standard port to avoid clashing with a local install). Data persists in the localmail-pgdata volume.

Docker shortcut

If you used the Docker recipe above, the localmail database, the localmail role, and the password are already set up — you can skip the rest of this page and jump to Step 2 — Install localmail. You still need to run CREATE EXTENSION vector; once, which the next-step localmail init-db will trigger via migrations.

Create the database and role

You will create a dedicated Postgres role and database so localmail's credentials never overlap with anything else on your system.

  1. Open a superuser psql session.

    On macOS with Postgres.app or Homebrew the current Unix user is already a superuser:

    psql postgres

    On Linux with the system Postgres package, switch to the postgres user first:

    sudo -u postgres psql
  2. Create the role and database.

    Pick a strong password and remember it — you will put it in config.toml in Step 2. The example uses local@@mail (matches config.example.toml); replace it with your own.

    CREATE ROLE localmail WITH LOGIN PASSWORD 'local@@mail';
    CREATE DATABASE localmail OWNER localmail;
    \q
  3. Enable the pgvector extension.

    Connect to the newly-created database as a superuser (extensions can only be enabled by superusers) and create the extension:

    psql -d localmail
    -- or: sudo -u postgres psql -d localmail
    CREATE EXTENSION IF NOT EXISTS vector;
    \q

    If you get could not open extension control file ... vector.control, the pgvector package is missing. Re-check the install commands above for your platform.

  4. Verify the credentials work.

    Open a new shell and connect as the localmail role:

    psql 'postgresql://localmail:local%40%40mail@localhost:5432/localmail'

    (If you used the Docker recipe, port is 5532 not 5432.) You should land at a localmail=> prompt with no errors. \q to quit.

    URL-encode special chars

    The @ in a password must appear in the DSN as %40; an unescaped @ would be parsed as the host separator. Other characters that need encoding: : → %3A, / → %2F,  → %20.

What about backups?

Now is a good moment to plan backups, even though there is nothing in the database yet. localmail's archive is the only copy of any mail you sync after you delete the original from the IMAP server, so a backup strategy matters. Two simple options:

Troubleshooting

Symptom Fix
connection refused on psql Postgres isn't running. brew services start postgresql@16 / sudo systemctl start postgresql / docker start localmail-postgres.
FATAL: password authentication failed You typed the password wrong, or the host's pg_hba.conf requires peer authentication. On Linux, edit /etc/postgresql/16/main/pg_hba.conf, change the local rule from peer to md5, then sudo systemctl reload postgresql.
extension "vector" is not available The pgvector package is missing or not in the same installation as the running server. Install it for the matching major version (e.g. postgresql-16-pgvector for PG 16), then restart Postgres.