Skip to content

Backup Restore

Sia edited this page May 31, 2026 · 3 revisions

Backup & Restore

One-click tar.gz of the workspace plus a ready-to-paste pg_dump command for PostgreSQL.

View at /backup (left nav: "백업").

What the page does

Section Content
Sizes table Walks each subdirectory of workspace.root (typically vibe-coder-data/) and reports the size with bytes-human formatting.
tar.gz download GET /backup/download streams a gzip-tar of the workspace (excludes listed below). Filename vibe-workspace-<yyyyMMdd-HHmm>.tar.gz.
PostgreSQL block A copy-paste pg_dump command for logical backups + a pg_restore command for the recovery side.
Restore procedure Three-line shell snippet for getting a backup running on a fresh host.

What's excluded from the tar.gz

The slim default backup leaves out everything that is either too large or too unsafe to put in a streaming tar:

Excluded path Reason
postgres/ Live PG data dir — page-tear risk; use pg_dump instead
dev-tools/gradle/caches Re-downloadable from Maven Central
dev-tools/gradle/daemon JVM warm pool / daemon log
dev-tools/npm-cache Re-fetchable from npm registry
dev-tools/playwright Re-downloaded browsers
.vibecoder/__scratch__/ General Chat scratch workspace
.vibecoder/*/logs/ Build logs (often the largest single dir)
.DS_Store macOS metadata noise

So a typical workspace that's 20 GB on disk usually backs up as a few hundred MB.

tar.gz mechanics

  • Streaming via org.apache.commons:commons-compress:1.27.1 (TarArchiveOutputStream over GZIPOutputStream). No temp file.
  • setLongFileMode(LONGFILE_POSIX) so long paths don't truncate.
  • Walks workspace.root with Files.walk(root).use { … } so directory handles are released even on error.
  • Per-file try { … } swallow — one unreadable file (permissions, race) doesn't kill the whole stream.

PostgreSQL backup

Live PG data dir copy is unsafe (raw page tear during writes), so the page surfaces a logical-dump command:

docker exec vibe-coder-postgres \
  pg_dump -U vibecoder -F c vibecoder \
  > vibe-pg-$(date +%F).pgdump

-F c is the custom binary format which supports parallel restore and is the recommended choice for non-trivial DBs.

To restore on a fresh server:

docker compose up -d postgres
docker exec -i vibe-coder-postgres \
  pg_restore -U vibecoder -d vibecoder -c \
  < vibe-pg-YYYY-MM-DD.pgdump
docker compose up -d vibe-coder-server

The -c flag drops existing objects before recreating — clean restore into an empty vibecoder database.

Restore procedure (workspace)

mkdir -p vibe-coder/vibe-coder-data
cd vibe-coder
tar xzf vibe-workspace-YYYYMMDD-HHmm.tar.gz -C vibe-coder-data/

# Bring back .env / compose.yml separately (those are committed to your
# private ops repo, not the workspace backup).
docker compose up -d

The tar contains paths relative to workspace.root, so extracting into vibe-coder-data/ recreates the same structure as the original host.

What isn't backed up

  • .env, docker-compose.yml, Dockerfile modifications — keep these in your ops repo, not in the workspace tar.
  • The image itself — already on Docker Hub.
  • The Claude OAuth credentials live at vibe-coder-data/claude/. They are included by default since they're inside the workspace tree (and they're already encrypted by Claude CLI). If you want them out, add claude to the exclusion list in BackupRoutes.kt.

Automation

Scheduled in-server backup, cron-driven. Disabled by default; opt-in:

# server.yml
backup:
  enabled: true
  cron: "03:00"        # daily 3 AM (HH:MM, *:MM, *:* — same as build scheduler)
  retentionCount: 7    # keep the most-recent 7 .tar.gz files

Files land in <workspace>/.vibecoder/backups/<ts>.tar.gz. The /backup page shows a list with per-file download / delete + a "Run now" button that triggers an immediate backup + rotation (useful as a smoke test).

Exclusion list is identical to the manual download, plus .vibecoder/backups/ itself so the backup never includes prior backups (would grow unbounded).

BackupService is shared between the manual download and the scheduler — same walk logic, same tar pipeline.

Roadmap

  • Progress bar. Streaming tar gives no progress signal — large workspaces look frozen. WebSocket-fed byte count is a small UI add.
  • Direct S3 / B2 upload. Instead of downloading to your laptop first.
  • Encrypted backups. Optional --passphrase → tar piped through openssl enc.

Clone this wiki locally