Compare commits

..
3 Commits
Author SHA1 Message Date
Stanko K.R. 2aa4141077 Port over automatic note generation 2026-08-04 17:13:07 +02:00
Stanko Krtalić 27e9257b2a Merge pull request #231 from basecamp/once-backup-hooks
Add ONCE backup and restore hooks
2026-08-04 17:11:19 +02:00
Kevin McConnell 2d749057f9 Add ONCE backup and restore hooks
By default, ONCE pauses the application container when taking a backup.
This guarantees a consistent snapshot of the data, but for a large
installation and/or a slow destination path (like a network mount), that
pause could be a bit disruptive to live traffic.

But ONCE also support a pause-free path: if a `pre-backup` hook is
present in the container, ONCE will run that and skip the pause. So by
supplying necessary hooks, we can avoid any disruption from backups.

- `pre-backup` runs the existing script/admin/prepare-backup, which uses
  SQLite's online backup API to get a consistent snapshop.

- `post-restore` moves our snaphotted file back into place, and removes
  the orphaned sidecar files
2026-08-03 12:41:01 +01:00
4 changed files with 34 additions and 10 deletions

No files matched your search

+3
View File
@@ -66,6 +66,9 @@ ENV HTTP_WRITE_TIMEOUT=300
COPY --from=build --chown=rails:rails /usr/local/bundle /usr/local/bundle COPY --from=build --chown=rails:rails /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=rails:rails /rails /rails COPY --from=build --chown=rails:rails /rails /rails
# Install ONCE backup/restore hooks
COPY --chmod=755 hooks /hooks
# Set version and revision # Set version and revision
ARG APP_VERSION ARG APP_VERSION
ENV APP_VERSION=$APP_VERSION ENV APP_VERSION=$APP_VERSION
+17 -10
View File
@@ -15,6 +15,7 @@ include SSHKit::DSL
ARCH = "linux/amd64,linux/arm64" ARCH = "linux/amd64,linux/arm64"
BUILDER_NAME = "campfire-builder" BUILDER_NAME = "campfire-builder"
GIT_SHA = `git rev-parse HEAD`.strip GIT_SHA = `git rev-parse HEAD`.strip
MANUAL_NOTES = ARGV.delete("--notes")
VERSION = ARGV[0] VERSION = ARGV[0]
DOCKER_IMAGE_NAME = "registry.once.com/campfire" DOCKER_IMAGE_NAME = "registry.once.com/campfire"
@@ -28,7 +29,7 @@ EXPORT_REMOTE_USER = "app"
EXPORT_DEPLOY_HOSTS = %w[ once-store-app-101 once-store-app-102 ] EXPORT_DEPLOY_HOSTS = %w[ once-store-app-101 once-store-app-102 ]
EXPORT_DEPLOY_LOCATION = "/local/app/product_releases/" EXPORT_DEPLOY_LOCATION = "/local/app/product_releases/"
abort "You must specify a version, e.g. `bin/release 1.0.0`" unless VERSION abort "You must specify a version, e.g. `bin/release 1.0.0` (pass --notes to write release notes manually)" unless VERSION
current_branch = `git rev-parse --abbrev-ref HEAD`.strip current_branch = `git rev-parse --abbrev-ref HEAD`.strip
if current_branch != "main" if current_branch != "main"
@@ -57,19 +58,25 @@ on(:local) do
end end
announcing "Creating GitHub release v#{VERSION}..." do announcing "Creating GitHub release v#{VERSION}..." do
notes_file = "tmp/release_notes.md"
on(:local) do on(:local) do
execute :mkdir, "-p", "tmp" if MANUAL_NOTES
notes_file = "tmp/release_notes.md"
File.write(notes_file, "# What's Changed\n\n- \n") execute :mkdir, "-p", "tmp"
system ENV["EDITOR"] || "vim", notes_file
unless system "gh", "release", "create", "v#{VERSION}", "--title", "v#{VERSION}", "--notes-file", notes_file File.write(notes_file, "# What's Changed\n\n- \n")
abort "Failed to create release; check that the version doesn't already exist" system ENV["EDITOR"] || "vim", notes_file
unless system "gh", "release", "create", "v#{VERSION}", "--title", "v#{VERSION}", "--notes-file", notes_file
abort "Failed to create release; check that the version doesn't already exist"
end
execute :rm, notes_file
else
unless system "gh", "release", "create", "v#{VERSION}", "--title", "v#{VERSION}", "--generate-notes"
abort "Failed to create release; check that the version doesn't already exist"
end
end end
execute :rm, notes_file
end end
end end
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
set -euo pipefail
db_name="${RAILS_ENV:-production}.sqlite3"
snapshot="/rails/storage/backups/$db_name"
db="/rails/storage/db/$db_name"
if [ -f "$snapshot" ]; then
mkdir -p "$(dirname "$db")"
cp "$snapshot" "$db"
rm -f "$db-wal" "$db-shm"
fi
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
exec /rails/script/admin/prepare-backup