Skip to content

Add GOBLOG_DATA_DIR: one directory for everything goblog writes - #661

Merged
compscidr merged 2 commits into
mainfrom
feat/data-dir
Oct 3, 2026
Merged

compscidr merged 2 commits into
mainfrom
feat/data-dir

Conversation

@compscidr

Copy link
Copy Markdown
Collaborator

Closes #653.

Problem

goblog writes its state into its working directory, mixed in with the files it ships: .env, the SQLite file, www/uploads, plugins/wasm, plugins/dynamic and themes/installed. The documented quick start (docker run -p 7000:7000 compscidr/goblog:latest) therefore loses the whole site when the container is replaced, and keeping it takes one bind mount per path.

Change

New datadir package and GOBLOG_DATA_DIR environment variable. When set, everything goblog writes lives under it:

without with GOBLOG_DATA_DIR=/data
.env ./.env /data/.env
SQLite (relative path) ./goblog.db /data/goblog.db
uploads ./www/uploads/ /data/uploads/, served at /uploads
plugins ./plugins/{wasm,dynamic}/ /data/plugins/{wasm,dynamic}/
installed themes ./themes/installed/ /data/themes/installed/
  • An absolute SQLite path is used as given. THEMES_INSTALLED_DIR still wins for themes.
  • The directory is created at startup if missing.
  • Unset, every path is exactly what it was. The Docker image does not set it, so existing deployments (per-path bind mounts) are unaffected.

The README quick start becomes:

docker run -p 7000:7000 -e GOBLOG_DATA_DIR=/data -v goblog-data:/data compscidr/goblog:latest

Smoke test

The install smoke test now runs the container that way, uploads a file during the wizard, then removes the container and starts a new one on the same volume, and checks the site, its title and the upload are still there. A fourth CI job (sqlite, no data directory) keeps covering the old layout with a restart.

Testing

  • go test ./... passes, including a new datadir test.
  • The smoke test passes locally for sqlite, mysql and postgres with the data volume, and for sqlite in the old layout.

Not covered

  • Moving an existing site into a data directory is manual (copy the files in the table); there is no migration and the README does not walk through it.
  • Installed plugins and themes go through datadir.Path, but the smoke test does not install one, so those two paths are untested end to end.
  • /wp-content/uploads, the WordPress-compatibility route, still reads only from www.
  • local.env, the development fallback, is still read from the working directory.
  • The goblog.live homepage (in goblog-site-theme) still shows the old one-line docker run.

🤖 Generated with Claude Code

goblog writes .env, the SQLite file, uploads and installed plugins and
themes into its working directory, next to the files it ships with. In a
container that means the documented quick start loses the whole site when
the container is replaced, and keeping it takes a bind mount per path.

With GOBLOG_DATA_DIR set, all of those live under that directory, so one
volume keeps the site. A relative SQLite path is resolved inside it;
absolute paths and THEMES_INSTALLED_DIR are left alone. Unset, every path
is what it was, so existing installs are unaffected.

The install smoke test now runs with a data volume and replaces the
container half way through, checking the site, its settings and an
uploaded file are still there. A fourth job covers the old layout.

Closes #653.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 3, 2026 15:20
@codecov

codecov Bot commented Oct 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
admin/admin.go 25.00% 1 Missing and 2 partials ⚠️
wizard/wizard.go 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

The include entry only added a key to the existing sqlite job, so the
matrix ran sqlite without a data directory and never with one. Making
legacy a matrix key gives the include its own job.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The CI matrix include merges legacy into the existing sqlite combination instead of adding a fourth job, so the SQLite-on-a-volume scenario central to #653 is never smoke-tested.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

This PR introduces a GOBLOG_DATA_DIR environment variable and a small datadir package so that everything goblog writes at runtime (.env, the SQLite database, uploads, installed plugins, and installed themes) can live under a single directory. The goal (issue #653) is that a Docker user can keep one volume and not lose their site when the container is replaced on an image upgrade. When unset, every path stays exactly as before, so existing deployments are unaffected.

Changes:

  • New datadir package (Dir()/Path()) that prefixes GOBLOG_DATA_DIR for relative paths, leaving absolute paths untouched; wired into .env, SQLite, uploads, plugin, and theme paths.
  • Uploads are written under <data>/uploads and served at /uploads (falling through to www); the data directory is created at startup.
  • README quick-start updated to use the volume, and the install smoke test / CI matrix extended to cover container replacement on a volume plus a legacy (no data dir) layout.
File Description
datadir/​datadir.go New package resolving writable paths under GOBLOG_DATA_DIR.
datadir/​datadir_test.go Unit test for Path() (relative, absolute, unset).
goblog.go Routes .env, plugin dirs, and uploads serving through datadir; creates the data dir at startup.
db.go Opens the SQLite file via datadir.Path.
admin/​admin.go Writes uploads to <data>/uploads when a data dir is set.
theme/​theme.go InstalledRoot now resolves under the data dir (unless THEMES_INSTALLED_DIR set).
wizard/​wizard.go, auth/​auth.go, blog/​blog.go .env loads/writes go through datadir.Path (keeping local.env fallback).
scripts/​install-smoke-test.sh Runs on a volume, replaces the container, uploads a file, and verifies persistence; legacy mode restarts instead.
.github/​workflows/​install-smoke.yml Adds a legacy matrix entry and passes GOBLOG_SMOKE_LEGACY.
README.md Documents GOBLOG_DATA_DIR in the Docker quick start and plugins section.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/install-smoke.yml
@compscidr
compscidr merged commit b5297e0 into main Oct 3, 2026
5 checks passed
@compscidr
compscidr deleted the feat/data-dir branch October 3, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quick start loses the site when the container is replaced

2 participants