Railway pgvector Runtime
Railway’s standard PostgreSQL service image does not include pgvector. Railway’s docs direct teams to use a pgvector-capable template or custom database image when an extension is not available in the standard Postgres image:
- https://docs.railway.com/databases/postgresql
- https://docs.railway.com/databases/database-view
- https://docs.railway.com/guides/rag-pipeline-pgvector
The platform expects PostgreSQL 16 plus pgvector for vector-backed candidate embedding search. The local Docker runtime is pgvector/pgvector:pg16 to match that requirement. Candidate semantic search currently stores durable vectors in CandidateProfileEmbedding.vectorJson and uses the pgvector column only as a rebuildable acceleration path for Ollama nomic-embed-text embeddings at 768 dimensions.
Safe Runtime Change
Section titled “Safe Runtime Change”Do not delete the Railway database volume, reset the database, or recreate rows manually.
-
Confirm the current Railway database major version is PostgreSQL 16. If it is not PostgreSQL 16, take a Railway backup/snapshot and use a normal PostgreSQL backup/restore or major-version upgrade path instead of reusing the volume directly.
-
Capture a Railway backup or snapshot and keep it until the application is healthy after deployment.
-
Capture a data baseline against the existing Railway database:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm --filter @repo/database validate:pgvector -- --mode=baseline --output=railway-pgvector-baseline.json -
Change the Railway database service source to a pgvector-capable PostgreSQL 16 runtime, preferably
pgvector/pgvector:pg16or the Railway-supported pgvector template equivalent. Keep the existing volume mounted at/var/lib/postgresql/data. -
Redeploy the database service and wait for it to accept connections.
-
Enable and verify pgvector while comparing existing data to the baseline:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm --filter @repo/database validate:pgvector -- --mode=post-change --compare=railway-pgvector-baseline.json --output=railway-pgvector-post-change.json -
Run deploy migrations:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm run db:migrate -
Smoke-test API reads for existing candidates and job postings before removing the backup/snapshot.
Railway Ollama Embeddings
Section titled “Railway Ollama Embeddings”Run Ollama as a separate Railway service rather than inside the API container.
-
Add an
ollamaservice in the same Railway project and environment as the API. -
Configure the service to run Ollama on port
11434with persistent storage for pulled models. -
Pull
nomic-embed-textbefore enabling the API provider, for example from a Railway shell on the Ollama service:Terminal window ollama pull nomic-embed-text -
Confirm the API service can reach the private Railway service URL from inside Railway networking.
-
Configure optional API variables in staging first:
Terminal window EMBEDDING_PROVIDER=ollamaEMBEDDING_MODEL=nomic-embed-textOLLAMA_BASE_URL=http://ollama.railway.internal:11434Use the actual private Railway DNS name if it differs.
-
Deploy the API and database migrations, then regenerate embeddings:
Terminal window railway ssh --service api --environment prod -- pnpm --filter api candidate-embeddings:backfill
Run the same sequence in staging before production. For production, take a Railway Postgres backup or snapshot before the pgvector dimension migration, keep it through API health checks, candidate reads, job-posting reads, and suggestion refresh verification, then remove it only after the rollout is stable.
Validation Evidence
Section titled “Validation Evidence”The validation report records:
- PostgreSQL server version and current schema.
- Whether
CREATE EXTENSION IF NOT EXISTS vectorsucceeded. - Whether
pg_extensioncontainsvector. - Row counts for critical platform tables.
- A full-table checksum for each critical table.
- Five sampled primary keys per table.
For the runtime change to pass, the post-change report must show vectorExtension.enabled: true, no comparison mismatches, and unchanged row counts/checksums for the baseline tables.