Initial redis skill implementation
This commit is contained in:
119
SKILL.md
Normal file
119
SKILL.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
name: redis
|
||||||
|
description: Redis in-memory cache with persistence and pub/sub
|
||||||
|
metadata:
|
||||||
|
version: "1.0.0"
|
||||||
|
vibestack:
|
||||||
|
main: false
|
||||||
|
metrics-port: 9121
|
||||||
|
---
|
||||||
|
|
||||||
|
# Redis Skill
|
||||||
|
|
||||||
|
Installs and configures [Redis](https://redis.io/) in-memory data store for caching, pub/sub messaging, and session storage.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- In-memory key-value store
|
||||||
|
- RDB + AOF persistence
|
||||||
|
- Pub/sub messaging
|
||||||
|
- Optional authentication
|
||||||
|
- Memory limit with eviction policy
|
||||||
|
- Auto-registers with Caddy if domain set
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `REDIS_PORT` | `6379` | Redis port |
|
||||||
|
| `REDIS_PASSWORD` | (none) | Optional authentication password |
|
||||||
|
| `REDIS_MAXMEMORY` | `100mb` | Memory limit |
|
||||||
|
| `REDIS_MAXMEMORY_POLICY` | `allkeys-lru` | Eviction policy when memory limit reached |
|
||||||
|
| `REDIS_DATA_DIR` | `/data/redis` | Persistence directory |
|
||||||
|
| `REDIS_APPENDONLY` | `yes` | Enable AOF persistence |
|
||||||
|
| `REDIS_SAVE` | `900 1 300 10 60 10000` | RDB save intervals |
|
||||||
|
| `REDIS_DOMAIN` | (none) | Domain for Caddy auto-config |
|
||||||
|
|
||||||
|
### Output Variables
|
||||||
|
|
||||||
|
After starting, the skill exports:
|
||||||
|
|
||||||
|
| Variable | Example |
|
||||||
|
|----------|---------|
|
||||||
|
| `REDIS_URL` | `redis://:password@localhost:6379` |
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### As a dependency
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
metadata:
|
||||||
|
vibestack:
|
||||||
|
requires:
|
||||||
|
- redis
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Connect with redis-cli
|
||||||
|
redis-cli -p 6379
|
||||||
|
|
||||||
|
# With authentication
|
||||||
|
redis-cli -p 6379 -a "$REDIS_PASSWORD"
|
||||||
|
|
||||||
|
# From application
|
||||||
|
REDIS_URL=redis://localhost:6379
|
||||||
|
# or with auth
|
||||||
|
REDIS_URL=redis://:password@localhost:6379
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Operations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set a key
|
||||||
|
redis-cli SET mykey "Hello"
|
||||||
|
|
||||||
|
# Get a key
|
||||||
|
redis-cli GET mykey
|
||||||
|
|
||||||
|
# Pub/sub
|
||||||
|
redis-cli SUBSCRIBE mychannel
|
||||||
|
redis-cli PUBLISH mychannel "Hello subscribers!"
|
||||||
|
|
||||||
|
# Check memory usage
|
||||||
|
redis-cli INFO memory
|
||||||
|
```
|
||||||
|
|
||||||
|
## Persistence
|
||||||
|
|
||||||
|
Redis is configured with both RDB snapshots and AOF (Append Only File):
|
||||||
|
|
||||||
|
- **RDB**: Point-in-time snapshots at configured intervals
|
||||||
|
- **AOF**: Log of all write operations for durability
|
||||||
|
|
||||||
|
Data is stored in `REDIS_DATA_DIR` (default: `/data/redis`).
|
||||||
|
|
||||||
|
## Memory Management
|
||||||
|
|
||||||
|
When `REDIS_MAXMEMORY` is reached, the `REDIS_MAXMEMORY_POLICY` determines behavior:
|
||||||
|
|
||||||
|
| Policy | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `allkeys-lru` | Evict least recently used keys (default) |
|
||||||
|
| `volatile-lru` | Evict LRU keys with TTL set |
|
||||||
|
| `allkeys-random` | Evict random keys |
|
||||||
|
| `noeviction` | Return errors on write |
|
||||||
|
|
||||||
|
## Caddy Integration
|
||||||
|
|
||||||
|
If the `caddy` skill is present and `REDIS_DOMAIN` is set, Redis will be accessible via HTTPS (useful for Redis Insight or other GUI tools).
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
For production use:
|
||||||
|
1. Always set `REDIS_PASSWORD`
|
||||||
|
2. Restrict network access
|
||||||
|
3. Use TLS for external connections
|
||||||
76
scripts/autorun.sh
Normal file
76
scripts/autorun.sh
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REDIS_DATA_DIR="${REDIS_DATA_DIR:-/data/redis}"
|
||||||
|
SKILLS_DIR="${SKILLS_DIR:-/skills}"
|
||||||
|
|
||||||
|
# Idempotent Redis installation
|
||||||
|
install_redis() {
|
||||||
|
if command -v redis-server &>/dev/null; then
|
||||||
|
echo "Redis already installed: $(redis-server --version)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing Redis..."
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl gpg lsb-release
|
||||||
|
|
||||||
|
# Add Redis repository
|
||||||
|
curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" > /etc/apt/sources.list.d/redis.list
|
||||||
|
|
||||||
|
# Install Redis
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y redis
|
||||||
|
|
||||||
|
echo "Redis installed: $(redis-server --version)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup directories
|
||||||
|
setup_dirs() {
|
||||||
|
mkdir -p "$REDIS_DATA_DIR"
|
||||||
|
chown -R redis:redis "$REDIS_DATA_DIR" 2>/dev/null || true
|
||||||
|
chmod 755 "$REDIS_DATA_DIR"
|
||||||
|
|
||||||
|
echo "Redis data directory: $REDIS_DATA_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure Caddy if present
|
||||||
|
configure_caddy() {
|
||||||
|
local caddy_dir="$SKILLS_DIR/caddy"
|
||||||
|
local redis_domain="${REDIS_DOMAIN:-}"
|
||||||
|
local redis_port="${REDIS_PORT:-6379}"
|
||||||
|
|
||||||
|
if [ ! -d "$caddy_dir" ]; then
|
||||||
|
echo "Caddy not found - Redis will run standalone"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$redis_domain" ]; then
|
||||||
|
echo "REDIS_DOMAIN not set - skipping Caddy config"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Caddy detected - configuring reverse proxy..."
|
||||||
|
|
||||||
|
local snippets_dir="$caddy_dir/snippets.d"
|
||||||
|
mkdir -p "$snippets_dir"
|
||||||
|
|
||||||
|
cat > "$snippets_dir/redis.caddy" << EOF
|
||||||
|
# Auto-generated by redis skill
|
||||||
|
# Note: Redis protocol is not HTTP - this is for Redis Insight or similar tools
|
||||||
|
# $redis_domain {
|
||||||
|
# reverse_proxy localhost:$redis_port
|
||||||
|
# }
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Caddy snippet created (manual config needed for Redis)"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_redis
|
||||||
|
setup_dirs
|
||||||
|
configure_caddy
|
||||||
|
|
||||||
|
echo "Redis setup complete"
|
||||||
64
scripts/run.sh
Normal file
64
scripts/run.sh
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REDIS_PORT="${REDIS_PORT:-6379}"
|
||||||
|
REDIS_PASSWORD="${REDIS_PASSWORD:-}"
|
||||||
|
REDIS_MAXMEMORY="${REDIS_MAXMEMORY:-100mb}"
|
||||||
|
REDIS_MAXMEMORY_POLICY="${REDIS_MAXMEMORY_POLICY:-allkeys-lru}"
|
||||||
|
REDIS_DATA_DIR="${REDIS_DATA_DIR:-/data/redis}"
|
||||||
|
REDIS_APPENDONLY="${REDIS_APPENDONLY:-yes}"
|
||||||
|
REDIS_SAVE="${REDIS_SAVE:-900 1 300 10 60 10000}"
|
||||||
|
|
||||||
|
# Build REDIS_URL
|
||||||
|
if [ -n "$REDIS_PASSWORD" ]; then
|
||||||
|
export REDIS_URL="redis://:${REDIS_PASSWORD}@localhost:${REDIS_PORT}"
|
||||||
|
else
|
||||||
|
export REDIS_URL="redis://localhost:${REDIS_PORT}"
|
||||||
|
fi
|
||||||
|
echo "REDIS_URL=$REDIS_URL"
|
||||||
|
|
||||||
|
# Write to shared env file for other skills
|
||||||
|
mkdir -p /run/vibestack
|
||||||
|
echo "REDIS_URL=$REDIS_URL" > /run/vibestack/redis.env
|
||||||
|
|
||||||
|
# Build command arguments
|
||||||
|
args=()
|
||||||
|
args+=("--port" "$REDIS_PORT")
|
||||||
|
args+=("--dir" "$REDIS_DATA_DIR")
|
||||||
|
args+=("--maxmemory" "$REDIS_MAXMEMORY")
|
||||||
|
args+=("--maxmemory-policy" "$REDIS_MAXMEMORY_POLICY")
|
||||||
|
args+=("--appendonly" "$REDIS_APPENDONLY")
|
||||||
|
|
||||||
|
# Add authentication if set
|
||||||
|
if [ -n "$REDIS_PASSWORD" ]; then
|
||||||
|
args+=("--requirepass" "$REDIS_PASSWORD")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure RDB persistence
|
||||||
|
# REDIS_SAVE format: "seconds changes [seconds changes ...]"
|
||||||
|
if [ -n "$REDIS_SAVE" ]; then
|
||||||
|
# Parse save intervals (e.g., "900 1 300 10 60 10000")
|
||||||
|
read -ra save_args <<< "$REDIS_SAVE"
|
||||||
|
for ((i=0; i<${#save_args[@]}; i+=2)); do
|
||||||
|
if [ $((i+1)) -lt ${#save_args[@]} ]; then
|
||||||
|
args+=("--save" "${save_args[i]} ${save_args[i+1]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bind to all interfaces
|
||||||
|
args+=("--bind" "0.0.0.0")
|
||||||
|
|
||||||
|
# Enable protected mode only if no password
|
||||||
|
if [ -z "$REDIS_PASSWORD" ]; then
|
||||||
|
args+=("--protected-mode" "yes")
|
||||||
|
else
|
||||||
|
args+=("--protected-mode" "no")
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting Redis on port $REDIS_PORT..."
|
||||||
|
echo "Max memory: $REDIS_MAXMEMORY"
|
||||||
|
echo "Eviction policy: $REDIS_MAXMEMORY_POLICY"
|
||||||
|
echo "Persistence: AOF=$REDIS_APPENDONLY"
|
||||||
|
|
||||||
|
exec redis-server "${args[@]}"
|
||||||
Reference in New Issue
Block a user