From 0ec5022920254826ae2fbc0e1574add137800091 Mon Sep 17 00:00:00 2001 From: Azat Date: Mon, 2 Feb 2026 23:43:53 +0100 Subject: [PATCH] Initial postgres skill implementation --- SKILL.md | 90 +++++++++++++++++++++++++++++++ scripts/autorun.sh | 128 +++++++++++++++++++++++++++++++++++++++++++++ scripts/run.sh | 20 +++++++ 3 files changed, 238 insertions(+) create mode 100644 SKILL.md create mode 100644 scripts/autorun.sh create mode 100644 scripts/run.sh diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..6dafa2c --- /dev/null +++ b/SKILL.md @@ -0,0 +1,90 @@ +--- +name: postgres +description: PostgreSQL database server for persistent relational storage +metadata: + version: "1.0.0" + vibestack: + main: false + metrics-port: 9187 +--- + +# PostgreSQL Skill + +Installs and configures [PostgreSQL](https://www.postgresql.org/) database server for persistent relational data storage. + +## Features + +- Persistent relational database +- Auto-creates database and user on first run +- WAL-based replication ready +- Connection string exposed as `DATABASE_URL` +- Optional metrics via postgres_exporter + +## Configuration + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `POSTGRES_PORT` | `5432` | PostgreSQL port | +| `POSTGRES_USER` | `vibestack` | Default user | +| `POSTGRES_PASSWORD` | `vibestack` | Default password | +| `POSTGRES_DB` | `vibestack` | Default database | +| `POSTGRES_DATA_DIR` | `/data/postgres` | Data directory | +| `POSTGRES_INITDB_ARGS` | (none) | Extra initdb arguments | +| `POSTGRES_MAX_CONNECTIONS` | `100` | Maximum connections | + +### Output Variables + +After starting, the skill exports: + +| Variable | Example | +|----------|---------| +| `DATABASE_URL` | `postgresql://vibestack:vibestack@localhost:5432/vibestack` | + +## Usage + +### As a dependency + +```yaml +metadata: + vibestack: + requires: + - postgres +``` + +### Connection + +```bash +# Connect with psql +psql "$DATABASE_URL" + +# From application +DATABASE_URL=postgresql://vibestack:vibestack@localhost:5432/vibestack +``` + +### Custom initialization + +Place SQL files in `initdb.d/` directory - they'll be executed on first startup: + +``` +skills/postgres/ +├── initdb.d/ +│ ├── 01-create-tables.sql +│ └── 02-seed-data.sql +``` + +## Data Persistence + +All data is stored in `POSTGRES_DATA_DIR` (default: `/data/postgres`). Mount this directory to persist data across container restarts. + +## Backup Integration + +The `backup` skill automatically backs up PostgreSQL data using pg_dump for consistent snapshots. + +## Security + +For production use: +1. Set a strong `POSTGRES_PASSWORD` +2. Restrict network access to trusted hosts +3. Use SSL for connections (configure in postgresql.conf) diff --git a/scripts/autorun.sh b/scripts/autorun.sh new file mode 100644 index 0000000..c1f5d71 --- /dev/null +++ b/scripts/autorun.sh @@ -0,0 +1,128 @@ +#!/bin/bash +set -e + +POSTGRES_VERSION="${POSTGRES_VERSION:-16}" +POSTGRES_DATA_DIR="${POSTGRES_DATA_DIR:-/data/postgres}" +POSTGRES_USER="${POSTGRES_USER:-vibestack}" +POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-vibestack}" +POSTGRES_DB="${POSTGRES_DB:-vibestack}" +POSTGRES_INITDB_ARGS="${POSTGRES_INITDB_ARGS:-}" + +# Idempotent PostgreSQL installation +install_postgres() { + if command -v psql &>/dev/null; then + echo "PostgreSQL already installed: $(psql --version)" + return 0 + fi + + echo "Installing PostgreSQL ${POSTGRES_VERSION}..." + + # Install dependencies and add PostgreSQL repo + apt-get update + apt-get install -y curl ca-certificates gnupg lsb-release + + # Add PostgreSQL APT repository + curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /usr/share/keyrings/postgresql-keyring.gpg + echo "deb [signed-by=/usr/share/keyrings/postgresql-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list + + # Install PostgreSQL + apt-get update + apt-get install -y "postgresql-${POSTGRES_VERSION}" + + echo "PostgreSQL installed: $(psql --version)" +} + +# Setup directories and permissions +setup_dirs() { + mkdir -p "$POSTGRES_DATA_DIR" + chown -R postgres:postgres "$POSTGRES_DATA_DIR" + chmod 700 "$POSTGRES_DATA_DIR" + + echo "PostgreSQL data directory: $POSTGRES_DATA_DIR" +} + +# Initialize database if not exists +init_database() { + if [ -f "$POSTGRES_DATA_DIR/PG_VERSION" ]; then + echo "Database already initialized" + return 0 + fi + + echo "Initializing database..." + + # Initialize with specified args + su - postgres -c "/usr/lib/postgresql/${POSTGRES_VERSION}/bin/initdb -D '$POSTGRES_DATA_DIR' $POSTGRES_INITDB_ARGS" + + # Configure PostgreSQL + cat >> "$POSTGRES_DATA_DIR/postgresql.conf" << EOF + +# VibeStack configuration +listen_addresses = '*' +port = ${POSTGRES_PORT:-5432} +max_connections = ${POSTGRES_MAX_CONNECTIONS:-100} +EOF + + # Configure authentication + cat > "$POSTGRES_DATA_DIR/pg_hba.conf" << EOF +# TYPE DATABASE USER ADDRESS METHOD +local all postgres peer +local all all md5 +host all all 127.0.0.1/32 md5 +host all all ::1/128 md5 +host all all 0.0.0.0/0 md5 +EOF + + echo "Database initialized" +} + +# Create default user and database +create_user_and_db() { + local pg_ctl="/usr/lib/postgresql/${POSTGRES_VERSION}/bin/pg_ctl" + local psql_cmd="/usr/lib/postgresql/${POSTGRES_VERSION}/bin/psql" + + # Start PostgreSQL temporarily + echo "Starting PostgreSQL for initial setup..." + su - postgres -c "$pg_ctl -D '$POSTGRES_DATA_DIR' -w start" + + # Create user if not exists + if ! su - postgres -c "$psql_cmd -tAc \"SELECT 1 FROM pg_roles WHERE rolname='$POSTGRES_USER'\"" | grep -q 1; then + echo "Creating user: $POSTGRES_USER" + su - postgres -c "$psql_cmd -c \"CREATE USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD'\"" + fi + + # Create database if not exists + if ! su - postgres -c "$psql_cmd -tAc \"SELECT 1 FROM pg_database WHERE datname='$POSTGRES_DB'\"" | grep -q 1; then + echo "Creating database: $POSTGRES_DB" + su - postgres -c "$psql_cmd -c \"CREATE DATABASE $POSTGRES_DB OWNER $POSTGRES_USER\"" + fi + + # Grant privileges + su - postgres -c "$psql_cmd -c \"GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB TO $POSTGRES_USER\"" + + # Run init scripts if present + local skill_dir="$(dirname "$(dirname "$0")")" + local initdb_dir="$skill_dir/initdb.d" + + if [ -d "$initdb_dir" ]; then + echo "Running init scripts..." + for f in "$initdb_dir"/*.sql; do + if [ -f "$f" ]; then + echo " Running: $(basename "$f")" + su - postgres -c "PGPASSWORD='$POSTGRES_PASSWORD' $psql_cmd -U $POSTGRES_USER -d $POSTGRES_DB -f '$f'" + fi + done + fi + + # Stop PostgreSQL (run.sh will start it properly) + echo "Stopping PostgreSQL after setup..." + su - postgres -c "$pg_ctl -D '$POSTGRES_DATA_DIR' -w stop" + + echo "User and database setup complete" +} + +install_postgres +setup_dirs +init_database +create_user_and_db + +echo "PostgreSQL setup complete" diff --git a/scripts/run.sh b/scripts/run.sh new file mode 100644 index 0000000..f32afc7 --- /dev/null +++ b/scripts/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +POSTGRES_VERSION="${POSTGRES_VERSION:-16}" +POSTGRES_DATA_DIR="${POSTGRES_DATA_DIR:-/data/postgres}" +POSTGRES_PORT="${POSTGRES_PORT:-5432}" +POSTGRES_USER="${POSTGRES_USER:-vibestack}" +POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-vibestack}" +POSTGRES_DB="${POSTGRES_DB:-vibestack}" + +# Export DATABASE_URL for other services +export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}" +echo "DATABASE_URL=$DATABASE_URL" + +# Write to shared env file for other skills +mkdir -p /run/vibestack +echo "DATABASE_URL=$DATABASE_URL" > /run/vibestack/postgres.env + +echo "Starting PostgreSQL on port $POSTGRES_PORT..." +exec su - postgres -c "/usr/lib/postgresql/${POSTGRES_VERSION}/bin/postgres -D '$POSTGRES_DATA_DIR'"