This is an old revision of the document!
Table of Contents
WriteFreely SQLite Database Opened Read-Only at Startup
Status: Resolved
Date: 2026-06-29
Affected service: WriteFreely (write.folk.zone)
Symptom
Attempting to register a new account returned a 500 error page:
"This is an unhelpful error message for a miscellaneous internal error."
The JSON response body was:
{"code":500,"error_msg":"This is an unhelpful error message for a miscellaneous internal error."}
Container logs showed:
ERROR: database.go:233: Rolling back users INSERT: attempt to write a readonly database ERROR: handle.go:539: [Web handler] 500: attempt to write a readonly database
Root Cause
The SQLite database file (writefreely.db) was owned by UID 1000 (the host user brennan), but the WriteFreely process inside the container runs as UID 5000 (writefreely). The file permissions were 644, so the process could read but not write the file.
Critically, WriteFreely opens its SQLite connection at startup. If the file is not writable at that moment, the connection is established in read-only mode and stays that way for the lifetime of the process. Fixing the file permissions alone (without restarting the container) has no effect on the existing connection.
The algernon/writefreely image does not apply WRITEFREELY_DB_* environment variables to an existing config.ini. Once config.ini is present in the data volume, it is used as-is. The compose env vars are only effective on first initialisation.
Fix
1. Fix ownership of the database file:
docker exec --user root folkzone-write chown writefreely:writefreely /data/writefreely.db
2. Restart the container so WriteFreely reopens the database connection with the corrected permissions:
cd /home/brennan/homelab/server docker compose restart folkzone-write
Confirm the startup log shows Connected to database. with no errors before testing again.
Notes
- The data volume (
folkzone_write_data) persists the ownership change across container restarts, so this fix is permanent unless the volume is recreated. - If the volume is ever recreated from a backup or file copy, ensure the
writefreely.dbfile is owned by UID 5000 before starting the container. - This instance uses SQLite, not the MariaDB container also present in the stack. The
WRITEFREELY_DB_TYPE=mysqlenv var indocker-compose.ymlhas no effect becauseconfig.inialready existed.
