Skip to content

feat: add Neo4j and CouchDB backup/restore support#471

Open
IronAlloy wants to merge 4 commits intonfrastack:mainfrom
IronAlloy:feat/neo4j-couchdb
Open

feat: add Neo4j and CouchDB backup/restore support#471
IronAlloy wants to merge 4 commits intonfrastack:mainfrom
IronAlloy:feat/neo4j-couchdb

Conversation

@IronAlloy
Copy link
Copy Markdown

Summary

Adds backup and restore support for Neo4j and CouchDB, rebased onto the latest main (4.1.100). This supersedes #448 which only covered Neo4j.

Neo4j

  • Backup via cypher-shell using apoc.export.cypher.all().cypher files
  • Connectivity check via cypher-shell query
  • cypher-shell installed from Neo4j community edition (NEO4J_VERSION=5.26.0)

CouchDB

The project previously had skeletal CouchDB support (type detection + availability check), but backup_couch() was missing the actual backup command, and there was no restore support.

  • Backup: Uses the HTTP REST API (curl + _all_docs?include_docs=true) — no client binary needed
    • Supports DB_NAME=ALL to enumerate all non-system databases via _all_dbs
    • Supports comma-separated DB_NAME list
    • Supports DB_NAME_EXCLUDE when using ALL
    • System databases (prefixed with _) filtered automatically
    • Output is JSON (.json extension)
  • Restore: Creates the database, strips _rev from documents via jq, posts via _bulk_docs
    • Interactive drop-or-merge prompt (same UX as Mongo restore)
  • Bug fix: backup_job_backup_job_db_portbackup_job_db_port (double prefix bug in the CouchDB bootstrap case)
  • Adds jq to runtime dependencies (needed for restore)
  • Documents DB_NAME / DB_NAME_EXCLUDE for CouchDB in the README

Test plan

  • Build image succeeds
  • Neo4j backup + restore round-trip
  • CouchDB backup with DB_NAME=testdb
  • CouchDB backup with DB_NAME=ALL (system DBs excluded)
  • CouchDB backup with DB_NAME=ALL + DB_NAME_EXCLUDE=somedb
  • CouchDB restore (drop mode) — verify all documents present
  • CouchDB restore (merge mode) — verify documents updated
  • Compression works across gzip/zstd/none for both DB types

Closes #448

IronAlloy and others added 2 commits April 5, 2026 17:53
The upstream workflow required DockerHub secrets that aren't set on this
fork, blocking builds. Replace with standalone workflows that push
multi-arch images to ghcr.io/${{ github.repository }} using only the
built-in GITHUB_TOKEN, so builds succeed without external credentials.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tiredofit
Copy link
Copy Markdown
Collaborator

Thanks for your work. Going to leave open for now until I am ready to release the Nfrastack variant of this image.

IronAlloy and others added 2 commits April 17, 2026 17:09
latest-* backup files have no extension, causing the compression
detection case-statement to fall through and leave decompress_cmd
unset. Plain cat then piped raw compressed bytes into jq/the DB
client, producing invalid UTF-8 / parse errors and a zero-document
restore.

Fix: resolve symlinks before extension sniffing, and fall back to
`file --brief --mime-type` magic-byte detection when no recognizable
extension is found. Applies to all DB types (MySQL, Postgres, MongoDB,
Neo4j, CouchDB, Redis).

Also adds rdbtools/python-lzf to the image for Redis RDB restore support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

2 participants