Files
Keybard-Vagabond-Demo/manifests/applications/write-freely/README.md

8.9 KiB

WriteFreely Deployment

WriteFreely is a clean, minimalist publishing platform made for writers. This deployment provides a fully functional WriteFreely instance with persistent storage, SSL certificates, and admin access.

🚀 Access Information

  • Blog URL: https://blog.keyboardvagabond.com
  • Admin Username: mdileo
  • Admin Password: Stored in writefreely-secret Kubernetes secret

📁 File and Folder Locations

Inside the Pod

/writefreely/                     # WriteFreely application directory
├── writefreely                   # Main binary executable  
├── writefreely-docker.sh         # Docker entrypoint script
├── static/                       # CSS, JS, fonts, images
├── templates/                    # HTML templates
├── pages/                        # Static pages
└── keys/                         # Application encryption keys (symlinked to /data/keys)

/data/                            # Persistent volume mount (survives pod restarts)
├── config.ini                    # Main configuration file (writable)
├── writefreely.db               # SQLite database
└── keys/                        # Encryption keys directory
    ├── email.aes256              # Email encryption key
    ├── cookies.aes256            # Cookie encryption key
    ├── session.aes256            # Session encryption key
    └── csrf.aes256               # CSRF protection key

Kubernetes Resources

manifests/applications/write-freely/
├── namespace.yaml               # writefreely-system namespace
├── deployment.yaml              # Main application deployment
├── service.yaml                 # ClusterIP service (port 8080)
├── ingress.yaml                 # NGINX ingress with SSL
├── storage.yaml                 # PersistentVolumeClaim for data
├── secret.yaml                  # Admin password (SOPS encrypted)
├── configmap.yaml               # Configuration template (unused in current setup)
├── kustomization.yaml           # Kustomize resource list
└── README.md                    # This file

⚙️ Configuration Management

Edit config.ini

To edit the WriteFreely configuration file:

# Get current pod name
POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Edit config.ini directly
kubectl -n writefreely-system exec -it $POD_NAME -- vi /data/config.ini

# Or copy out, edit locally, and copy back
kubectl -n writefreely-system cp $POD_NAME:/data/config.ini ./config.ini
# Edit config.ini locally
kubectl -n writefreely-system cp ./config.ini $POD_NAME:/data/config.ini

View current configuration

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')
kubectl -n writefreely-system exec $POD_NAME -- cat /data/config.ini

Restart after config changes

kubectl -n writefreely-system rollout restart deployment writefreely

🔧 Admin Commands

WriteFreely includes several admin commands for user and database management:

Create additional users

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Create admin user
kubectl -n writefreely-system exec $POD_NAME -- /writefreely/writefreely -c /data/config.ini user create --admin username:password

# Create regular user (requires existing admin)
kubectl -n writefreely-system exec $POD_NAME -- /writefreely/writefreely -c /data/config.ini user create username:password

Reset user password

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')
kubectl -n writefreely-system exec -it $POD_NAME -- /writefreely/writefreely -c /data/config.ini user reset-pass username

Database operations

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Initialize database (if needed)
kubectl -n writefreely-system exec $POD_NAME -- /writefreely/writefreely -c /data/config.ini db init

# Migrate database schema
kubectl -n writefreely-system exec $POD_NAME -- /writefreely/writefreely -c /data/config.ini db migrate

📊 Monitoring and Logs

View application logs

# Live logs
kubectl -n writefreely-system logs -f -l app=writefreely

# Recent logs
kubectl -n writefreely-system logs -l app=writefreely --tail=100

Check pod status

kubectl -n writefreely-system get pods -l app=writefreely
kubectl -n writefreely-system describe pod -l app=writefreely

Check persistent storage

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Check data directory contents
kubectl -n writefreely-system exec $POD_NAME -- ls -la /data/

# Check database size
kubectl -n writefreely-system exec $POD_NAME -- du -h /data/writefreely.db

# Check encryption keys
kubectl -n writefreely-system exec $POD_NAME -- ls -la /data/keys/

🔐 Security

Password Management

The admin password is stored in a Kubernetes secret:

# View current password (base64 encoded)
kubectl -n writefreely-system get secret writefreely-secret -o jsonpath='{.data.admin-password}' | base64 -d

# Update password (regenerate secret)
# Edit manifests/applications/write-freely/secret.yaml and apply

SSL Certificates

SSL certificates are automatically managed by cert-manager and Let's Encrypt:

# Check certificate status
kubectl -n writefreely-system get certificates
kubectl -n writefreely-system describe certificate writefreely-tls

🔄 Backup and Restore

Database Backup

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Backup database
kubectl -n writefreely-system exec $POD_NAME -- cp /data/writefreely.db /data/writefreely-backup-$(date +%Y%m%d).db

# Copy backup locally
kubectl -n writefreely-system cp $POD_NAME:/data/writefreely-backup-$(date +%Y%m%d).db ./writefreely-backup-$(date +%Y%m%d).db

Full Data Backup

The entire /data directory is stored in a Longhorn persistent volume with automatic S3 backup to Backblaze B2.

🐛 Troubleshooting

Common Issues

  1. "Unable to load config.ini": Ensure config file exists in /data/config.ini and is writable
  2. "Username admin is invalid": Use non-reserved usernames (avoid "admin", "administrator")
  3. "Read-only file system": Config file must be in writable location (/data/config.ini)
  4. CSS/JS not loading: Check ingress configuration and static file serving

Reset to Clean State

# Delete pod to force recreation
kubectl -n writefreely-system delete pod -l app=writefreely

# If needed, delete persistent data (WARNING: This will delete all blog content)
# kubectl -n writefreely-system delete pvc writefreely-data

Debug Commands

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')

# Check environment variables
kubectl -n writefreely-system exec $POD_NAME -- env | grep WRITEFREELY

# Check file permissions
kubectl -n writefreely-system exec $POD_NAME -- ls -la /data/
kubectl -n writefreely-system exec $POD_NAME -- ls -la /writefreely/

# Interactive shell for debugging
kubectl -n writefreely-system exec -it $POD_NAME -- sh

⚠️ Critical Configuration Settings

Theme Configuration (Required)

Important: The theme setting must not be empty or CSS/JS files will not load properly.

[app]
theme = write

Symptoms of missing theme:

  • CSS files return 404 or malformed URLs like /css/.css
  • Blog appears unstyled
  • JavaScript not loading

Fix: Edit the config file and set theme = write:

POD_NAME=$(kubectl -n writefreely-system get pods -l app=writefreely -o jsonpath='{.items[0].metadata.name}')
kubectl -n writefreely-system exec -it $POD_NAME -- vi /data/config-writable.ini

# Add or update in the [app] section:
# theme = write

# Restart after changes
kubectl -n writefreely-system rollout restart deployment writefreely

📝 Configuration Reference

Key configuration sections in config.ini:

  • [server]: Host, port, and TLS settings
  • [database]: Database connection and file paths
  • [app]: Site name, description, federation settings
  • [auth]: User authentication and registration settings
  • [federation]: ActivityPub and federation configuration
  • [users]: User creation and management settings

For detailed configuration options, see the WriteFreely documentation.