Files

Pixelfed Kubernetes-Optimized Containers

This directory contains separate, optimized Docker containers for Pixelfed v0.12.6 designed specifically for Kubernetes deployment with your infrastructure.

🏗️ Architecture Overview

Three-Container Design

  1. pixelfed-base - Shared foundation image with all Pixelfed dependencies
  2. pixelfed-web - Web server handling HTTP requests (Nginx + PHP-FPM)
  3. pixelfed-worker - Background job processing (Laravel Horizon + Scheduler)

Why Separate Containers?

✅ Independent Scaling: Scale web and workers separately based on load
✅ Better Resource Management: Optimize CPU/memory for each workload type
✅ Enhanced Monitoring: Separate metrics for web performance vs queue processing
✅ Fault Isolation: Web issues don't affect background processing and vice versa
✅ Rolling Updates: Update web and workers independently
✅ Kubernetes Native: Works perfectly with HPA, resource limits, and service mesh

🚀 Quick Start

Build All Containers

# From the build/ directory
./build-all.sh

This will:

  1. Build the base image with all Pixelfed dependencies
  2. Build the web container with Nginx + PHP-FPM
  3. Build the worker container with Horizon + Scheduler
  4. Push to your Harbor registry: registry.keyboardvagabond.com

Individual Container Builds

# Build just web container
cd pixelfed-web && docker build --platform linux/arm64 \
  -t registry.keyboardvagabond.com/pixelfed/web:v6 .

# Build just worker container  
cd pixelfed-worker && docker build --platform linux/arm64 \
  -t registry.keyboardvagabond.com/pixelfed/worker:v0.12.6 .

📦 Container Details

pixelfed-web - Web Server Container

Purpose: Handle HTTP requests, API calls, file uploads
Components:

  • Nginx (optimized with rate limiting, gzip, security headers)
  • PHP-FPM (tuned for web workload with connection pooling)
  • Static asset serving with CDN fallback

Resources: Optimized for HTTP response times
Health Check: curl -f http://localhost:80/api/v1/instance
Scaling: Based on HTTP traffic, CPU usage

pixelfed-worker - Background Job Container

Purpose: Process federation, image optimization, emails, scheduled tasks
Components:

  • Laravel Horizon (queue management with Redis)
  • Laravel Scheduler (cron-like task scheduling)
  • Optional high-priority worker for urgent tasks

Resources: Optimized for background processing throughput
Health Check: php artisan horizon:status
Scaling: Based on queue depth, memory usage

⚙️ Configuration

Environment Variables

Both containers share the same configuration:

Required

APP_DOMAIN=pixelfed.keyboardvagabond.com
DB_HOST=postgresql-shared-rw.postgresql-system.svc.cluster.local
DB_DATABASE=pixelfed
DB_USERNAME=pixelfed
DB_PASSWORD=secure_password_here

Redis Configuration

REDIS_HOST=redis-ha-haproxy.redis-system.svc.cluster.local
REDIS_PORT=6379
REDIS_PASSWORD=redis_password_if_needed

S3 Media Storage (Backblaze B2)

# Enable cloud storage with dedicated bucket approach
PF_ENABLE_CLOUD=true
DANGEROUSLY_SET_FILESYSTEM_DRIVER=s3
FILESYSTEM_DRIVER=s3
FILESYSTEM_CLOUD=s3
FILESYSTEM_DISK=s3

# Backblaze B2 S3-compatible configuration  
AWS_ACCESS_KEY_ID=your_b2_key_id
AWS_SECRET_ACCESS_KEY=your_b2_secret_key
AWS_DEFAULT_REGION=eu-central-003
AWS_BUCKET=pixelfed-bucket
AWS_URL=https://pm.keyboardvagabond.com/
AWS_ENDPOINT=https://s3.eu-central-003.backblazeb2.com
AWS_USE_PATH_STYLE_ENDPOINT=false
AWS_ROOT=
AWS_VISIBILITY=public

# CDN Configuration for media delivery
CDN_DOMAIN=pm.keyboardvagabond.com

Email (Mailgun)

MAIL_MAILER=smtp
MAIL_HOST=smtp.eu.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=pixelfed@mail.keyboardvagabond.com
MAIL_PASSWORD=<mail password>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=pixelfed@mail.keyboardvagabond.com
MAIL_FROM_NAME="Pixelfed at Keyboard Vagabond"

Container-Specific Configuration

Web Container Only

PIXELFED_INIT_CONTAINER=true  # Only set on ONE web pod

Worker Container Only

PIXELFED_INIT_CONTAINER=false  # Never set on worker pods

🎯 Deployment Strategy

Initialization Pattern

  1. First Web Pod: Set PIXELFED_INIT_CONTAINER=true

    • Runs database migrations
    • Generates application key
    • Imports initial data
  2. Additional Web Pods: Set PIXELFED_INIT_CONTAINER=false

    • Skip initialization tasks
    • Start faster
  3. All Worker Pods: Set PIXELFED_INIT_CONTAINER=false

    • Never run database migrations
    • Focus on background processing

Scaling Recommendations

Web Containers

  • Start: 2 replicas for high availability
  • Scale Up: When CPU > 70% or response time > 200ms
  • Resources: 4 CPU, 4GB RAM (medium+ tier)

Worker Containers

  • Start: 1 replica for basic workload
  • Scale Up: When queue depth > 100 or processing lag > 5 minutes
  • Resources: 2 CPU, 4GB RAM initially, scale to 4 CPU, 8GB for heavy federation

📊 Monitoring Integration

OpenObserve Dashboards

Web Container Metrics

  • HTTP response times
  • Request rates by endpoint
  • PHP-FPM pool status
  • Nginx connection metrics
  • Rate limiting effectiveness

Worker Container Metrics

  • Queue processing rates
  • Job failure rates
  • Horizon supervisor status
  • Memory usage for image processing
  • Federation activity

Health Checks

Web: HTTP-based health check

curl -f http://localhost:80/api/v1/instance

Worker: Horizon status check

php artisan horizon:status

🔄 Updates & Maintenance

Updating Pixelfed Version

  1. Update PIXELFED_VERSION in pixelfed-base/Dockerfile
  2. Update VERSION in build-all.sh
  3. Run ./build-all.sh
  4. Deploy web containers first, then workers

Rolling Updates

# Update web containers first
kubectl rollout restart deployment pixelfed-web

# Wait for web to be healthy
kubectl rollout status deployment pixelfed-web

# Then update workers
kubectl rollout restart deployment pixelfed-worker

🛠️ Troubleshooting

Common Issues

Database Connection

# Check from web container
kubectl exec -it pixelfed-web-xxx -- php artisan migrate:status

# Check from worker container  
kubectl exec -it pixelfed-worker-xxx -- php artisan queue:work --once

Queue Processing

# Check Horizon status
kubectl exec -it pixelfed-worker-xxx -- php artisan horizon:status

# View queue stats
kubectl exec -it pixelfed-worker-xxx -- php artisan queue:work --once --verbose

Storage Issues

# Test S3 connection
kubectl exec -it pixelfed-web-xxx -- php artisan storage:link

# Check media upload  
curl -v https://pixelfed.keyboardvagabond.com/api/v1/media

Performance Optimization

Web Container Tuning

  • Adjust PHP-FPM pool size in Dockerfile
  • Tune Nginx worker connections
  • Enable OPcache optimizations

Worker Container Tuning

  • Increase Horizon worker processes
  • Adjust queue processing timeouts
  • Scale based on queue metrics

🔗 Integration with Your Infrastructure

Perfect Fit For Your Setup

  • ✅ PostgreSQL: Uses your CloudNativePG cluster with read replicas
  • ✅ Redis: Integrates with your Redis cluster
  • ✅ S3 Storage: Leverages Backblaze B2 + Cloudflare CDN
  • ✅ Monitoring: Ready for OpenObserve metrics collection
  • ✅ SSL: Works with your cert-manager + Let's Encrypt setup
  • ✅ DNS: Compatible with external-dns + Cloudflare
  • ✅ Auth: Ready for Authentik SSO integration

Next Steps

  1. ✅ Build containers with ./build-all.sh
  2. ✅ Create Kubernetes manifests for both deployments
  3. ✅ Set up PostgreSQL database and user
  4. ✅ Configure ingress for pixelfed.keyboardvagabond.com
  5. ❌ Integrate with Authentik for SSO
  6. ❌ Configure Cloudflare Turnstile for spam protection
  7. ✅ Use enhanced spam filter instead of recaptcha

Built with ❤️ for your sophisticated Kubernetes infrastructure