Capabilities

Self-hosting

Run Personify on your own hardware — Docker Compose, backups, schema upgrades, multi-vault, and reverse proxy notes.

Personify is built to run locally on your own hardware. There is no hosted offering. This page covers the operational pieces: Docker, backups, upgrades, multiple vaults, and network exposure.

The Compose stack

The shipped docker-compose.yml defines one Postgres service:

yaml
services:
  db:
    image: pgvector/pgvector:pg17
    container_name: personify-db
    environment:
      POSTGRES_USER: ${PERSONIFY_DB_USER:-personify}
      POSTGRES_PASSWORD: ${PERSONIFY_DB_PASSWORD:-personify-local-dev-only}
      POSTGRES_DB: ${PERSONIFY_DB_NAME:-personify}
    ports:
      - "127.0.0.1:5544:5432"
    volumes:
      - personify_pg:/var/lib/postgresql/data

pgvector/pgvector:pg17 is Postgres 17 with pgvector preinstalled. The port binding is intentionally localhost-only. The setup script writes .env with a generated database password so fresh clones do not all share personify as the database password.

The Docker volume is where Postgres stores database files. The local vault/ and vaults/ folders store raw exports, normalized snapshots, manifests, and logs.

Warning

Changing PERSONIFY_DB_PASSWORD only affects a fresh Postgres volume. If you already have a running volume, rotate the Postgres user's password inside Postgres and update PERSONIFY_DB_URL to match.

Backups

The preferred portable backup path is the Personify CLI:

bash
vault export --out ./backups/personify.tar.gz

That bundle contains database rows plus the vault filesystem folders needed to restore raw exports and normalized files. Embeddings are intentionally skipped because they can be regenerated with vault embed.

Restore goes into a new, empty vault name:

bash
vault restore ./backups/personify.tar.gz --into restored-copy

For Postgres-native backups you can still use pg_dump, but remember that a database dump alone is not the full vault. Back up vault/raw/ and named vault folders too.

Upgrading

After pulling a new version:

bash
git pull
npm run setup

npm run setup is safe to rerun. It preserves .env, refreshes dependencies, starts Docker/Postgres, and runs vault init so schema additions are applied. Take a backup before major upgrades.

Multi-vault setups

One Docker Postgres container can host many vault databases. The UI can create them with New vault... once npm start is running.

CLI equivalent:

bash
vault --vault code-corpus init

This creates database personify_code_corpus and directory ./vaults/code-corpus/.

The UI process serves the active vault selected in the vault switcher. If you want several vaults exposed at the same time over HTTP, run separate FastAPI processes on separate ports:

bash
PERSONIFY_VAULT_NAME=personal    PERSONIFY_API_PORT=18765 uvicorn personify.api:app
PERSONIFY_VAULT_NAME=code-corpus PERSONIFY_API_PORT=18766 uvicorn personify.api:app

Environment variable overrides

Anything Personify reads from config can be set in the environment or .env:

bash
PERSONIFY_DB_URL=postgresql+psycopg://personify:supersecret@127.0.0.1:5544/personify
PERSONIFY_VAULT_DIR=./vault
PERSONIFY_VAULT_NAME=personal
PERSONIFY_VAULTS_DIR=./vaults
PERSONIFY_API_HOST=127.0.0.1
PERSONIFY_API_PORT=18765
PERSONIFY_EMBED_MODEL=sentence-transformers/all-MiniLM-L6-v2
PERSONIFY_EMBED_DIM=384

Setting PERSONIFY_API_HOST=0.0.0.0 makes FastAPI listen on all interfaces. Do not do this on an untrusted network without a reverse proxy with auth in front of it. The API does not currently provide built-in user authentication.

Behind nginx

If you expose the API beyond localhost, terminate TLS and add auth before proxying to FastAPI:

nginx
server {
    listen 443 ssl;
    server_name personify.internal.example;
 
    ssl_certificate     /etc/letsencrypt/live/personify.internal.example/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/personify.internal.example/privkey.pem;
 
    auth_basic           "Personify";
    auth_basic_user_file /etc/nginx/personify.htpasswd;
 
    location / {
        proxy_pass         http://127.0.0.1:18765;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Same caveat: whatever you put in front is the thing protecting /items/{id}, /search, /api/exports, and the UI-gated /mcp transport.

Operational checklist

  • vault export or pg_dump runs on a schedule.
  • vault/raw/ and vaults/*/raw/ are in your filesystem backup.
  • Postgres stays bound to 127.0.0.1 unless you have a specific network plan.
  • PERSONIFY_API_HOST stays at 127.0.0.1 unless a reverse proxy with auth is in front.
  • You took a backup before the last upgrade.
  • If using semantic search, embeddings have been regenerated after restore.