Category Archives: RAG

Local RAG with .NET, PostgreSQL, and Ollama: Code Setup (Part 3)

In Part 1 and Part 2, we set up our infrastructure: a PostgreSQL database with pgvector for storing embeddings, and Ollama running the Phi4 model locally. Now we’ll create a .NET application to bring these components together into a working RAG system. We’ll start by setting up our solution structure with proper test projects.

If you’re just joining, you’ll need to follow the steps in Parts 1 and 2 first to get PostgreSQL and Ollama running in Docker.

Let’s start by creating the .NET solution and projects from the command line (we could do this through Visual Studio’s UI, but I prefer keeping my command-line-fu strong).

Creating a new .NET project

Open PowerShell as an administrator. Browse to a directory where you’d like to create your solution – I keep mine in my Git repositories folder. Then run these commands:

First, create the solution

dotnet new sln -n LocalRagConsoleDemo

You might see a prompt about the dev certificate – if so, run:

dotnet dev-certs https --trust

Now create our three projects: the main console app and two test projects

dotnet new console -n LocalRagConsoleDemo
dotnet new nunit -n LocalRagConsoleUnitTests
dotnet new nunit -n LocalRagConsoleIntegrationTests

Finally, add everything to the solution, organizing tests in their own folder

dotnet sln LocalRagConsoleDemo.sln add LocalRagConsoleDemo/LocalRagConsoleDemo.csproj

dotnet sln LocalRagConsoleDemo.sln add LocalRagConsoleUnitTests/LocalRagConsoleUnitTests.csproj --solution-folder "Unit Tests"

dotnet sln LocalRagConsoleDemo.sln add LocalRagConsoleIntegrationTests/LocalRagConsoleIntegrationTests.csproj --solution-folder "Unit Tests"

Now we have a solution set up with proper separation of concerns – a main console project for our RAG application and separate projects for unit and integration tests. In the next section, we’ll add the required NuGet packages and start building our connection to PostgreSQL.

You can verify everything is set up correctly by opening LocalRagConsoleDemo.sln in Visual Studio or your preferred IDE. You should see:

Two test projects organized in a “Unit Tests” solution folder and a main console project.

Adding Dependencies

Navigate to the LocalRagConsoleDemo project folder and add our initial NuGet packages:

dotnet add package Microsoft.Extensions.Http
dotnet add package Newtonsoft.Json

At this point, you should have a working solution structure:

  • A main console project
  • Two test projects in a “Unit Tests” solution folder
  • Basic HTTP and JSON handling capabilities

You can verify the setup by opening LocalRagConsoleDemo.sln in Visual Studio or your preferred IDE.

What’s Next?
I’ll be back soon with a detailed walkthrough of building the RAG application. In the meantime, you can check out the working code at:

https://github.com/jimsowers/LocalRAGConsoleDemo

Happy Coding!
-Jim

Local RAG with .NET, Postgres, and Ollama: Ollama Setup (Part 2)

In Part 1, we set up a PostgreSQL database with pgvector extension in a Docker container (that’s a mouthful of tech terms – sorry!).

Our goal is to build a local RAG (Retrieval-Augmented Generation) application combining Postgres for vector storage with a local AI model. Now, we’ll use Docker to run Ollama, an open-source tool that lets us run AI models locally on our machine.

Step 1: Pulling the Ollama Docker container

You can pull the ollama image in a powershell prompt from docker hub with this command:


 docker pull ollama/ollama

Or, you can use the search bar in docker desktop :

We already should have Docker running with Postgres with pgvector and now we will start the Ollama container also.

Step 2: Starting the Ollama container

Before you start Ollama, you should read the Docker Hub docs about starting it correctly for your video card / computer settings https://hub.docker.com/r/ollama/ollama. You click run on the container in Docker desktop, but if you use the proper startup settings for the GPU you have, it may run much much better.

For instance, I have used this startup from a command line:

docker run --name ollamaLocal --hostname=ollamaLocal --env=CUDA_VISIBLE_DEVICES=0 --env=GPU_MEMORY_UTILIZATION=90 --env=GPU_LAYERS=35 --env=NVIDIA_DRIVER_CAPABILITIES=compute,utility --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OLLAMA_HOST=0.0.0.0 --env=LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64 --env=NVIDIA_VISIBLE_DEVICES=all --volume=ollama:/root/.ollama --network=bridge -p 11434:11434 --restart=no --label='org.opencontainers.image.ref.name=ubuntu' --label='org.opencontainers.image.version=22.04' --runtime=runc -d sha256:f1fd985cee59a6403508e3ba26367744eafad7b7383ba960d80872aae61661b6

Check that Docker is running with this command:

docker ps

That should return something like this:

showing both Ollama and Postgres with pgvector are running.

To see if you already have models installed, you can execute the following command in PowerShell (please note that I did not include the full container ID—only enough characters to uniquely identify it: ‘5d5’—and typically, three characters are enough):

docker exec -it ollamaLocal ollama list

In this container, I already have phi4, deepseek-r1, and llama3.

For this project , I want to use Phi4 from Microsoft to start.

We will use the docker exec command to open an interactive terminal:

docker exec -it ollamaLocal /bin/sh

Then the pull command in the docker terminal:

ollama pull phi4

Step 3: Check that Phi4 is running in Ollama:

Staying in the interactive terminal (at the # prompt) – run this command:

ollama run phi4 "Tell me a joke about a duck and a pencil"

You should get a response from the phi4 model something like this:

To get out of the interactive terminal, type exit of Ctrl+D.

There you go – if all that went well, you have the phi4 language model running locally! Let’s review what we’ve accomplished:

  • Postgres with pgvector is running in a Docker container
  • Ollama is running with GPU optimization
  • Microsoft’s Phi4 model is ready to use

In the next articles, we’ll build a .NET application that ties these pieces together. We’ll cover generating embeddings from our documents, storing them in pgvector, and using Phi4 to answer questions based on our stored knowledge.

If you need to stop the containers, you can use docker stop with your container IDs, or use Docker Desktop to stop them.

Local RAG with .NET, Postgres, and Ollama: Postgres with pgvector Setup (Part 1)

Step 1: Set Up Postgres Locally with the pgvector Extension

In this series, we’ll build a RAG (Retrieval-Augmented Generation) application that runs completely on your local machine. RAG systems use AI to answer questions based on your specific documents or data. The first component we need is a vector database to store and search through our document embeddings1. We’ll use Postgreswith the pgvector extension, which adds support for vector similarity search.

To make things easy to start, I am going to use a Docker container to run PostgreSQL with the pgvector extension instead of installing and configuring Postgres locally. This makes sure we all have the same setup and avoids configuration issues across different operating systems.

To make it easy to start, I am going to use a Docker container to run Postgres with the pgvector extension instead of installing and configuring it locally.

In a powershell prompt, I pull the image:

docker pull pgvector/pgvector:pg16

This pulled the code from docker hub here : https://hub.docker.com/r/pgvector/pgvector

At the time or this post, I got an image ‘pgvector/pgvector’ with tag pg16. You can see this by running this command in PowerShell:

docker images

Once you have the image, you can run it – starting the container with this command:

docker run -d --name postgres__with_pgvector -e POSTGRES_PASSWORD=password99 -e POSTGRES_USER=postgres -e POSTGRES_DB=vectordb -p 5432:5432 pgvector/pgvector:pg16

You can also do this start-up visually using Docker Desktop if you prefer:

Click on the images link on the left menu on Docker Desktop and then click the run triangle next to the image you just downloaded. You will put the parameters in the command line above into environment variables like this:

Click on the Containers cube link on the left and you will see your container is running.

Next, you can connect to postgres in the container with the command:

 docker exec -it postgres_with_pgvector psql -U postgres

That should give you a postgres prompt ‘postgres=#’

Let’s test that everything is connected and working now with these commands (hitting enter after each line):

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE items (
    id bigserial PRIMARY KEY,
    embedding vector(3)
);
INSERT INTO items (embedding) VALUES ('[1,2,3]');
SELECT * FROM items;

The select should return:

 id | embedding
----+-----------
  1 | [1,2,3]
(1 row)

To get out of the sql prompt, type ‘\q’

Let’s review what we’ve accomplished:

  • Postgres is running in a Docker container
  • The pgvector extension is installed and working
  • We’ve verified we can store and retrieve vector data

In Part 2, we’ll set up Ollama to run an AI model locally. This will allow us to generate the vector embeddings that we’ll store in our Postgres database. Then in Part 3, we’ll create a .NET application that brings these components together into a complete RAG system.

If you need to stop the container, you can use:

docker stop postgres__with_pgvector

Or use Docker Desktop to stop it. Your data will persist for next time.

See you in Part 2!
-Jim

  1. Embeddings are mathematical representations of objects like text, images, and audio. They are used by machine learning (ML) and artificial intelligence (AI) systems to understand complex relationships in data.  ↩︎