Files
Michael DiLeo 7327d77dcd redaction (#1)
Add the redacted source file for demo purposes

Reviewed-on: https://source.michaeldileo.org/michael_dileo/Keybard-Vagabond-Demo/pulls/1
Co-authored-by: Michael DiLeo <michael_dileo@proton.me>
Co-committed-by: Michael DiLeo <michael_dileo@proton.me>
2025-12-24 13:40:47 +00:00

272 lines
8.9 KiB
Markdown

# 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:
```bash
# 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
```bash
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
```bash
kubectl -n writefreely-system rollout restart deployment writefreely
```
## 🔧 Admin Commands
WriteFreely includes several admin commands for user and database management:
### Create additional users
```bash
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
```bash
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
```bash
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
```bash
# 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
```bash
kubectl -n writefreely-system get pods -l app=writefreely
kubectl -n writefreely-system describe pod -l app=writefreely
```
### Check persistent storage
```bash
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:
```bash
# 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:
```bash
# Check certificate status
kubectl -n writefreely-system get certificates
kubectl -n writefreely-system describe certificate writefreely-tls
```
## 🔄 Backup and Restore
### Database Backup
```bash
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
```bash
# 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
```bash
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.
```ini
[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`:
```bash
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](https://writefreely.org/docs/main/admin/config).
## 🔗 Links
- [WriteFreely Documentation](https://writefreely.org/docs/)
- [WriteFreely Admin Commands](https://writefreely.org/docs/main/admin/commands)
- [WriteFreely GitHub](https://github.com/writefreely/writefreely)