# 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)