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>
272 lines
8.9 KiB
Markdown
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) |