diff --git a/.docs/playgrounds.es.md b/.docs/playgrounds.es.md new file mode 100644 index 0000000..5a000ef --- /dev/null +++ b/.docs/playgrounds.es.md @@ -0,0 +1,170 @@ +# Playgrounds + +> [Read in English](./playgrounds.md) + +Un **playground** es la unidad fundamental de instalación de extensiones. Cada playground representa un paso en el pipeline que transforma una imagen base `postgres:N` en una imagen con extensiones preinstaladas. + +--- + +## Arquitectura + +Cada playground se define en el paquete `extensions/` y se registra en la variable global `Playgrounds` (`extensions/extensions.go`), que es un slice ordenado de `[]*plyd.Playground`. + +### Estructura de un Playground + +```go +type Playground struct { + Name string + handlers HandlersList +} +``` + +Cada playground contiene una lista de **handlers**, donde cada handler asocia un **rango de versiones semver** con una **función ejecutora**: + +```go +type Handler struct { + Range string // Ej: ">=14.0.0, <19.0.0" + Runner HandlerFunc // func(ins *instance.InstanceInfo) error +} +``` + +### Ejecución (`Run`) + +```go +func (p *Playground) Run(ins *instance.InstanceInfo) { + handler := p.matchHandler(ins.PostgreSQL.Version) + if handler == nil { + log.Printf("[WARNING] No handler for PG %s in playground '%s'", ...) + return // No es fatal — el playground simplemente se salta + } + handler.Runner(ins) +} +``` + +--- + +## Versionado + +El versionado usa **semver 2.0** mediante la librería `github.com/Masterminds/semver/v3`. + +### Flujo de matching + +1. Se detecta la versión de PostgreSQL ejecutando `postgres --version`. +2. Se normaliza a semver canónico (ej: `"17"` → `"17.0.0"`). +3. `matchHandler` recorre los handlers en orden: + - Primero busca coincidencia exacta de string. + - Luego evalúa cada rango como `semver.Constraint`. +4. Retorna el primer handler que coincida. + +### Orden de handlers + +Los handlers se ordenan automáticamente en `NewHandlersList`: +- **Versiones exactas primero** (ej: `"17.2.0"`), ascendente. +- **Rangos después** (ej: `">=14.0.0, <19.0.0"`), orden alfabético. + +Esto permite tener overrides específicos por versión antes de caer en rangos genéricos. + +### Ejemplo + +```go +var miExtension = plyd.New("mi-extension", + plyd.NewHandlersList( + plyd.NewHandler(">=16.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y mi-extension") + }), + plyd.NewHandler(">=14.0.0, <16.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y mi-extension-old") + }), + ), +) +``` + +--- + +## Playgrounds por defecto (orden de ejecución) + +El orden en `extensions/extensions.go` es crítico: + +| # | Playground | Archivo | Propósito | +|---|-----------|---------|-----------| +| 1 | `build-deps-install` | `builddeps_install.go` | Instala `git`, `make`, `gcc`, `postgresql-server-dev-MAYOR` | +| 2 | `pgmq` | `pgmq.go` | Clona, compila e instala [PGMQ](https://github.com/pgmq/pgmq) v1.11.1 | +| 3 | `pgvector` | `pgvector.go` | Clona, compila e instala [pgvector](https://github.com/pgvector/pgvector) v0.8.2 | +| 4 | `postgis` | `postgis.go` | Instala `postgresql-MAYOR-postgis-3` vía apt | +| 5 | `postgres-contrib` | `postgrescontrib.go` | Instala `postgresql-MAYOR` (contrib) vía apt | +| 6 | `build-deps-remove` | `builddeps_remove.go` | Desinstala dependencias de build y limpia apt | + +### ¿Por qué este orden? + +1. **Primero** se instalan las herramientas de build (necesarias para compilar pgmq y pgvector desde fuente). +2. **Luego** se compilan e instalan las extensiones que requieren build desde fuente (pgmq, pgvector). +3. **Después** se instalan las extensiones vía apt (postgis, contrib), que necesitan `postgresql-server-dev-MAYOR` ya presente. +4. **Al final** se eliminan las herramientas de build para mantener la imagen final ligera. + +--- + +## Versiones PostgreSQL soportadas + +Actualmente: **14, 15, 16, 17, 18** (y `latest` que apunta a la más reciente). + +Todos los playgrounds usan el rango `>=14.0.0, <19.0.0`. Para ampliar el soporte (ej: PG 19), basta con actualizar los rangos. + +--- + +## Cómo crear un nuevo playground + +### 1. Crear el archivo de extensión + +En `extensions/`, crea un archivo como `miextension.go`: + +```go +package extensions + +import ( + "postgres-extensor/instance" + "postgres-extensor/plyd" +) + +var miExtension = plyd.New("mi-extension", + plyd.NewHandlersList( + plyd.NewHandler(">=14.0.0, <19.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y postgresql-" + ins.PostgreSQL.Mayor + "-mi-extension") + }), + ), +) +``` + +### 2. Registrarlo en el orden correcto + +Edita `extensions/extensions.go` y agrégalo al slice `Playgrounds` en la posición adecuada: + +```go +var Playgrounds = []*plyd.Playground{ + buildDepsInstall, + pgmq, + pgvector, + miExtension, // <-- Nuevo + postgis, + postgresContrib, + buildDepsRemove, +} +``` + +### 3. Verificar la instalación + +Tu handler debería verificar que la extensión quedó instalada: + +```go +verification := "test -f $(pg_config --sharedir)/extension/mi_extension.control" +``` + +### 4. Agregar cobertura en tests + +Edita `.docker/runtime-test.sql` para incluir la nueva extensión. + +### 5. Build y test + +```sh +make build PG_VERSION=18 +make runtime-test PG_VERSION=18 +``` diff --git a/.docs/playgrounds.md b/.docs/playgrounds.md new file mode 100644 index 0000000..2dcad1c --- /dev/null +++ b/.docs/playgrounds.md @@ -0,0 +1,170 @@ +# Playgrounds + +> [Leer en español](./playgrounds.es.md) + +A **playground** is the fundamental unit of extension installation. Each playground represents a step in the pipeline that transforms a `postgres:N` base image into an image with pre-installed extensions. + +--- + +## Architecture + +Each playground is defined in the `extensions/` package and registered in the global `Playgrounds` slice (`extensions/extensions.go`), an ordered `[]*plyd.Playground`. + +### Playground struct + +```go +type Playground struct { + Name string + handlers HandlersList +} +``` + +Each playground contains a list of **handlers**, where each handler associates a **semver version range** with an **executor function**: + +```go +type Handler struct { + Range string // e.g. ">=14.0.0, <19.0.0" + Runner HandlerFunc // func(ins *instance.InstanceInfo) error +} +``` + +### Execution (`Run`) + +```go +func (p *Playground) Run(ins *instance.InstanceInfo) { + handler := p.matchHandler(ins.PostgreSQL.Version) + if handler == nil { + log.Printf("[WARNING] No handler for PG %s in playground '%s'", ...) + return // Non-fatal — the playground simply skips + } + handler.Runner(ins) +} +``` + +--- + +## Versioning + +Versioning uses **semver 2.0** via `github.com/Masterminds/semver/v3`. + +### Matching flow + +1. The PostgreSQL version is detected by running `postgres --version`. +2. It is normalized to canonical semver (e.g. `"17"` → `"17.0.0"`). +3. `matchHandler` iterates over handlers: + - First tries exact string match. + - Then evaluates each range as a `semver.Constraint`. +4. Returns the first matching handler. + +### Handler ordering + +Handlers are automatically sorted in `NewHandlersList`: +- **Exact versions first** (e.g. `"17.2.0"`), ascending. +- **Ranges after** (e.g. `">=14.0.0, <19.0.0"`), alphabetical order. + +This allows version-specific overrides before falling back to generic ranges. + +### Example + +```go +var myExtension = plyd.New("my-extension", + plyd.NewHandlersList( + plyd.NewHandler(">=16.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y my-extension") + }), + plyd.NewHandler(">=14.0.0, <16.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y my-extension-old") + }), + ), +) +``` + +--- + +## Default playgrounds (execution order) + +The order in `extensions/extensions.go` is critical: + +| # | Playground | File | Purpose | +|---|-----------|------|---------| +| 1 | `build-deps-install` | `builddeps_install.go` | Installs `git`, `make`, `gcc`, `postgresql-server-dev-MAJOR` | +| 2 | `pgmq` | `pgmq.go` | Clones, compiles and installs [PGMQ](https://github.com/pgmq/pgmq) v1.11.1 | +| 3 | `pgvector` | `pgvector.go` | Clones, compiles and installs [pgvector](https://github.com/pgvector/pgvector) v0.8.2 | +| 4 | `postgis` | `postgis.go` | Installs `postgresql-MAJOR-postgis-3` via apt | +| 5 | `postgres-contrib` | `postgrescontrib.go` | Installs `postgresql-MAJOR` (contrib) via apt | +| 6 | `build-deps-remove` | `builddeps_remove.go` | Removes build dependencies and cleans apt | + +### Why this order? + +1. **First** install build tools (needed to compile pgmq and pgvector from source). +2. **Then** compile and install extensions that require source builds (pgmq, pgvector). +3. **After that** install extensions via apt (postgis, contrib), which need `postgresql-server-dev-MAJOR` present. +4. **Finally** remove build tools to keep the final image lightweight. + +--- + +## Supported PostgreSQL versions + +Currently: **14, 15, 16, 17, 18** (and `latest`, which points to the newest). + +All playgrounds use the range `>=14.0.0, <19.0.0`. To extend support (e.g., PG 19), just update the ranges. + +--- + +## How to create a new playground + +### 1. Create the extension file + +In `extensions/`, create a file like `myextension.go`: + +```go +package extensions + +import ( + "postgres-extensor/instance" + "postgres-extensor/plyd" +) + +var myExtension = plyd.New("my-extension", + plyd.NewHandlersList( + plyd.NewHandler(">=14.0.0, <19.0.0", func(ins *instance.InstanceInfo) error { + return plyd.Run("apt-get install -y postgresql-" + ins.PostgreSQL.Mayor + "-my-extension") + }), + ), +) +``` + +### 2. Register it in the correct order + +Edit `extensions/extensions.go` and add it to the `Playgrounds` slice at the right position: + +```go +var Playgrounds = []*plyd.Playground{ + buildDepsInstall, + pgmq, + pgvector, + myExtension, // <-- New + postgis, + postgresContrib, + buildDepsRemove, +} +``` + +### 3. Verify installation + +Your handler should verify the extension was installed: + +```go +verification := "test -f $(pg_config --sharedir)/extension/my_extension.control" +``` + +### 4. Add test coverage + +Edit `.docker/runtime-test.sql` to include the new extension. + +### 5. Build and test + +```sh +make build PG_VERSION=18 +make runtime-test PG_VERSION=18 +``` diff --git a/.docs/tests.es.md b/.docs/tests.es.md new file mode 100644 index 0000000..cac21b1 --- /dev/null +++ b/.docs/tests.es.md @@ -0,0 +1,84 @@ +# Tests + +> [Read in English](./tests.md) + +Este proyecto utiliza **tests de integración** en lugar de tests unitarios de Go (`_test.go`). La razón es que el propósito del binario es ejecutarse dentro de una imagen Docker en tiempo de build, interactuando directamente con el sistema operativo (apt, git, make, pg_config, etc.). No hay lógica de negocio aislable que justifique tests unitarios tradicionales. + +--- + +## `make test` — Build test + +```sh +make test +``` + +Construye la imagen Docker usando `.docker/Dockerfile.test`. Este Dockerfile ejecuta el binario `./main` dentro de un contenedor `postgres:13` y verifica que todo el pipeline de instalación de extensiones compile y se ejecute sin errores. Al finalizar, la imagen se elimina. + +- **Propósito:** Validación rápida de que el código compila y los playgrounds no fallan. +- **Limitación:** Usa PostgreSQL 13 fijo, independientemente de `PG_VERSION`. + +--- + +## `make runtime-test` — Runtime test + +```sh +make runtime-test # PG_VERSION=18 por defecto +PG_VERSION=17 make runtime-test +``` + +Ejecuta el script `.docker/runtime-test.sh`, que: + +1. Construye la imagen Docker de producción (`.docker/Dockerfile`). +2. Inicia un contenedor con `POSTGRES_PASSWORD=postgres`. +3. Espera a que PostgreSQL esté listo (`pg_isready`). +4. Ejecuta `.docker/runtime-test.sql` contra la base de datos vía `psql`. + +El script SQL verifica: + +```sql +CREATE EXTENSION IF NOT EXISTS vector; +CREATE EXTENSION IF NOT EXISTS pgmq; +CREATE EXTENSION IF NOT EXISTS postgis; + +-- Confirma que las extensiones están instaladas +SELECT * FROM pg_extension WHERE extname IN ('vector', 'pgmq', 'postgis'); + +-- Confirma que contrib está disponible +SELECT * FROM pg_available_extensions WHERE name = 'pg_stat_statements'; +``` + +- **Propósito:** Validación real de que todas las extensiones se instalan correctamente y son funcionales dentro de PostgreSQL. +- **Versiones:** Se ejecuta contra la versión de PostgreSQL indicada por `PG_VERSION`. + +--- + +## CI — GitHub Actions + +En `pr-test.yml`, cada Pull Request ejecuta la runtime test matrix para todas las versiones soportadas (`14`, `15`, `16`, `17`, `18`, `latest`) en `linux/amd64`. Esto asegura que cualquier cambio funcione en todo el rango de versiones objetivo. + +--- + +## Cómo ampliar los tests + +### Agregar verificación de una extensión nueva + +Edita `.docker/runtime-test.sql`: + +```sql +CREATE EXTENSION IF NOT EXISTS mi_extension; +SELECT * FROM pg_extension WHERE extname = 'mi_extension'; +``` + +### Agregar un nuevo paso en runtime-test.sh + +Si necesitas lógica adicional antes o después de los tests SQL (por ejemplo, copiar archivos, verificar permisos), edita `.docker/runtime-test.sh`. + +### Tests unitarios (futuro) + +Si en el futuro se extrae lógica reutilizable (por ejemplo, el parseo de versiones o el matching de handlers), se pueden agregar archivos `_test.go` en los paquetes correspondientes y ejecutarlos con: + +```sh +go test ./... +``` + +Actualmente no existen porque la lógica del proyecto está fuertemente acoplada al entorno Docker. diff --git a/.docs/tests.md b/.docs/tests.md new file mode 100644 index 0000000..eac2b2f --- /dev/null +++ b/.docs/tests.md @@ -0,0 +1,84 @@ +# Tests + +> [Leer en español](./tests.es.md) + +This project uses **integration tests** rather than Go unit tests (`_test.go`). The binary runs inside a Docker image at build time, interacting directly with the OS (apt, git, make, pg_config, etc.). There is no isolatable business logic that would benefit from traditional unit tests. + +--- + +## `make test` — Build test + +```sh +make test +``` + +Builds the Docker image using `.docker/Dockerfile.test`. This Dockerfile runs `./main` inside a `postgres:13` container and verifies the entire extension installation pipeline compiles and executes without errors. The image is removed afterwards. + +- **Purpose:** Fast validation that the code compiles and playgrounds don't crash. +- **Limitation:** Uses hardcoded PostgreSQL 13, regardless of `PG_VERSION`. + +--- + +## `make runtime-test` — Runtime test + +```sh +make runtime-test # PG_VERSION=18 by default +PG_VERSION=17 make runtime-test +``` + +Runs the `.docker/runtime-test.sh` script, which: + +1. Builds the production Docker image (`.docker/Dockerfile`). +2. Starts a container with `POSTGRES_PASSWORD=postgres`. +3. Waits for PostgreSQL readiness (`pg_isready`). +4. Executes `.docker/runtime-test.sql` against the database via `psql`. + +The SQL script verifies: + +```sql +CREATE EXTENSION IF NOT EXISTS vector; +CREATE EXTENSION IF NOT EXISTS pgmq; +CREATE EXTENSION IF NOT EXISTS postgis; + +-- Confirms extensions are installed +SELECT * FROM pg_extension WHERE extname IN ('vector', 'pgmq', 'postgis'); + +-- Confirms contrib is available +SELECT * FROM pg_available_extensions WHERE name = 'pg_stat_statements'; +``` + +- **Purpose:** Real validation that all extensions install correctly and work inside PostgreSQL. +- **Versions:** Runs against the PostgreSQL version specified by `PG_VERSION`. + +--- + +## CI — GitHub Actions + +The `pr-test.yml` workflow runs the runtime test matrix for all supported versions (`14`, `15`, `16`, `17`, `18`, `latest`) on `linux/amd64` for every Pull Request. This ensures changes work across the entire supported version range. + +--- + +## How to extend the tests + +### Add verification for a new extension + +Edit `.docker/runtime-test.sql`: + +```sql +CREATE EXTENSION IF NOT EXISTS my_extension; +SELECT * FROM pg_extension WHERE extname = 'my_extension'; +``` + +### Add a new step in runtime-test.sh + +If you need additional logic before or after the SQL tests (e.g., copy files, check permissions), edit `.docker/runtime-test.sh`. + +### Unit tests (future) + +If reusable logic is extracted in the future (e.g., version parsing or handler matching), add `_test.go` files in the corresponding packages and run them with: + +```sh +go test ./... +``` + +Currently none exist because the project's logic is tightly coupled to the Docker environment. diff --git a/CONTRIBUTING.es.md b/CONTRIBUTING.es.md new file mode 100644 index 0000000..90b0b17 --- /dev/null +++ b/CONTRIBUTING.es.md @@ -0,0 +1,51 @@ +# Contribuyendo + +> [Read in English](./CONTRIBUTING.md) + +Gracias por tu interés en contribuir a PostgreSQL Extensor. + +## Reportar issues + +Usa las plantillas en `.github/ISSUE_TEMPLATE/`: + +- **Bug report** — para errores o comportamientos inesperados. +- **Feature request** — para sugerir nuevas extensiones o funcionalidades. +- **Custom** — para cualquier otro caso. + +## Pull Requests + +1. Crea un fork del repositorio. +2. Crea una rama con un nombre descriptivo: `feat/pg-partman`, `fix/pgvector-build`. +3. Asegúrate de que los tests pasen para todas las versiones de PostgreSQL: + + ```sh + make test + make runtime-test PG_VERSION=18 + ``` + +4. Si agregas una nueva extensión, incluye: + - El playground en `extensions/`. + - El registro en `extensions/extensions.go`. + - La verificación en `.docker/runtime-test.sql`. + - Actualiza la documentación relevante en `.docs/`. + +5. Abre el PR contra `main`. Los workflows de CI ejecutarán los tests automáticamente para todas las versiones soportadas. + +## Guías + +- Sigue el estilo del código existente. +- No agregues dependencias innecesarias a `go.mod`. +- Los playgrounds deben ser idempotentes y limpiar los archivos temporales. +- Documenta los rangos de versiones semver claramente. + +## Estructura del proyecto + +``` +.docker/ — Dockerfiles y scripts de test +.docs/ — Documentación +.github/ — Workflows CI/CD y templates +extensions/ — Definición de playgrounds +instance/ — Detección del entorno (OS, versión PG) +plyd/ — Motor de playgrounds (core framework) +utils/ — Utilidades de versionado semver +``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6fbaad5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contributing + +> [Leer en español](./CONTRIBUTING.es.md) + +Thank you for your interest in contributing to PostgreSQL Extensor. + +## Reporting issues + +Use the templates in `.github/ISSUE_TEMPLATE/`: + +- **Bug report** — for errors or unexpected behavior. +- **Feature request** — to suggest new extensions or features. +- **Custom** — for any other case. + +## Pull Requests + +1. Fork the repository. +2. Create a branch with a descriptive name: `feat/pg-partman`, `fix/pgvector-build`. +3. Make sure tests pass for all PostgreSQL versions: + + ```sh + make test + make runtime-test PG_VERSION=18 + ``` + +4. If adding a new extension, include: + - The playground in `extensions/`. + - The registration in `extensions/extensions.go`. + - The verification in `.docker/runtime-test.sql`. + - Update the relevant documentation in `.docs/`. + +5. Open the PR against `main`. CI workflows will run tests automatically for all supported versions. + +## Guidelines + +- Follow the style of existing code. +- Don't add unnecessary dependencies to `go.mod`. +- Playgrounds should be idempotent and clean up temporary files. +- Document semver version ranges clearly. + +## Project structure + +``` +.docker/ — Dockerfiles and test scripts +.docs/ — Documentation +.github/ — CI/CD workflows and templates +extensions/ — Playground definitions +instance/ — Environment detection (OS, PG version) +plyd/ — Playground engine (core framework) +utils/ — Semver versioning utilities +``` diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..41cacd0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ruxwez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.es.md b/README.es.md new file mode 100644 index 0000000..64094da --- /dev/null +++ b/README.es.md @@ -0,0 +1,50 @@ +# PostgreSQL Extensor + +> [Read in English](./README.md) + +Imágenes Docker de PostgreSQL con extensiones populares preinstaladas. + +## Propósito + +Las imágenes oficiales de `postgres` no incluyen extensiones como pgvector, PGMQ o PostGIS. Instalarlas manualmente en cada despliegue es tedioso y lento. Este proyecto resuelve el problema construyendo imágenes Docker listas para usar, con las extensiones ya compiladas e instaladas. + +El binario Go se ejecuta en tiempo de build de la imagen Docker, detecta automáticamente la versión de PostgreSQL, instala cada extensión y luego se elimina a sí mismo. El resultado es una imagen limpia y optimizada. + +## Imágenes Docker + +Disponibles en [Docker Hub](https://hub.docker.com/r/ruxwez/postgres): + +```sh +docker pull ruxwez/postgres:18 +docker pull ruxwez/postgres:17 +docker pull ruxwez/postgres:16 +docker pull ruxwez/postgres:15 +docker pull ruxwez/postgres:14 +docker pull ruxwez/postgres:latest +``` + +Soporte multi-arquitectura: `linux/amd64` y `linux/arm64`. + +### Extensiones incluidas + +| Extensión | Versión | Instalación | +|-----------|---------|-------------| +| [pgvector](https://github.com/pgvector/pgvector) | 0.8.2 | Compilación desde fuente | +| [PGMQ](https://github.com/pgmq/pgmq) | 1.11.1 | Compilación desde fuente | +| [PostGIS](https://postgis.net/) | 3 | Paquete apt (`postgresql-N-postgis-3`) | +| [postgresql-contrib](https://www.postgresql.org/docs/current/contrib.html) | — | Paquete apt (`pg_stat_statements`, etc.) | + +## Build local + +```sh +make build PG_VERSION=18 +``` + +## Documentación + +- [Tests](./.docs/tests.es.md) — Cómo funcionan los tests y cómo ampliarlos. +- [Playgrounds](./.docs/playgrounds.es.md) — Arquitectura, versionado y creación de nuevos playgrounds. + +## Licencia + +MIT — ver [LICENSE](./LICENSE). diff --git a/README.md b/README.md new file mode 100644 index 0000000..916a4d7 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# PostgreSQL Extensor + +> [Leer en español](./README.es.md) + +Pre-built PostgreSQL Docker images with popular extensions. + +## Purpose + +Official `postgres` images don't include extensions like pgvector, PGMQ, or PostGIS. Installing them manually in every deployment is tedious and slow. This project solves that by building ready-to-use Docker images with extensions already compiled and installed. + +The Go binary runs at Docker build time, auto-detects the PostgreSQL version, installs each extension, and then deletes itself. The result is a clean, optimized image. + +## Docker Images + +Available on [Docker Hub](https://hub.docker.com/r/ruxwez/postgres): + +```sh +docker pull ruxwez/postgres:18 +docker pull ruxwez/postgres:17 +docker pull ruxwez/postgres:16 +docker pull ruxwez/postgres:15 +docker pull ruxwez/postgres:14 +docker pull ruxwez/postgres:latest +``` + +Multi-architecture support: `linux/amd64` and `linux/arm64`. + +### Included extensions + +| Extension | Version | Installation | +|-----------|---------|-------------| +| [pgvector](https://github.com/pgvector/pgvector) | 0.8.2 | Build from source | +| [PGMQ](https://github.com/pgmq/pgmq) | 1.11.1 | Build from source | +| [PostGIS](https://postgis.net/) | 3 | apt package (`postgresql-N-postgis-3`) | +| [postgresql-contrib](https://www.postgresql.org/docs/current/contrib.html) | — | apt package (`pg_stat_statements`, etc.) | + +## Local build + +```sh +make build PG_VERSION=18 +``` + +## Documentation + +- [Tests](./.docs/tests.md) — How tests work and how to extend them. +- [Playgrounds](./.docs/playgrounds.md) — Architecture, versioning, and creating new playgrounds. + +## License + +MIT — see [LICENSE](./LICENSE).