kamal-backup 0.1.0.pre.2 → 0.1.0.pre.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +162 -230
- data/exe/kamal-backup +4 -0
- data/lib/kamal_backup/app.rb +368 -0
- data/lib/kamal_backup/cli.rb +330 -117
- data/lib/kamal_backup/command.rb +33 -19
- data/lib/kamal_backup/config.rb +232 -79
- data/lib/kamal_backup/databases/base.rb +41 -17
- data/lib/kamal_backup/databases/mysql.rb +70 -60
- data/lib/kamal_backup/databases/postgres.rb +63 -67
- data/lib/kamal_backup/databases/sqlite.rb +23 -25
- data/lib/kamal_backup/evidence.rb +51 -39
- data/lib/kamal_backup/kamal_bridge.rb +120 -0
- data/lib/kamal_backup/redactor.rb +12 -14
- data/lib/kamal_backup/restic.rb +80 -78
- data/lib/kamal_backup/scheduler.rb +13 -14
- data/lib/kamal_backup/schema.rb +12 -0
- data/lib/kamal_backup/version.rb +1 -1
- data/lib/kamal_backup.rb +3 -0
- metadata +40 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ed4e21bfee7ac0e789c3a0706626062055c92701128b5999a3828f5f3190057
|
|
4
|
+
data.tar.gz: 5983618fb0fb16db51cfa82f4ff28398c00568d7a5082fd494a7063c944b111d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 227a34dc536cd9d5ca13cb2853fcac13c03c5defbe87e406374c1ebc7b94e7cc094693903aab1e7b6addb2b2a11913bae419767cb0e242f56d86818171bacb79
|
|
7
|
+
data.tar.gz: 16788fa7108df55c2afa70f900511ce6574c931be8459774649ebcb533c415873e4424d8172e0df987804f6509f4aea7fb398676cd3741ff0c59fddf6d7e9a74
|
data/README.md
CHANGED
|
@@ -1,40 +1,60 @@
|
|
|
1
1
|
# kamal-backup
|
|
2
2
|
|
|
3
|
-
`kamal-backup`
|
|
3
|
+
`kamal-backup` gives Rails apps a clean backup and restore workflow for Kamal.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It backs up:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- PostgreSQL, MySQL/MariaDB, or SQLite
|
|
8
|
+
- file-backed Active Storage and other mounted app files
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
- Kamal MySQL and MariaDB backup
|
|
11
|
-
- Kamal Active Storage backup
|
|
12
|
-
- Kamal restic backup
|
|
13
|
-
- Restore drills and evidence for security reviews such as CASA
|
|
10
|
+
It restores in two clear modes:
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
- `restore local`: pull a production backup onto your machine
|
|
13
|
+
- `restore production`: restore back into live production
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
And it drills in two clear modes:
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
- `drill local`: prove the backup works on your machine
|
|
18
|
+
- `drill production`: restore into scratch targets on production infrastructure, run checks, and record evidence
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
Under the hood it uses [restic](https://restic.net/) for encrypted backup storage and repository management.
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
## Why Rails teams use it
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
`kamal-backup` is aimed at the common self-hosted Rails setup where:
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
- the app is deployed with Kamal
|
|
27
|
+
- the database is PostgreSQL, MySQL/MariaDB, or SQLite
|
|
28
|
+
- file data lives on a mounted volume
|
|
29
|
+
- you need real restore drills and evidence for CASA or another security review
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
If your app already stores Active Storage blobs directly in S3, there may be no local file path for `BACKUP_PATHS` to capture. In that case, `kamal-backup` still covers the database side, but object-storage backups are a separate concern.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
Add the gem in your Rails app:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
group :development do
|
|
39
|
+
gem "kamal-backup"
|
|
40
|
+
end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Install it and generate the local config stubs:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
bundle install
|
|
47
|
+
bundle exec kamal-backup init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That creates:
|
|
37
51
|
|
|
52
|
+
- `config/kamal-backup.yml`
|
|
53
|
+
- `config/kamal-backup.local.yml`
|
|
54
|
+
|
|
55
|
+
Then add the backup accessory to `config/deploy.yml`:
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
38
58
|
accessories:
|
|
39
59
|
backup:
|
|
40
60
|
image: ghcr.io/crmne/kamal-backup:latest
|
|
@@ -64,294 +84,206 @@ bin/kamal accessory boot backup
|
|
|
64
84
|
bin/kamal accessory logs backup
|
|
65
85
|
```
|
|
66
86
|
|
|
67
|
-
Run
|
|
87
|
+
Run the first backup from your app checkout with the local gem and Kamal-style destination selection:
|
|
68
88
|
|
|
69
89
|
```sh
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
bin/kamal backup-evidence
|
|
74
|
-
bin/kamal backup-logs
|
|
90
|
+
bundle exec kamal-backup -d production backup
|
|
91
|
+
bundle exec kamal-backup -d production list
|
|
92
|
+
bundle exec kamal-backup -d production evidence
|
|
75
93
|
```
|
|
76
94
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Alias | Expands to | Use |
|
|
80
|
-
|---|---|---|
|
|
81
|
-
| `bin/kamal backup` | `accessory exec backup "kamal-backup backup"` | Run one backup immediately. |
|
|
82
|
-
| `bin/kamal backup-list` | `accessory exec backup "kamal-backup list"` | Show restic snapshots for the configured app. |
|
|
83
|
-
| `bin/kamal backup-check` | `accessory exec backup "kamal-backup check"` | Run `restic check` and store the latest check result. |
|
|
84
|
-
| `bin/kamal backup-evidence` | `accessory exec backup "kamal-backup evidence"` | Print redacted backup evidence JSON. |
|
|
85
|
-
| `bin/kamal backup-logs` | `accessory logs backup -f` | Tail the backup accessory logs. |
|
|
86
|
-
|
|
87
|
-
## Commands
|
|
88
|
-
|
|
89
|
-
Commands usually run inside the production backup accessory with `bin/kamal accessory exec backup "kamal-backup <command>"`, or through Kamal aliases such as `bin/kamal backup`. A local gem install is useful when you intentionally want the operator laptop to run restic and database client commands directly.
|
|
95
|
+
If you keep multiple deploy configs, pass `-c` the same way Kamal does:
|
|
90
96
|
|
|
91
97
|
```sh
|
|
92
|
-
kamal-backup backup
|
|
93
|
-
kamal-backup restore-db [snapshot-or-latest]
|
|
94
|
-
kamal-backup restore-files [snapshot-or-latest] [target-dir]
|
|
95
|
-
kamal-backup list
|
|
96
|
-
kamal-backup check
|
|
97
|
-
kamal-backup evidence
|
|
98
|
-
kamal-backup schedule
|
|
99
|
-
kamal-backup version
|
|
98
|
+
bundle exec kamal-backup -c config/deploy.staging.yml -d staging backup
|
|
100
99
|
```
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|---|---|
|
|
104
|
-
| `backup` | Runs one immediate backup, creating one database snapshot and one file snapshot for all `BACKUP_PATHS`. |
|
|
105
|
-
| `restore-db [snapshot-or-latest]` | Restores a database dump. Defaults to `latest` and requires explicit restore environment. |
|
|
106
|
-
| `restore-files [snapshot-or-latest] [target-dir]` | Restores file paths from a file snapshot. Defaults to `latest /restore/files`. |
|
|
107
|
-
| `list` | Lists restic snapshots for the configured app tags. |
|
|
108
|
-
| `check` | Runs `restic check` and records the latest result for evidence output. |
|
|
109
|
-
| `evidence` | Prints redacted JSON with backup configuration, latest snapshots, check status, and tool versions. |
|
|
110
|
-
| `schedule` | Runs the foreground scheduler loop used by the container default command. |
|
|
111
|
-
| `version` | Prints the gem version. `--version` and `-v` do the same. |
|
|
101
|
+
Examples live in:
|
|
112
102
|
|
|
113
|
-
|
|
103
|
+
- [examples/kamal-accessory.yml](examples/kamal-accessory.yml)
|
|
104
|
+
- [examples/kamal-backup.yml.example](examples/kamal-backup.yml.example)
|
|
105
|
+
- [examples/kamal-backup.local.yml.example](examples/kamal-backup.local.yml.example)
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
kamal-backup schedule
|
|
117
|
-
```
|
|
107
|
+
## What Restic Does Here
|
|
118
108
|
|
|
119
|
-
|
|
109
|
+
`kamal-backup` uses restic as the backup engine and repository format.
|
|
120
110
|
|
|
121
|
-
|
|
111
|
+
In the normal Kamal setup, you do not install restic on the Rails app host. The backup accessory image already includes it. You only point the accessory at a restic repository, usually:
|
|
122
112
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
RESTIC_REPOSITORY=s3:https://s3.example.com/chatwithwork-backups
|
|
127
|
-
RESTIC_PASSWORD=change-me
|
|
128
|
-
BACKUP_PATHS=/data/storage
|
|
129
|
-
```
|
|
113
|
+
- S3-compatible object storage
|
|
114
|
+
- a restic REST server
|
|
115
|
+
- a filesystem path for local development
|
|
130
116
|
|
|
131
|
-
|
|
117
|
+
If you choose a `rest:` repository, `kamal-backup` does not install or operate that server for you. It is a separate service.
|
|
132
118
|
|
|
133
|
-
|
|
119
|
+
## Commands
|
|
134
120
|
|
|
135
|
-
|
|
136
|
-
DATABASE_ADAPTER=postgres
|
|
137
|
-
DATABASE_URL=postgres://app@app-db:5432/app_production
|
|
138
|
-
PGPASSWORD=change-me
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
MySQL/MariaDB:
|
|
121
|
+
The operator-facing command surface is:
|
|
142
122
|
|
|
143
123
|
```sh
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
124
|
+
kamal-backup init
|
|
125
|
+
kamal-backup backup
|
|
126
|
+
kamal-backup restore local [snapshot-or-latest]
|
|
127
|
+
kamal-backup restore production [snapshot-or-latest]
|
|
128
|
+
kamal-backup drill local [snapshot-or-latest]
|
|
129
|
+
kamal-backup drill production [snapshot-or-latest]
|
|
130
|
+
kamal-backup list
|
|
131
|
+
kamal-backup check
|
|
132
|
+
kamal-backup evidence
|
|
133
|
+
kamal-backup schedule
|
|
134
|
+
kamal-backup version
|
|
147
135
|
```
|
|
148
136
|
|
|
149
|
-
|
|
137
|
+
Production-side commands shell out through Kamal when you pass `-d` or `-c`. Local commands run on your machine.
|
|
150
138
|
|
|
151
|
-
|
|
152
|
-
DATABASE_ADAPTER=sqlite
|
|
153
|
-
SQLITE_DATABASE_PATH=/data/db/production.sqlite3
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Retention defaults:
|
|
139
|
+
Common examples:
|
|
157
140
|
|
|
158
141
|
```sh
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
142
|
+
bundle exec kamal-backup -d production backup
|
|
143
|
+
bundle exec kamal-backup -d production check
|
|
144
|
+
bundle exec kamal-backup -d production evidence
|
|
145
|
+
bundle exec kamal-backup -d production restore production latest
|
|
146
|
+
bundle exec kamal-backup -d production drill production latest --database app_restore_20260423 --files /restore/files
|
|
147
|
+
bundle exec kamal-backup -d production version
|
|
148
|
+
bundle exec kamal-backup restore local latest
|
|
149
|
+
bundle exec kamal-backup drill local latest --check "bin/rails runner 'puts User.count'"
|
|
165
150
|
```
|
|
166
151
|
|
|
167
|
-
|
|
152
|
+
Use `kamal-backup help`, `kamal-backup help restore`, or `kamal-backup help drill` for task-specific usage.
|
|
168
153
|
|
|
169
|
-
|
|
154
|
+
## How a Backup Run Works
|
|
170
155
|
|
|
171
|
-
|
|
172
|
-
BACKUP_SCHEDULE_SECONDS=86400
|
|
173
|
-
BACKUP_START_DELAY_SECONDS=0
|
|
174
|
-
RESTIC_CHECK_AFTER_BACKUP=false
|
|
175
|
-
RESTIC_CHECK_READ_DATA_SUBSET=5%
|
|
176
|
-
```
|
|
156
|
+
When `kamal-backup backup` runs, it does five things:
|
|
177
157
|
|
|
178
|
-
|
|
158
|
+
1. Validates the app name, restic repository, database settings, and `BACKUP_PATHS`.
|
|
159
|
+
2. Creates a database backup with the database-native export tool.
|
|
160
|
+
3. Streams that database backup into restic with tags such as `type:database`, `adapter:<adapter>`, and `run:<timestamp>`.
|
|
161
|
+
4. Runs one `restic backup` for all configured `BACKUP_PATHS`, tagged as `type:files` with the same `run:<timestamp>`.
|
|
162
|
+
5. Optionally runs `restic forget --prune` and `restic check`.
|
|
179
163
|
|
|
180
|
-
|
|
181
|
-
AWS_ACCESS_KEY_ID=...
|
|
182
|
-
AWS_SECRET_ACCESS_KEY=...
|
|
183
|
-
AWS_DEFAULT_REGION=...
|
|
184
|
-
```
|
|
164
|
+
That shared `run:<timestamp>` tag lets you match the database backup and file backup from the same run.
|
|
185
165
|
|
|
186
|
-
## Restore
|
|
166
|
+
## Restore
|
|
187
167
|
|
|
188
|
-
|
|
168
|
+
`restore` means "put data back."
|
|
189
169
|
|
|
190
|
-
|
|
191
|
-
KAMAL_BACKUP_ALLOW_RESTORE=true
|
|
192
|
-
```
|
|
170
|
+
`restore local` runs on your machine. With `-d` or `-c`, it asks Kamal for the backup accessory config and uses that as the source of truth for:
|
|
193
171
|
|
|
194
|
-
|
|
172
|
+
- `APP_NAME`
|
|
173
|
+
- `DATABASE_ADAPTER`
|
|
174
|
+
- `RESTIC_REPOSITORY`
|
|
175
|
+
- `LOCAL_RESTORE_SOURCE_PATHS` from the accessory `BACKUP_PATHS`
|
|
195
176
|
|
|
196
|
-
|
|
177
|
+
You still provide the local targets yourself in `config/kamal-backup.local.yml` or env:
|
|
197
178
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
--env RESTORE_DATABASE_URL=postgres://app@app-db:5432/app_restore \
|
|
202
|
-
"kamal-backup restore-db latest"
|
|
203
|
-
```
|
|
179
|
+
- `DATABASE_URL` or `SQLITE_DATABASE_PATH`
|
|
180
|
+
- `BACKUP_PATHS`
|
|
181
|
+
- local secrets such as `RESTIC_PASSWORD` and DB passwords
|
|
204
182
|
|
|
205
|
-
|
|
183
|
+
Example:
|
|
206
184
|
|
|
207
185
|
```sh
|
|
208
|
-
|
|
209
|
-
--env KAMAL_BACKUP_ALLOW_RESTORE=true \
|
|
210
|
-
--env RESTORE_DATABASE_URL=mysql2://app@app-mysql:3306/app_restore \
|
|
211
|
-
"kamal-backup restore-db latest"
|
|
186
|
+
bundle exec kamal-backup -d production restore local latest
|
|
212
187
|
```
|
|
213
188
|
|
|
214
|
-
|
|
189
|
+
`restore production` is the emergency path back into the live production database and live production file paths:
|
|
215
190
|
|
|
216
191
|
```sh
|
|
217
|
-
|
|
218
|
-
--env KAMAL_BACKUP_ALLOW_RESTORE=true \
|
|
219
|
-
--env RESTORE_SQLITE_DATABASE_PATH=/restore/db/restore.sqlite3 \
|
|
220
|
-
"kamal-backup restore-db latest"
|
|
192
|
+
bundle exec kamal-backup -d production restore production latest
|
|
221
193
|
```
|
|
222
194
|
|
|
223
|
-
|
|
195
|
+
It prompts locally, then shells out through Kamal to the backup accessory.
|
|
224
196
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"kamal-backup restore-files latest /restore/files"
|
|
229
|
-
```
|
|
197
|
+
## Restore Drills
|
|
198
|
+
|
|
199
|
+
`drill` means "restore, check, and record the result."
|
|
230
200
|
|
|
231
|
-
|
|
201
|
+
`drill local` is often the fastest proof for a small app:
|
|
232
202
|
|
|
233
203
|
```sh
|
|
234
|
-
|
|
204
|
+
bundle exec kamal-backup -d production drill local latest --check "bin/rails runner 'puts User.count'"
|
|
235
205
|
```
|
|
236
206
|
|
|
237
|
-
|
|
207
|
+
`drill production` restores into scratch targets on production infrastructure. It does not touch the live production database:
|
|
238
208
|
|
|
239
209
|
```sh
|
|
240
|
-
|
|
210
|
+
bundle exec kamal-backup -d production drill production latest \
|
|
211
|
+
--database app_restore_20260423 \
|
|
212
|
+
--files /restore/files \
|
|
213
|
+
--check "test -d /restore/files/data/storage"
|
|
241
214
|
```
|
|
242
215
|
|
|
243
|
-
|
|
216
|
+
Every drill writes `last_restore_drill.json` under `KAMAL_BACKUP_STATE_DIR`, and `kamal-backup evidence` includes that latest result.
|
|
244
217
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
- app name
|
|
248
|
-
- current time
|
|
249
|
-
- database adapter
|
|
250
|
-
- redacted restic repository
|
|
251
|
-
- configured file backup paths
|
|
252
|
-
- whether client-side forget/prune is enabled
|
|
253
|
-
- retention policy
|
|
254
|
-
- latest database and file snapshots
|
|
255
|
-
- last tracked `restic check` result
|
|
256
|
-
- image version
|
|
257
|
-
- installed tool versions
|
|
218
|
+
## Evidence for CASA and Similar Reviews
|
|
258
219
|
|
|
259
|
-
|
|
220
|
+
`evidence` is the JSON summary you can attach to an ops record or security review.
|
|
260
221
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
```sh
|
|
264
|
-
bin/kamal accessory exec backup "kamal-backup evidence"
|
|
265
|
-
```
|
|
222
|
+
It includes:
|
|
266
223
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
224
|
+
- latest database and file snapshots
|
|
225
|
+
- latest `restic check` result
|
|
226
|
+
- latest restore drill result
|
|
227
|
+
- retention settings
|
|
228
|
+
- tool versions
|
|
270
229
|
|
|
271
|
-
|
|
272
|
-
bin/test
|
|
273
|
-
```
|
|
230
|
+
For many reviews, the useful sequence is:
|
|
274
231
|
|
|
275
|
-
|
|
232
|
+
1. scheduled backups
|
|
233
|
+
2. repository checks
|
|
234
|
+
3. a real restore drill
|
|
235
|
+
4. `kamal-backup evidence`
|
|
276
236
|
|
|
277
|
-
|
|
278
|
-
cd docs
|
|
279
|
-
bundle install
|
|
280
|
-
bundle exec jekyll serve --livereload
|
|
281
|
-
```
|
|
237
|
+
That reads much better to a reviewer than "the backup job is green."
|
|
282
238
|
|
|
283
|
-
|
|
239
|
+
## Configuration Highlights
|
|
284
240
|
|
|
285
|
-
|
|
241
|
+
Core accessory environment:
|
|
286
242
|
|
|
287
243
|
```sh
|
|
288
|
-
|
|
244
|
+
APP_NAME=chatwithwork
|
|
245
|
+
DATABASE_ADAPTER=postgres
|
|
246
|
+
RESTIC_REPOSITORY=s3:https://s3.example.com/chatwithwork-backups
|
|
247
|
+
RESTIC_PASSWORD=change-me
|
|
248
|
+
BACKUP_PATHS=/data/storage
|
|
289
249
|
```
|
|
290
250
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
The CLI is packaged as the `kamal-backup` gem. The Docker image builds and installs that gem, which is why `kamal-backup` is on `PATH` inside the container. On default-branch CI, a new gem version is published to RubyGems and GitHub Packages when it does not already exist. The RubyGems publish step expects the repository secret `RUBYGEMS_AUTH_TOKEN`.
|
|
294
|
-
|
|
295
|
-
For local Ruby use:
|
|
251
|
+
PostgreSQL:
|
|
296
252
|
|
|
297
253
|
```sh
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
254
|
+
DATABASE_ADAPTER=postgres
|
|
255
|
+
DATABASE_URL=postgres://app@app-db:5432/app_production
|
|
256
|
+
PGPASSWORD=change-me
|
|
301
257
|
```
|
|
302
258
|
|
|
303
|
-
|
|
259
|
+
MySQL/MariaDB:
|
|
304
260
|
|
|
305
261
|
```sh
|
|
306
|
-
|
|
262
|
+
DATABASE_ADAPTER=mysql
|
|
263
|
+
DATABASE_URL=mysql2://app@app-mysql:3306/app_production
|
|
264
|
+
MYSQL_PWD=change-me
|
|
307
265
|
```
|
|
308
266
|
|
|
309
|
-
|
|
267
|
+
SQLite:
|
|
310
268
|
|
|
311
269
|
```sh
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
export SQLITE_DATABASE_PATH=/tmp/app.sqlite3
|
|
315
|
-
export BACKUP_PATHS=/tmp/app-files
|
|
316
|
-
export RESTIC_REPOSITORY=/tmp/kamal-backup-restic
|
|
317
|
-
export RESTIC_PASSWORD=local-password
|
|
318
|
-
export RESTIC_INIT_IF_MISSING=true
|
|
319
|
-
|
|
320
|
-
kamal-backup backup
|
|
321
|
-
kamal-backup list
|
|
322
|
-
kamal-backup evidence
|
|
270
|
+
DATABASE_ADAPTER=sqlite
|
|
271
|
+
SQLITE_DATABASE_PATH=/data/db/production.sqlite3
|
|
323
272
|
```
|
|
324
273
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
## Container Contents
|
|
328
|
-
|
|
329
|
-
The image is based on Debian slim Ruby and includes:
|
|
330
|
-
|
|
331
|
-
- Ruby runtime
|
|
332
|
-
- `pg_dump` and `pg_restore`
|
|
333
|
-
- `mariadb-dump` or `mysqldump`, plus `mariadb` or `mysql`
|
|
334
|
-
- `sqlite3`
|
|
335
|
-
- `restic`
|
|
336
|
-
- CA certificates
|
|
337
|
-
- `tini`
|
|
338
|
-
|
|
339
|
-
## Security Notes
|
|
274
|
+
Local config files:
|
|
340
275
|
|
|
341
|
-
-
|
|
342
|
-
-
|
|
343
|
-
- Database backups use logical dump tools.
|
|
344
|
-
- File data should be mounted read-only in the backup accessory.
|
|
345
|
-
- Restores require explicit environment flags.
|
|
346
|
-
- Object storage credentials should be least-privilege for the backup bucket or prefix.
|
|
276
|
+
- `config/kamal-backup.yml`
|
|
277
|
+
- `config/kamal-backup.local.yml`
|
|
347
278
|
|
|
348
|
-
|
|
279
|
+
Keep secrets such as `RESTIC_PASSWORD`, cloud credentials, and local DB passwords in environment variables, not in YAML files.
|
|
349
280
|
|
|
350
|
-
|
|
351
|
-
- Not a replacement for database point-in-time recovery.
|
|
352
|
-
- Not a physical replication tool.
|
|
353
|
-
- Not a secret manager.
|
|
281
|
+
## Docs
|
|
354
282
|
|
|
355
|
-
|
|
283
|
+
Full docs live in [`docs/`](docs/):
|
|
356
284
|
|
|
357
|
-
|
|
285
|
+
- [`docs/_guide/getting-started.md`](docs/_guide/getting-started.md)
|
|
286
|
+
- [`docs/_guide/configuration.md`](docs/_guide/configuration.md)
|
|
287
|
+
- [`docs/_guide/restore.md`](docs/_guide/restore.md)
|
|
288
|
+
- [`docs/_guide/restore-drills.md`](docs/_guide/restore-drills.md)
|
|
289
|
+
- [`docs/_reference/commands.md`](docs/_reference/commands.md)
|