container-superposition 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -15
- package/dist/scripts/init.js +1 -1537
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/cli/args.d.ts +20 -0
- package/dist/tool/cli/args.d.ts.map +1 -0
- package/dist/tool/cli/args.js +325 -0
- package/dist/tool/cli/args.js.map +1 -0
- package/dist/tool/cli/run.d.ts +2 -0
- package/dist/tool/cli/run.d.ts.map +1 -0
- package/dist/tool/cli/run.js +318 -0
- package/dist/tool/cli/run.js.map +1 -0
- package/dist/tool/commands/doctor.d.ts.map +1 -1
- package/dist/tool/commands/doctor.js +141 -6
- package/dist/tool/commands/doctor.js.map +1 -1
- package/dist/tool/commands/explain.d.ts.map +1 -1
- package/dist/tool/commands/explain.js +9 -0
- package/dist/tool/commands/explain.js.map +1 -1
- package/dist/tool/commands/migrate.d.ts +7 -0
- package/dist/tool/commands/migrate.d.ts.map +1 -0
- package/dist/tool/commands/migrate.js +52 -0
- package/dist/tool/commands/migrate.js.map +1 -0
- package/dist/tool/questionnaire/answers.d.ts +16 -0
- package/dist/tool/questionnaire/answers.d.ts.map +1 -0
- package/dist/tool/questionnaire/answers.js +102 -0
- package/dist/tool/questionnaire/answers.js.map +1 -0
- package/dist/tool/questionnaire/composer.d.ts +3 -3
- package/dist/tool/questionnaire/composer.d.ts.map +1 -1
- package/dist/tool/questionnaire/composer.js +691 -27
- package/dist/tool/questionnaire/composer.js.map +1 -1
- package/dist/tool/questionnaire/presets.d.ts +60 -0
- package/dist/tool/questionnaire/presets.d.ts.map +1 -0
- package/dist/tool/questionnaire/presets.js +164 -0
- package/dist/tool/questionnaire/presets.js.map +1 -0
- package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
- package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
- package/dist/tool/questionnaire/questionnaire.js +580 -0
- package/dist/tool/questionnaire/questionnaire.js.map +1 -0
- package/dist/tool/schema/manifest-migrations.d.ts +5 -0
- package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
- package/dist/tool/schema/manifest-migrations.js +45 -0
- package/dist/tool/schema/manifest-migrations.js.map +1 -1
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
- package/dist/tool/schema/overlay-loader.js +24 -0
- package/dist/tool/schema/overlay-loader.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +13 -1
- package/dist/tool/schema/project-config.d.ts.map +1 -1
- package/dist/tool/schema/project-config.js +183 -9
- package/dist/tool/schema/project-config.js.map +1 -1
- package/dist/tool/schema/target-rules.d.ts +78 -0
- package/dist/tool/schema/target-rules.d.ts.map +1 -0
- package/dist/tool/schema/target-rules.js +367 -0
- package/dist/tool/schema/target-rules.js.map +1 -0
- package/dist/tool/schema/types.d.ts +38 -1
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/parameters.d.ts +76 -0
- package/dist/tool/utils/parameters.d.ts.map +1 -0
- package/dist/tool/utils/parameters.js +125 -0
- package/dist/tool/utils/parameters.js.map +1 -0
- package/dist/tool/utils/paths.d.ts +2 -0
- package/dist/tool/utils/paths.d.ts.map +1 -0
- package/dist/tool/utils/paths.js +31 -0
- package/dist/tool/utils/paths.js.map +1 -0
- package/docs/deployment-targets.md +88 -56
- package/docs/examples.md +20 -17
- package/docs/filesystem-contract.md +5 -0
- package/docs/minimal-and-editor.md +65 -5
- package/docs/overlay-imports.md +92 -14
- package/docs/overlays.md +113 -28
- package/docs/specs/007-init-project-file/spec.md +66 -0
- package/docs/specs/007-target-aware-generation/spec.md +126 -0
- package/docs/specs/008-project-file-canonical/spec.md +83 -0
- package/docs/specs/009-project-env/spec.md +147 -0
- package/docs/specs/010-compose-env-materialization/spec.md +130 -0
- package/docs/specs/011-overlay-parameters/spec.md +235 -0
- package/overlays/.shared/README.md +27 -2
- package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
- package/overlays/comfyui/.env.example +34 -0
- package/overlays/comfyui/README.md +342 -0
- package/overlays/comfyui/devcontainer.patch.json +15 -0
- package/overlays/comfyui/docker-compose.yml +39 -0
- package/overlays/comfyui/overlay.yml +20 -0
- package/overlays/comfyui/setup.sh +36 -0
- package/overlays/comfyui/verify.sh +103 -0
- package/overlays/k3d/README.md +201 -0
- package/overlays/k3d/devcontainer.patch.json +9 -0
- package/overlays/k3d/overlay.yml +19 -0
- package/overlays/k3d/setup.sh +34 -0
- package/overlays/k3d/verify.sh +38 -0
- package/overlays/ollama/.env.example +14 -0
- package/overlays/ollama/README.md +325 -0
- package/overlays/ollama/devcontainer.patch.json +14 -0
- package/overlays/ollama/docker-compose.yml +24 -0
- package/overlays/ollama/overlay.yml +22 -0
- package/overlays/ollama/setup.sh +106 -0
- package/overlays/ollama/verify.sh +99 -0
- package/overlays/open-webui/.env.example +5 -0
- package/overlays/open-webui/README.md +162 -0
- package/overlays/open-webui/devcontainer.patch.json +14 -0
- package/overlays/open-webui/docker-compose.yml +23 -0
- package/overlays/open-webui/overlay.yml +38 -0
- package/overlays/pgvector/.env.example +6 -0
- package/overlays/pgvector/README.md +215 -0
- package/overlays/pgvector/devcontainer.patch.json +23 -0
- package/overlays/pgvector/docker-compose.yml +32 -0
- package/overlays/pgvector/overlay.yml +44 -0
- package/overlays/postgres/.env.example +5 -5
- package/overlays/postgres/devcontainer.patch.json +4 -4
- package/overlays/postgres/docker-compose.yml +10 -6
- package/overlays/postgres/overlay.yml +19 -1
- package/overlays/qdrant/.env.example +4 -0
- package/overlays/qdrant/README.md +216 -0
- package/overlays/qdrant/devcontainer.patch.json +20 -0
- package/overlays/qdrant/docker-compose.yml +25 -0
- package/overlays/qdrant/overlay.yml +40 -0
- package/overlays/skaffold/README.md +256 -0
- package/overlays/skaffold/devcontainer.patch.json +9 -0
- package/overlays/skaffold/overlay.yml +20 -0
- package/overlays/skaffold/setup.sh +33 -0
- package/overlays/skaffold/verify.sh +24 -0
- package/package.json +3 -2
- package/tool/schema/config.schema.json +31 -1
- package/tool/schema/overlay-manifest.schema.json +33 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# pgvector Overlay
|
|
2
|
+
|
|
3
|
+
Adds a PostgreSQL 16 database pre-loaded with the [pgvector](https://github.com/pgvector/pgvector) extension, enabling vector similarity search directly within a familiar SQL environment.
|
|
4
|
+
|
|
5
|
+
> **Note:** This overlay conflicts with the `postgres` overlay because both provide a PostgreSQL service on port 5432. Choose `pgvector` when you need vector search, or `postgres` for a plain database.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **pgvector extension** — `CREATE EXTENSION vector;` is available immediately; no manual installation required
|
|
10
|
+
- **Full PostgreSQL 16** — All standard SQL features alongside vector operations
|
|
11
|
+
- **`psql` client in devcontainer** — `postgresql-client` package installed for interactive SQL sessions
|
|
12
|
+
- **Pre-configured environment** — `PGHOST`, `PGPORT`, `PGDATABASE`, and `PGUSER` set automatically
|
|
13
|
+
- **Persistent storage** — Named Docker volume preserves data across container rebuilds
|
|
14
|
+
- **Health check** — Compose readiness check using `pg_isready` before dependent services start
|
|
15
|
+
|
|
16
|
+
## How It Works
|
|
17
|
+
|
|
18
|
+
pgvector runs as a Docker Compose service (`pgvector`) alongside your devcontainer, using the official `pgvector/pgvector:pg16` image, which bundles PostgreSQL 16 with the pgvector extension pre-compiled and ready to use.
|
|
19
|
+
|
|
20
|
+
**Service configuration:**
|
|
21
|
+
|
|
22
|
+
- Image: `pgvector/pgvector:pg16`
|
|
23
|
+
- Network: `devnet` (shared with the dev container)
|
|
24
|
+
- Port: `5432` (customisable via `PGVECTOR_PORT`)
|
|
25
|
+
- Volume: `pgvector-data` for persistent data
|
|
26
|
+
|
|
27
|
+
The following environment variables are pre-set in the devcontainer for seamless `psql` usage:
|
|
28
|
+
|
|
29
|
+
| Variable | Value |
|
|
30
|
+
| ------------ | ---------- |
|
|
31
|
+
| `PGHOST` | `pgvector` |
|
|
32
|
+
| `PGPORT` | `5432` |
|
|
33
|
+
| `PGDATABASE` | `devdb` |
|
|
34
|
+
| `PGUSER` | `postgres` |
|
|
35
|
+
|
|
36
|
+
## Getting Started
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Connect to the database
|
|
40
|
+
psql -h pgvector -U postgres -d devdb
|
|
41
|
+
|
|
42
|
+
# Enable the vector extension (run once per database)
|
|
43
|
+
psql -h pgvector -U postgres -d devdb -c "CREATE EXTENSION IF NOT EXISTS vector;"
|
|
44
|
+
|
|
45
|
+
# Verify the extension is installed
|
|
46
|
+
psql -h pgvector -U postgres -d devdb -c "SELECT * FROM pg_extension WHERE extname = 'vector';"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Common Commands
|
|
50
|
+
|
|
51
|
+
### Vector Operations in SQL
|
|
52
|
+
|
|
53
|
+
```sql
|
|
54
|
+
-- Enable the extension in your database
|
|
55
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
56
|
+
|
|
57
|
+
-- Create a table with a vector column (1536 dimensions for OpenAI embeddings)
|
|
58
|
+
CREATE TABLE documents (
|
|
59
|
+
id SERIAL PRIMARY KEY,
|
|
60
|
+
content TEXT,
|
|
61
|
+
embedding vector(1536)
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
-- Insert a record with an embedding
|
|
65
|
+
INSERT INTO documents (content, embedding)
|
|
66
|
+
VALUES ('Hello, world!', '[0.1, 0.2, 0.3, ...]');
|
|
67
|
+
|
|
68
|
+
-- Cosine similarity search (find closest neighbours)
|
|
69
|
+
SELECT id, content, 1 - (embedding <=> '[0.1, 0.2, 0.3, ...]') AS similarity
|
|
70
|
+
FROM documents
|
|
71
|
+
ORDER BY embedding <=> '[0.1, 0.2, 0.3, ...]'
|
|
72
|
+
LIMIT 5;
|
|
73
|
+
|
|
74
|
+
-- Create an HNSW index for faster approximate search
|
|
75
|
+
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
|
|
76
|
+
|
|
77
|
+
-- Create an IVFFlat index for large datasets
|
|
78
|
+
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Database Management
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Connect interactively
|
|
85
|
+
psql
|
|
86
|
+
|
|
87
|
+
# Run a SQL file
|
|
88
|
+
psql -f schema.sql
|
|
89
|
+
|
|
90
|
+
# Dump the database
|
|
91
|
+
pg_dump -h pgvector -U postgres devdb > backup.sql
|
|
92
|
+
|
|
93
|
+
# Restore from dump
|
|
94
|
+
psql -h pgvector -U postgres devdb < backup.sql
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Python Integration
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install psycopg2-binary pgvector
|
|
101
|
+
|
|
102
|
+
python - <<'EOF'
|
|
103
|
+
import psycopg2
|
|
104
|
+
from pgvector.psycopg2 import register_vector
|
|
105
|
+
import numpy as np
|
|
106
|
+
|
|
107
|
+
conn = psycopg2.connect(
|
|
108
|
+
host="pgvector", port=5432,
|
|
109
|
+
dbname="devdb", user="postgres", password="postgres"
|
|
110
|
+
)
|
|
111
|
+
register_vector(conn)
|
|
112
|
+
cur = conn.cursor()
|
|
113
|
+
|
|
114
|
+
cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
|
|
115
|
+
cur.execute("CREATE TABLE IF NOT EXISTS items (id serial PRIMARY KEY, embedding vector(3))")
|
|
116
|
+
cur.execute("INSERT INTO items (embedding) VALUES (%s)", (np.array([1, 2, 3]),))
|
|
117
|
+
conn.commit()
|
|
118
|
+
|
|
119
|
+
cur.execute("SELECT * FROM items ORDER BY embedding <-> %s LIMIT 5", (np.array([1, 2, 4]),))
|
|
120
|
+
print(cur.fetchall())
|
|
121
|
+
conn.close()
|
|
122
|
+
EOF
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Configuration
|
|
126
|
+
|
|
127
|
+
### Environment Variables
|
|
128
|
+
|
|
129
|
+
| Variable | Default | Description |
|
|
130
|
+
| ------------------- | ---------- | ------------------------------------------ |
|
|
131
|
+
| `PGVECTOR_VERSION` | `pg16` | pgvector image tag (e.g. `pg16`, `pg17`) |
|
|
132
|
+
| `PGVECTOR_DB` | `devdb` | Name of the database to create |
|
|
133
|
+
| `PGVECTOR_USER` | `postgres` | PostgreSQL superuser name |
|
|
134
|
+
| `PGVECTOR_PASSWORD` | `postgres` | PostgreSQL superuser password |
|
|
135
|
+
| `PGVECTOR_PORT` | `5432` | Host port mapped to the PostgreSQL service |
|
|
136
|
+
|
|
137
|
+
Copy `.devcontainer/.env.example` to `.devcontainer/.env` and customize.
|
|
138
|
+
|
|
139
|
+
## pgvector vs Qdrant
|
|
140
|
+
|
|
141
|
+
| Feature | pgvector (this overlay) | Qdrant |
|
|
142
|
+
| -------------------- | ------------------------------- | ------------------------ |
|
|
143
|
+
| **Storage model** | ✅ Relational + vector | Vector-only |
|
|
144
|
+
| **SQL support** | ✅ Full PostgreSQL SQL | ❌ REST/gRPC API only |
|
|
145
|
+
| **Familiar tooling** | ✅ psql, ORMs, existing schema | New client SDKs required |
|
|
146
|
+
| **Query language** | ✅ SQL with `<->`, `<=>`, `<#>` | ⚠️ JSON query DSL |
|
|
147
|
+
| **Filtering** | ✅ SQL WHERE clause | ✅ Payload-based filters |
|
|
148
|
+
| **Scale** | ⚠️ Vertical scaling preferred | ✅ Distributed by design |
|
|
149
|
+
| **Index types** | IVFFlat, HNSW | HNSW |
|
|
150
|
+
|
|
151
|
+
**Choose pgvector when:**
|
|
152
|
+
|
|
153
|
+
- You already use PostgreSQL and want to add vectors to existing tables
|
|
154
|
+
- You need to join vector results with relational data
|
|
155
|
+
- Your team is comfortable with SQL
|
|
156
|
+
|
|
157
|
+
**Choose Qdrant when:**
|
|
158
|
+
|
|
159
|
+
- Vectors are your primary data model
|
|
160
|
+
- You need purpose-built vector search performance at scale
|
|
161
|
+
- You want advanced filtering and payload storage
|
|
162
|
+
|
|
163
|
+
## Use Cases
|
|
164
|
+
|
|
165
|
+
- **RAG pipelines** — Store document embeddings alongside metadata; retrieve context with SQL joins
|
|
166
|
+
- **Semantic search** — Add vector search to an existing PostgreSQL application without a second database
|
|
167
|
+
- **Hybrid search** — Combine full-text search (`tsvector`) with vector similarity in a single query
|
|
168
|
+
- **Recommendation systems** — Store and query user or item embeddings with familiar SQL tooling
|
|
169
|
+
|
|
170
|
+
**Integrates well with:**
|
|
171
|
+
|
|
172
|
+
- `ollama` — Generate embeddings locally with `nomic-embed-text` or similar models
|
|
173
|
+
- `python` — `psycopg2` + `pgvector` Python package for seamless integration
|
|
174
|
+
- `nodejs` — `pg` driver with raw SQL for vector operations
|
|
175
|
+
|
|
176
|
+
## Troubleshooting
|
|
177
|
+
|
|
178
|
+
### Extension Not Found
|
|
179
|
+
|
|
180
|
+
If `CREATE EXTENSION vector` fails:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Confirm pgvector image (not plain postgres) is in use
|
|
184
|
+
docker compose ps pgvector
|
|
185
|
+
|
|
186
|
+
# Check available extensions
|
|
187
|
+
psql -h pgvector -U postgres -c "SELECT name FROM pg_available_extensions WHERE name = 'vector';"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Port Conflict with postgres Overlay
|
|
191
|
+
|
|
192
|
+
The `pgvector` and `postgres` overlays both bind port 5432 and conflict with each other. Select only one.
|
|
193
|
+
|
|
194
|
+
### Connection Refused
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Check service health
|
|
198
|
+
docker compose ps pgvector
|
|
199
|
+
docker compose logs pgvector
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## References
|
|
203
|
+
|
|
204
|
+
- [pgvector GitHub](https://github.com/pgvector/pgvector)
|
|
205
|
+
- [pgvector Docker Image](https://hub.docker.com/r/pgvector/pgvector)
|
|
206
|
+
- [PostgreSQL Documentation](https://www.postgresql.org/docs/16/)
|
|
207
|
+
- [pgvector Python package](https://github.com/pgvector/pgvector-python)
|
|
208
|
+
- [pgvector Node.js package](https://github.com/pgvector/pgvector-node)
|
|
209
|
+
|
|
210
|
+
**Related Overlays:**
|
|
211
|
+
|
|
212
|
+
- [`postgres`](../postgres/README.md) — Plain PostgreSQL without pgvector (conflicts)
|
|
213
|
+
- [`qdrant`](../qdrant/README.md) — Purpose-built vector database (alternative)
|
|
214
|
+
- [`ollama`](../ollama/README.md) — Local embedding generation
|
|
215
|
+
- [`python`](../python/README.md) — Python development environment
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
|
|
3
|
+
"runServices": ["pgvector"],
|
|
4
|
+
"forwardPorts": [5432],
|
|
5
|
+
"portsAttributes": {
|
|
6
|
+
"5432": {
|
|
7
|
+
"label": "pgvector database",
|
|
8
|
+
"onAutoForward": "notify"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"features": {
|
|
12
|
+
"./features/cross-distro-packages": {
|
|
13
|
+
"apt": "postgresql-client",
|
|
14
|
+
"apk": "postgresql-client"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"containerEnv": {
|
|
18
|
+
"PGHOST": "pgvector",
|
|
19
|
+
"PGPORT": "5432",
|
|
20
|
+
"PGDATABASE": "devdb",
|
|
21
|
+
"PGUSER": "postgres"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
pgvector:
|
|
5
|
+
image: pgvector/pgvector:${PGVECTOR_VERSION:-{{cs.PGVECTOR_VERSION}}}
|
|
6
|
+
restart: unless-stopped
|
|
7
|
+
volumes:
|
|
8
|
+
- pgvector-data:/var/lib/postgresql/data
|
|
9
|
+
environment:
|
|
10
|
+
POSTGRES_DB: ${PGVECTOR_DB:-{{cs.PGVECTOR_DB}}}
|
|
11
|
+
POSTGRES_USER: ${PGVECTOR_USER:-{{cs.PGVECTOR_USER}}}
|
|
12
|
+
POSTGRES_PASSWORD: ${PGVECTOR_PASSWORD:-{{cs.PGVECTOR_PASSWORD}}}
|
|
13
|
+
ports:
|
|
14
|
+
- '${PGVECTOR_PORT:-{{cs.PGVECTOR_PORT}}}:5432'
|
|
15
|
+
networks:
|
|
16
|
+
- devnet
|
|
17
|
+
healthcheck:
|
|
18
|
+
test:
|
|
19
|
+
[
|
|
20
|
+
'CMD-SHELL',
|
|
21
|
+
'pg_isready -U ${PGVECTOR_USER:-{{cs.PGVECTOR_USER}}} -d ${PGVECTOR_DB:-{{cs.PGVECTOR_DB}}}',
|
|
22
|
+
]
|
|
23
|
+
interval: 10s
|
|
24
|
+
timeout: 5s
|
|
25
|
+
retries: 5
|
|
26
|
+
start_period: 10s
|
|
27
|
+
|
|
28
|
+
volumes:
|
|
29
|
+
pgvector-data:
|
|
30
|
+
|
|
31
|
+
networks:
|
|
32
|
+
devnet:
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
id: pgvector
|
|
2
|
+
name: pgvector (PostgreSQL + vector)
|
|
3
|
+
description: PostgreSQL 16 with the pgvector extension for vector similarity search
|
|
4
|
+
category: database
|
|
5
|
+
supports:
|
|
6
|
+
- compose
|
|
7
|
+
requires: []
|
|
8
|
+
suggests:
|
|
9
|
+
- ollama
|
|
10
|
+
- python
|
|
11
|
+
- nodejs
|
|
12
|
+
conflicts:
|
|
13
|
+
- postgres
|
|
14
|
+
tags:
|
|
15
|
+
- database
|
|
16
|
+
- sql
|
|
17
|
+
- vector
|
|
18
|
+
- embeddings
|
|
19
|
+
- postgres
|
|
20
|
+
- pgvector
|
|
21
|
+
ports:
|
|
22
|
+
- port: 5432
|
|
23
|
+
service: pgvector
|
|
24
|
+
protocol: tcp
|
|
25
|
+
description: pgvector database connection
|
|
26
|
+
onAutoForward: notify
|
|
27
|
+
connectionStringTemplate: 'postgresql://{pgvector_user}:{pgvector_password}@{host}:{port}/{pgvector_db}'
|
|
28
|
+
parameters:
|
|
29
|
+
PGVECTOR_DB:
|
|
30
|
+
description: Name of the database to create
|
|
31
|
+
default: devdb
|
|
32
|
+
PGVECTOR_USER:
|
|
33
|
+
description: PostgreSQL superuser name
|
|
34
|
+
default: postgres
|
|
35
|
+
PGVECTOR_PASSWORD:
|
|
36
|
+
description: PostgreSQL superuser password
|
|
37
|
+
default: postgres
|
|
38
|
+
sensitive: true
|
|
39
|
+
PGVECTOR_PORT:
|
|
40
|
+
description: Host port mapped to pgvector (5432 inside container)
|
|
41
|
+
default: '5432'
|
|
42
|
+
PGVECTOR_VERSION:
|
|
43
|
+
description: pgvector/pgvector image tag (e.g. pg16, pg17)
|
|
44
|
+
default: pg16
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# PostgreSQL Configuration
|
|
2
|
-
POSTGRES_VERSION=
|
|
3
|
-
POSTGRES_DB=
|
|
4
|
-
POSTGRES_USER=
|
|
5
|
-
POSTGRES_PASSWORD=
|
|
6
|
-
POSTGRES_PORT=
|
|
2
|
+
POSTGRES_VERSION={{cs.POSTGRES_VERSION}}
|
|
3
|
+
POSTGRES_DB={{cs.POSTGRES_DB}}
|
|
4
|
+
POSTGRES_USER={{cs.POSTGRES_USER}}
|
|
5
|
+
POSTGRES_PASSWORD={{cs.POSTGRES_PASSWORD}}
|
|
6
|
+
POSTGRES_PORT={{cs.POSTGRES_PORT}}
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"remoteEnv": {
|
|
15
15
|
"POSTGRES_HOST": "postgres",
|
|
16
|
-
"POSTGRES_PORT": "
|
|
17
|
-
"POSTGRES_DB": "
|
|
18
|
-
"POSTGRES_USER": "
|
|
19
|
-
"POSTGRES_PASSWORD": "
|
|
16
|
+
"POSTGRES_PORT": "{{cs.POSTGRES_PORT}}",
|
|
17
|
+
"POSTGRES_DB": "{{cs.POSTGRES_DB}}",
|
|
18
|
+
"POSTGRES_USER": "{{cs.POSTGRES_USER}}",
|
|
19
|
+
"POSTGRES_PASSWORD": "{{cs.POSTGRES_PASSWORD}}"
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -2,20 +2,24 @@ version: '3.8'
|
|
|
2
2
|
|
|
3
3
|
services:
|
|
4
4
|
postgres:
|
|
5
|
-
image: postgres:${POSTGRES_VERSION:-
|
|
5
|
+
image: postgres:${POSTGRES_VERSION:-{{cs.POSTGRES_VERSION}}}-alpine
|
|
6
6
|
restart: unless-stopped
|
|
7
7
|
volumes:
|
|
8
8
|
- postgres-data:/var/lib/postgresql/data
|
|
9
9
|
environment:
|
|
10
|
-
POSTGRES_DB: ${POSTGRES_DB:-
|
|
11
|
-
POSTGRES_USER: ${POSTGRES_USER:-
|
|
12
|
-
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-
|
|
10
|
+
POSTGRES_DB: ${POSTGRES_DB:-{{cs.POSTGRES_DB}}}
|
|
11
|
+
POSTGRES_USER: ${POSTGRES_USER:-{{cs.POSTGRES_USER}}}
|
|
12
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-{{cs.POSTGRES_PASSWORD}}}
|
|
13
13
|
ports:
|
|
14
|
-
- '${POSTGRES_PORT:-
|
|
14
|
+
- '${POSTGRES_PORT:-{{cs.POSTGRES_PORT}}}:5432'
|
|
15
15
|
networks:
|
|
16
16
|
- devnet
|
|
17
17
|
healthcheck:
|
|
18
|
-
test:
|
|
18
|
+
test:
|
|
19
|
+
[
|
|
20
|
+
'CMD-SHELL',
|
|
21
|
+
'pg_isready -U ${POSTGRES_USER:-{{cs.POSTGRES_USER}}} -d ${POSTGRES_DB:-{{cs.POSTGRES_DB}}}',
|
|
22
|
+
]
|
|
19
23
|
interval: 10s
|
|
20
24
|
timeout: 5s
|
|
21
25
|
retries: 5
|
|
@@ -6,7 +6,8 @@ supports:
|
|
|
6
6
|
- compose
|
|
7
7
|
requires: []
|
|
8
8
|
suggests: []
|
|
9
|
-
conflicts:
|
|
9
|
+
conflicts:
|
|
10
|
+
- pgvector
|
|
10
11
|
tags:
|
|
11
12
|
- database
|
|
12
13
|
- sql
|
|
@@ -18,3 +19,20 @@ ports:
|
|
|
18
19
|
description: PostgreSQL database connection
|
|
19
20
|
onAutoForward: notify
|
|
20
21
|
connectionStringTemplate: 'postgresql://{postgres_user}:{postgres_password}@{host}:{port}/{postgres_db}'
|
|
22
|
+
parameters:
|
|
23
|
+
POSTGRES_DB:
|
|
24
|
+
description: Name of the database to create
|
|
25
|
+
default: devdb
|
|
26
|
+
POSTGRES_USER:
|
|
27
|
+
description: PostgreSQL superuser name
|
|
28
|
+
default: postgres
|
|
29
|
+
POSTGRES_PASSWORD:
|
|
30
|
+
description: PostgreSQL superuser password
|
|
31
|
+
default: postgres
|
|
32
|
+
sensitive: true
|
|
33
|
+
POSTGRES_PORT:
|
|
34
|
+
description: Host port mapped to PostgreSQL (5432 inside container)
|
|
35
|
+
default: '5432'
|
|
36
|
+
POSTGRES_VERSION:
|
|
37
|
+
description: PostgreSQL major version
|
|
38
|
+
default: '16'
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Qdrant Overlay
|
|
2
|
+
|
|
3
|
+
Adds [Qdrant](https://qdrant.tech) as a Docker Compose service, providing a high-performance vector database for similarity search and embedding-based retrieval.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Qdrant vector database** — Store, index, and query high-dimensional embedding vectors at scale
|
|
8
|
+
- **REST API on port 6333** — Full-featured HTTP API for collections, points, and search
|
|
9
|
+
- **gRPC API on port 6334** — High-throughput binary protocol for production workloads
|
|
10
|
+
- **Persistent storage** — Named Docker volume preserves data across container rebuilds
|
|
11
|
+
- **Pre-configured `QDRANT_URL`** — Container environment variable set for easy SDK usage
|
|
12
|
+
- **Health check** — Compose readiness check against `/readyz` before dependent services start
|
|
13
|
+
|
|
14
|
+
## How It Works
|
|
15
|
+
|
|
16
|
+
Qdrant runs as a Docker Compose service alongside your devcontainer. The devcontainer connects to it using the hostname `qdrant` on port `6333` (REST) or `6334` (gRPC).
|
|
17
|
+
|
|
18
|
+
**Service configuration:**
|
|
19
|
+
|
|
20
|
+
- Image: `qdrant/qdrant:latest`
|
|
21
|
+
- Network: `devnet` (shared with the dev container)
|
|
22
|
+
- Ports: `6333` (REST API), `6334` (gRPC)
|
|
23
|
+
- Volume: `qdrant-data` for persistent vector storage
|
|
24
|
+
|
|
25
|
+
The following environment variables are pre-set in the devcontainer:
|
|
26
|
+
|
|
27
|
+
| Variable | Value |
|
|
28
|
+
| ------------- | -------------------- |
|
|
29
|
+
| `QDRANT_HOST` | `qdrant` |
|
|
30
|
+
| `QDRANT_PORT` | `6333` |
|
|
31
|
+
| `QDRANT_URL` | `http://qdrant:6333` |
|
|
32
|
+
|
|
33
|
+
## Common Commands
|
|
34
|
+
|
|
35
|
+
### REST API
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Health check
|
|
39
|
+
curl http://qdrant:6333/healthz
|
|
40
|
+
|
|
41
|
+
# Create a collection
|
|
42
|
+
curl -X PUT http://qdrant:6333/collections/my_collection \
|
|
43
|
+
-H "Content-Type: application/json" \
|
|
44
|
+
-d '{
|
|
45
|
+
"vectors": {
|
|
46
|
+
"size": 1536,
|
|
47
|
+
"distance": "Cosine"
|
|
48
|
+
}
|
|
49
|
+
}'
|
|
50
|
+
|
|
51
|
+
# Insert points
|
|
52
|
+
curl -X PUT http://qdrant:6333/collections/my_collection/points \
|
|
53
|
+
-H "Content-Type: application/json" \
|
|
54
|
+
-d '{
|
|
55
|
+
"points": [
|
|
56
|
+
{
|
|
57
|
+
"id": 1,
|
|
58
|
+
"vector": [0.1, 0.2, 0.3],
|
|
59
|
+
"payload": {"text": "example document"}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}'
|
|
63
|
+
|
|
64
|
+
# Search for similar vectors
|
|
65
|
+
curl -X POST http://qdrant:6333/collections/my_collection/points/search \
|
|
66
|
+
-H "Content-Type: application/json" \
|
|
67
|
+
-d '{
|
|
68
|
+
"vector": [0.1, 0.2, 0.3],
|
|
69
|
+
"limit": 5
|
|
70
|
+
}'
|
|
71
|
+
|
|
72
|
+
# List collections
|
|
73
|
+
curl http://qdrant:6333/collections
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Python SDK
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install qdrant-client
|
|
80
|
+
|
|
81
|
+
python - <<'EOF'
|
|
82
|
+
from qdrant_client import QdrantClient
|
|
83
|
+
from qdrant_client.models import Distance, VectorParams, PointStruct
|
|
84
|
+
|
|
85
|
+
client = QdrantClient(url="http://qdrant:6333")
|
|
86
|
+
|
|
87
|
+
# Create collection
|
|
88
|
+
client.create_collection(
|
|
89
|
+
collection_name="my_collection",
|
|
90
|
+
vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Insert vectors
|
|
94
|
+
client.upsert(
|
|
95
|
+
collection_name="my_collection",
|
|
96
|
+
points=[
|
|
97
|
+
PointStruct(id=1, vector=[0.1] * 1536, payload={"text": "hello"})
|
|
98
|
+
],
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Search
|
|
102
|
+
results = client.search(
|
|
103
|
+
collection_name="my_collection",
|
|
104
|
+
query_vector=[0.1] * 1536,
|
|
105
|
+
limit=5,
|
|
106
|
+
)
|
|
107
|
+
print(results)
|
|
108
|
+
EOF
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Node.js SDK
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm install @qdrant/js-client-rest
|
|
115
|
+
|
|
116
|
+
node - <<'EOF'
|
|
117
|
+
import { QdrantClient } from "@qdrant/js-client-rest";
|
|
118
|
+
|
|
119
|
+
const client = new QdrantClient({ url: "http://qdrant:6333" });
|
|
120
|
+
|
|
121
|
+
await client.createCollection("my_collection", {
|
|
122
|
+
vectors: { size: 1536, distance: "Cosine" },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const results = await client.search("my_collection", {
|
|
126
|
+
vector: Array(1536).fill(0.1),
|
|
127
|
+
limit: 5,
|
|
128
|
+
});
|
|
129
|
+
console.log(results);
|
|
130
|
+
EOF
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Configuration
|
|
134
|
+
|
|
135
|
+
### Environment Variables
|
|
136
|
+
|
|
137
|
+
| Variable | Default | Description |
|
|
138
|
+
| ------------------ | -------- | ----------------------- |
|
|
139
|
+
| `QDRANT_VERSION` | `latest` | Qdrant Docker image tag |
|
|
140
|
+
| `QDRANT_PORT` | `6333` | Host port for REST API |
|
|
141
|
+
| `QDRANT_GRPC_PORT` | `6334` | Host port for gRPC API |
|
|
142
|
+
|
|
143
|
+
### Port Customization
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# .devcontainer/.env
|
|
147
|
+
QDRANT_PORT=6335
|
|
148
|
+
QDRANT_GRPC_PORT=6336
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Use Cases
|
|
152
|
+
|
|
153
|
+
- **RAG (Retrieval-Augmented Generation)** — Store embeddings for document chunks; retrieve context for LLM queries
|
|
154
|
+
- **Semantic search** — Find similar documents, images, or code snippets by embedding similarity
|
|
155
|
+
- **Recommendation systems** — Surface similar items based on learned embeddings
|
|
156
|
+
- **Anomaly detection** — Identify outliers in high-dimensional embedding spaces
|
|
157
|
+
- **Local AI pipelines** — Pair with `ollama` for fully offline embedding + retrieval workflows
|
|
158
|
+
|
|
159
|
+
**Integrates well with:**
|
|
160
|
+
|
|
161
|
+
- `ollama` — Generate embeddings locally (`ollama pull nomic-embed-text`)
|
|
162
|
+
- `python` — LangChain, LlamaIndex, or raw `qdrant-client` integrations
|
|
163
|
+
- `nodejs` — `@qdrant/js-client-rest` for JavaScript embeddings workflows
|
|
164
|
+
|
|
165
|
+
## Troubleshooting
|
|
166
|
+
|
|
167
|
+
### Service Not Ready
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Check service status
|
|
171
|
+
docker compose ps qdrant
|
|
172
|
+
|
|
173
|
+
# View Qdrant logs
|
|
174
|
+
docker compose logs qdrant
|
|
175
|
+
|
|
176
|
+
# Test health endpoint
|
|
177
|
+
curl http://qdrant:6333/healthz
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Port Conflict
|
|
181
|
+
|
|
182
|
+
If ports 6333 or 6334 are already in use:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# .devcontainer/.env
|
|
186
|
+
QDRANT_PORT=6335
|
|
187
|
+
QDRANT_GRPC_PORT=6336
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Data Persistence
|
|
191
|
+
|
|
192
|
+
Qdrant data is stored in the `qdrant-data` named Docker volume. It persists across container rebuilds but is scoped to the Docker environment:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Inspect the volume
|
|
196
|
+
docker volume inspect qdrant-data
|
|
197
|
+
|
|
198
|
+
# Backup data
|
|
199
|
+
docker run --rm -v qdrant-data:/data -v $(pwd):/backup alpine \
|
|
200
|
+
tar czf /backup/qdrant-backup.tar.gz /data
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## References
|
|
204
|
+
|
|
205
|
+
- [Qdrant Documentation](https://qdrant.tech/documentation/)
|
|
206
|
+
- [Qdrant REST API Reference](https://qdrant.github.io/qdrant/redoc/index.html)
|
|
207
|
+
- [Qdrant Docker Hub](https://hub.docker.com/r/qdrant/qdrant)
|
|
208
|
+
- [Python SDK](https://python-client.qdrant.tech/)
|
|
209
|
+
- [JavaScript SDK](https://github.com/qdrant/qdrant-js)
|
|
210
|
+
|
|
211
|
+
**Related Overlays:**
|
|
212
|
+
|
|
213
|
+
- [`pgvector`](../pgvector/README.md) — PostgreSQL-native vector storage (alternative; conflicts with `postgres`)
|
|
214
|
+
- [`ollama`](../ollama/README.md) — Local LLM and embedding generation
|
|
215
|
+
- [`python`](../python/README.md) — Python development environment
|
|
216
|
+
- [`nodejs`](../nodejs/README.md) — Node.js development environment
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
|
|
3
|
+
"runServices": ["qdrant"],
|
|
4
|
+
"forwardPorts": [6333, 6334],
|
|
5
|
+
"portsAttributes": {
|
|
6
|
+
"6333": {
|
|
7
|
+
"label": "Qdrant REST API",
|
|
8
|
+
"onAutoForward": "notify"
|
|
9
|
+
},
|
|
10
|
+
"6334": {
|
|
11
|
+
"label": "Qdrant gRPC",
|
|
12
|
+
"onAutoForward": "ignore"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"containerEnv": {
|
|
16
|
+
"QDRANT_HOST": "qdrant",
|
|
17
|
+
"QDRANT_PORT": "6333",
|
|
18
|
+
"QDRANT_URL": "http://qdrant:6333"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
qdrant:
|
|
5
|
+
image: qdrant/qdrant:${QDRANT_VERSION:-{{cs.QDRANT_VERSION}}}
|
|
6
|
+
restart: unless-stopped
|
|
7
|
+
volumes:
|
|
8
|
+
- qdrant-data:/qdrant/storage
|
|
9
|
+
ports:
|
|
10
|
+
- '${QDRANT_PORT:-{{cs.QDRANT_PORT}}}:6333'
|
|
11
|
+
- '${QDRANT_GRPC_PORT:-{{cs.QDRANT_GRPC_PORT}}}:6334'
|
|
12
|
+
networks:
|
|
13
|
+
- devnet
|
|
14
|
+
healthcheck:
|
|
15
|
+
test: ['CMD-SHELL', 'curl -sf http://localhost:6333/readyz || exit 1']
|
|
16
|
+
interval: 10s
|
|
17
|
+
timeout: 5s
|
|
18
|
+
retries: 5
|
|
19
|
+
start_period: 10s
|
|
20
|
+
|
|
21
|
+
volumes:
|
|
22
|
+
qdrant-data:
|
|
23
|
+
|
|
24
|
+
networks:
|
|
25
|
+
devnet:
|