Deployment Guide

This guide covers deployment strategies for both On-Demand and Server modes of Prompt Alchemy.

On-Demand Mode Deployment

Local Installation

macOS (Homebrew)

# Coming soon
brew tap jonwraymond/prompt-alchemy
brew install prompt-alchemy

Linux (Package Managers)

# Debian/Ubuntu
wget https://github.com/jonwraymond/prompt-alchemy/releases/latest/download/prompt-alchemy_linux_amd64.deb
sudo dpkg -i prompt-alchemy_linux_amd64.deb

# RedHat/Fedora
wget https://github.com/jonwraymond/prompt-alchemy/releases/latest/download/prompt-alchemy_linux_amd64.rpm
sudo rpm -i prompt-alchemy_linux_amd64.rpm

# Arch Linux (AUR)
yay -S prompt-alchemy

Manual Installation

# Download binary
curl -L https://github.com/jonwraymond/prompt-alchemy/releases/latest/download/prompt-alchemy-$(uname -s)-$(uname -m) -o prompt-alchemy
chmod +x prompt-alchemy
sudo mv prompt-alchemy /usr/local/bin/

# Verify installation
prompt-alchemy version

CI/CD Integration

GitHub Actions

name: Prompt Generation
on: [push, pull_request]

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Prompt Alchemy
        uses: jonwraymond/setup-prompt-alchemy@v1
        with:
          version: latest
          
      - name: Configure API Key
        run: |
          mkdir -p ~/.prompt-alchemy
          echo "providers:" > ~/.prompt-alchemy/config.yaml
          echo "  openai:" >> ~/.prompt-alchemy/config.yaml
          echo "    api_key: $" >> ~/.prompt-alchemy/config.yaml
          
      - name: Generate Prompts
        run: |
          prompt-alchemy batch process .github/prompts/batch.yaml

GitLab CI

generate-prompts:
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
    - curl -L https://github.com/jonwraymond/prompt-alchemy/releases/latest/download/prompt-alchemy-linux-amd64 -o /usr/local/bin/prompt-alchemy
    - chmod +x /usr/local/bin/prompt-alchemy
  script:
    - prompt-alchemy generate "Create deployment script"
  artifacts:
    paths:
      - generated/

Jenkins Pipeline

pipeline {
    agent any
    
    environment {
        OPENAI_API_KEY = credentials('openai-api-key')
    }
    
    stages {
        stage('Setup') {
            steps {
                sh '''
                    curl -L https://github.com/jonwraymond/prompt-alchemy/releases/latest/download/prompt-alchemy-linux-amd64 -o prompt-alchemy
                    chmod +x prompt-alchemy
                '''
            }
        }
        
        stage('Generate') {
            steps {
                sh './prompt-alchemy generate "Create test cases for ${JOB_NAME}"'
            }
        }
    }
}

Container Deployment

Docker (On-Demand)

To run on-demand commands within a Docker container:

FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o /prompt-alchemy cmd/prompt-alchemy/main.go

FROM alpine:3.18
RUN apk add --no-cache ca-certificates
COPY --from=builder /prompt-alchemy /usr/local/bin/
ENTRYPOINT ["prompt-alchemy"]

Usage in Docker

# Build the CLI image
docker build -t prompt-alchemy:cli .

# Run a generate command, mounting a config file and output directory
docker run --rm \
  -v ~/.prompt-alchemy/config.yaml:/root/.prompt-alchemy/config.yaml:ro \
  -v $(pwd)/output:/app/output \
  prompt-alchemy:cli generate "Create a README" --output-file /app/output/README.md

Server Mode Deployment

Important Note: Server mode runs a Model Context Protocol (MCP) server, not a standard HTTP web server. It communicates over stdin and stdout and is designed for programmatic use by AI agents or other MCP-compliant clients. The following examples demonstrate how to run the server as a persistent service.

Development Deployment

# Start the MCP server
prompt-alchemy serve

# Start with learning mode enabled via config or flag
prompt-alchemy serve --learning-enabled

Production Deployment

Systemd Service

# /etc/systemd/system/prompt-alchemy.service
[Unit]
Description=Prompt Alchemy MCP Server
After=network.target

[Service]
Type=simple
User=promptalchemy
Group=promptalchemy
WorkingDirectory=/var/lib/prompt-alchemy
ExecStart=/usr/local/bin/prompt-alchemy serve --config /etc/prompt-alchemy/config.yaml
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=prompt-alchemy

[Install]
WantedBy=multi-user.target

Docker Compose

version: '3.8'

services:
  prompt-alchemy-mcp:
    image: ghcr.io/jonwraymond/prompt-alchemy:latest
    container_name: prompt-alchemy-mcp-server
    restart: unless-stopped
    # The server reads from stdin and writes to stdout.
    # It does not expose HTTP ports.
    # Attach to this container to interact with the MCP server.
    stdin_open: true
    tty: true
    environment:
      - PROMPT_ALCHEMY_LEARNING_ENABLED=true
    env_file:
      - .env  # Contains API keys like OPENAI_API_KEY
    volumes:
      - ./data:/root/.prompt-alchemy # Mount data directory

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prompt-alchemy
  namespace: ai-tools
spec:
  replicas: 3
  selector:
    matchLabels:
      app: prompt-alchemy
  template:
    metadata:
      labels:
        app: prompt-alchemy
    spec:
      containers:
      - name: prompt-alchemy
        image: ghcr.io/jonwraymond/prompt-alchemy:latest
        ports: [] # No container ports are exposed for the MCP server
        env:
        - name: PROMPT_ALCHEMY_MODE
          value: "server"
        - name: PROMPT_ALCHEMY_LEARNING_ENABLED
          value: "true"
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: prompt-alchemy-secrets
              key: openai-api-key
        volumeMounts:
        - name: data
          mountPath: /data
        - name: config
          mountPath: /config
        resources:
          requests:
            memory: "256Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "2000m"
        # Note: Liveness/Readiness probes via HTTP are not applicable.
        # Custom probes using shell commands to check process status would be needed.
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: prompt-alchemy-data
      - name: config
        configMap:
          name: prompt-alchemy-config

---
apiVersion: v1
kind: Service
metadata:
  name: prompt-alchemy
  namespace: ai-tools
spec:
  selector:
    app: prompt-alchemy
  ports:
  - port: 80
    targetPort: 8080
    name: http
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prompt-alchemy
  namespace: ai-tools
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  tls:
  - hosts:
    - prompt-alchemy.example.com
    secretName: prompt-alchemy-tls
  rules:
  - host: prompt-alchemy.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prompt-alchemy
            port:
              number: 80

Cloud Deployments

AWS ECS

{
  "family": "prompt-alchemy",
  "taskRoleArn": "arn:aws:iam::123456789012:role/prompt-alchemy-task",
  "executionRoleArn": "arn:aws:iam::123456789012:role/prompt-alchemy-execution",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "prompt-alchemy",
      "image": "ghcr.io/jonwraymond/prompt-alchemy:latest",
      "cpu": 1024,
      "memory": 2048,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "PROMPT_ALCHEMY_MODE",
          "value": "server"
        },
        {
          "name": "PROMPT_ALCHEMY_LEARNING_ENABLED",
          "value": "true"
        }
      ],
      "secrets": [
        {
          "name": "OPENAI_API_KEY",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prompt-alchemy/openai-key"
        }
      ],
      "mountPoints": [
        {
          "sourceVolume": "data",
          "containerPath": "/data"
        }
      ],
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      },
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/prompt-alchemy",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ],
  "volumes": [
    {
      "name": "data",
      "efsVolumeConfiguration": {
        "fileSystemId": "fs-12345678",
        "transitEncryption": "ENABLED"
      }
    }
  ]
}

Google Cloud Run

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: prompt-alchemy
  annotations:
    run.googleapis.com/ingress: all
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/minScale: "1"
        autoscaling.knative.dev/maxScale: "100"
    spec:
      containerConcurrency: 100
      timeoutSeconds: 300
      containers:
      - image: gcr.io/PROJECT_ID/prompt-alchemy:latest
        ports:
        - containerPort: 8080
        env:
        - name: PROMPT_ALCHEMY_MODE
          value: "server"
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: openai-key
              key: latest
        resources:
          limits:
            cpu: "2"
            memory: "1Gi"

Azure Container Instances

az container create \
  --resource-group prompt-alchemy-rg \
  --name prompt-alchemy \
  --image ghcr.io/jonwraymond/prompt-alchemy:latest \
  --cpu 2 \
  --memory 1 \
  --ports 8080 \
  --environment-variables \
    PROMPT_ALCHEMY_MODE=server \
    PROMPT_ALCHEMY_LEARNING_ENABLED=true \
  --secure-environment-variables \
    OPENAI_API_KEY=$OPENAI_API_KEY \
  --ip-address Public \
  --dns-name-label prompt-alchemy

High Availability Setup

Load Balancer Configuration (HAProxy)

global
    maxconn 4096
    log stdout local0

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    option httplog

frontend prompt_alchemy_frontend
    bind *:80
    bind *:443 ssl crt /etc/ssl/certs/prompt-alchemy.pem
    redirect scheme https if !{ ssl_fc }
    
    # Rate limiting
    stick-table type ip size 100k expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_http_req_rate(0) gt 20 }
    
    default_backend prompt_alchemy_backend

backend prompt_alchemy_backend
    balance roundrobin
    option httpchk GET /health
    
    server prompt-alchemy-1 10.0.1.10:8080 check
    server prompt-alchemy-2 10.0.1.11:8080 check
    server prompt-alchemy-3 10.0.1.12:8080 check

Monitoring and Observability

Prometheus Configuration

scrape_configs:
  - job_name: 'prompt-alchemy'
    static_configs:
      - targets: ['prompt-alchemy:8080']
    metrics_path: '/metrics'
    scrape_interval: 15s

Grafana Dashboard

{
  "dashboard": {
    "title": "Prompt Alchemy Metrics",
    "panels": [
      {
        "title": "Request Rate",
        "targets": [
          {
            "expr": "rate(prompt_alchemy_requests_total[5m])"
          }
        ]
      },
      {
        "title": "Response Time",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, rate(prompt_alchemy_request_duration_seconds_bucket[5m]))"
          }
        ]
      },
      {
        "title": "Learning Effectiveness",
        "targets": [
          {
            "expr": "prompt_alchemy_learning_effectiveness"
          }
        ]
      }
    ]
  }
}

Security Hardening

Network Policies

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: prompt-alchemy-network-policy
spec:
  podSelector:
    matchLabels:
      app: prompt-alchemy
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: nginx-ingress
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443  # HTTPS for API calls
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432

API Authentication

# config.yaml
server:
  auth:
    enabled: true
    type: jwt
    secret: ${JWT_SECRET}
    issuer: "prompt-alchemy"
    audience: "prompt-alchemy-api"
  
  rate_limiting:
    enabled: true
    requests_per_minute: 60
    burst: 100
  
  cors:
    enabled: true
    allowed_origins:
      - https://app.example.com
    allowed_methods:
      - GET
      - POST
    allowed_headers:
      - Authorization
      - Content-Type

Backup and Recovery

Automated Backups

#!/bin/bash
# backup.sh - Run via cron

BACKUP_DIR="/backups/prompt-alchemy"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Backup database
sqlite3 /data/prompts.db ".backup ${BACKUP_DIR}/prompts_${TIMESTAMP}.db"

# Backup learned patterns
curl -X GET http://localhost:8080/api/export \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  > "${BACKUP_DIR}/patterns_${TIMESTAMP}.json"

# Compress and encrypt
tar czf - ${BACKUP_DIR}/*_${TIMESTAMP}.* | \
  openssl enc -aes-256-cbc -salt -k "${BACKUP_PASSWORD}" \
  > "${BACKUP_DIR}/backup_${TIMESTAMP}.tar.gz.enc"

# Upload to S3
aws s3 cp "${BACKUP_DIR}/backup_${TIMESTAMP}.tar.gz.enc" \
  s3://prompt-alchemy-backups/

# Cleanup old backups
find ${BACKUP_DIR} -name "*.db" -mtime +7 -delete
find ${BACKUP_DIR} -name "*.json" -mtime +7 -delete

Troubleshooting

Common Deployment Issues

Issue Solution
Port conflicts Check with netstat -tlnp \| grep 8080
Memory issues Increase container/pod memory limits
Slow startup Pre-warm containers, use readiness probes
Connection refused Check firewall rules and security groups
SSL errors Verify certificate chain and expiration

Health Check Endpoints

# Basic health check
curl http://localhost:8080/health

# Detailed health with dependencies
curl http://localhost:8080/health/detailed

# Readiness check
curl http://localhost:8080/ready

# Liveness check
curl http://localhost:8080/alive