kamal-backup 0.1.0.pre.2 → 0.1.0.pre.9
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 +173 -228
- data/exe/kamal-backup +4 -0
- data/lib/kamal_backup/app.rb +368 -0
- data/lib/kamal_backup/cli.rb +315 -117
- data/lib/kamal_backup/command.rb +33 -19
- data/lib/kamal_backup/config.rb +237 -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/rails_app.rb +152 -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 +4 -0
- metadata +41 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dffee9d885ca23342a84ac3fc494d09f9f44b323a10ae981df4665f31206b20a
|
|
4
|
+
data.tar.gz: 0c6352b4f00008b54b22442f0b192eb54adf7f52c0350ab8cb5c69dd1cff9c4f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77f916eec58efe57ad7c1b65b8f93cab39d647b9051dc6d77cbebfa66f830cbc65bfdf9bdfc8aa0016109969a88b68bef8f2ea79a71a97ce4670b6c1028fa8ba
|
|
7
|
+
data.tar.gz: 631793de8449a07bf774f91a5bf7aea669b4773da960a27319cf8ecca00c6194a37214f36cc70c49857247406e665292318ad145f9c9e87d15f53751b92bf00a
|
data/README.md
CHANGED
|
@@ -1,40 +1,67 @@
|
|
|
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 shared config stub:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
bundle install
|
|
47
|
+
bundle exec kamal-backup init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That creates:
|
|
51
|
+
|
|
52
|
+
- `config/kamal-backup.yml`
|
|
53
|
+
|
|
54
|
+
For most Rails apps, that is enough. `restore local` and `drill local` can infer:
|
|
55
|
+
|
|
56
|
+
- the development database target from `config/database.yml`
|
|
57
|
+
- the local files target from `storage`
|
|
58
|
+
- the local drill state directory from `tmp/kamal-backup`
|
|
37
59
|
|
|
60
|
+
Only create `config/kamal-backup.local.yml` if you need to override those local defaults.
|
|
61
|
+
|
|
62
|
+
Then add the backup accessory to `config/deploy.yml`:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
38
65
|
accessories:
|
|
39
66
|
backup:
|
|
40
67
|
image: ghcr.io/crmne/kamal-backup:latest
|
|
@@ -64,34 +91,49 @@ bin/kamal accessory boot backup
|
|
|
64
91
|
bin/kamal accessory logs backup
|
|
65
92
|
```
|
|
66
93
|
|
|
67
|
-
Run
|
|
94
|
+
Run the first backup from your app checkout with the local gem and Kamal-style destination selection:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
bundle exec kamal-backup -d production backup
|
|
98
|
+
bundle exec kamal-backup -d production list
|
|
99
|
+
bundle exec kamal-backup -d production evidence
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
If you keep multiple deploy configs, pass `-c` the same way Kamal does:
|
|
68
103
|
|
|
69
104
|
```sh
|
|
70
|
-
|
|
71
|
-
bin/kamal backup-list
|
|
72
|
-
bin/kamal backup-check
|
|
73
|
-
bin/kamal backup-evidence
|
|
74
|
-
bin/kamal backup-logs
|
|
105
|
+
bundle exec kamal-backup -c config/deploy.staging.yml -d staging backup
|
|
75
106
|
```
|
|
76
107
|
|
|
77
|
-
|
|
108
|
+
Examples live in:
|
|
78
109
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
110
|
+
- [examples/kamal-accessory.yml](examples/kamal-accessory.yml)
|
|
111
|
+
- [examples/kamal-backup.yml.example](examples/kamal-backup.yml.example)
|
|
112
|
+
- [examples/kamal-backup.local.yml.example](examples/kamal-backup.local.yml.example)
|
|
113
|
+
|
|
114
|
+
## What Restic Does Here
|
|
115
|
+
|
|
116
|
+
`kamal-backup` uses restic as the backup engine and repository format.
|
|
117
|
+
|
|
118
|
+
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:
|
|
119
|
+
|
|
120
|
+
- S3-compatible object storage
|
|
121
|
+
- a restic REST server
|
|
122
|
+
- a filesystem path for local development
|
|
123
|
+
|
|
124
|
+
If you choose a `rest:` repository, `kamal-backup` does not install or operate that server for you. It is a separate service.
|
|
86
125
|
|
|
87
126
|
## Commands
|
|
88
127
|
|
|
89
|
-
|
|
128
|
+
The operator-facing command surface is:
|
|
90
129
|
|
|
91
130
|
```sh
|
|
131
|
+
kamal-backup init
|
|
92
132
|
kamal-backup backup
|
|
93
|
-
kamal-backup restore
|
|
94
|
-
kamal-backup restore
|
|
133
|
+
kamal-backup restore local [snapshot-or-latest]
|
|
134
|
+
kamal-backup restore production [snapshot-or-latest]
|
|
135
|
+
kamal-backup drill local [snapshot-or-latest]
|
|
136
|
+
kamal-backup drill production [snapshot-or-latest]
|
|
95
137
|
kamal-backup list
|
|
96
138
|
kamal-backup check
|
|
97
139
|
kamal-backup evidence
|
|
@@ -99,259 +141,162 @@ kamal-backup schedule
|
|
|
99
141
|
kamal-backup version
|
|
100
142
|
```
|
|
101
143
|
|
|
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. |
|
|
144
|
+
Production-side commands shell out through Kamal when you pass `-d` or `-c`. Local commands run on your machine.
|
|
112
145
|
|
|
113
|
-
|
|
146
|
+
Common examples:
|
|
114
147
|
|
|
115
148
|
```sh
|
|
116
|
-
kamal-backup
|
|
149
|
+
bundle exec kamal-backup -d production backup
|
|
150
|
+
bundle exec kamal-backup -d production check
|
|
151
|
+
bundle exec kamal-backup -d production evidence
|
|
152
|
+
bundle exec kamal-backup -d production restore production latest
|
|
153
|
+
bundle exec kamal-backup -d production drill production latest --database app_restore_20260423 --files /restore/files
|
|
154
|
+
bundle exec kamal-backup -d production version
|
|
155
|
+
bundle exec kamal-backup restore local latest
|
|
156
|
+
bundle exec kamal-backup drill local latest --check "bin/rails runner 'puts User.count'"
|
|
117
157
|
```
|
|
118
158
|
|
|
119
|
-
|
|
159
|
+
Use `kamal-backup help`, `kamal-backup help restore`, or `kamal-backup help drill` for task-specific usage.
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
## How a Backup Run Works
|
|
122
162
|
|
|
123
|
-
|
|
124
|
-
APP_NAME=chatwithwork
|
|
125
|
-
DATABASE_ADAPTER=postgres
|
|
126
|
-
RESTIC_REPOSITORY=s3:https://s3.example.com/chatwithwork-backups
|
|
127
|
-
RESTIC_PASSWORD=change-me
|
|
128
|
-
BACKUP_PATHS=/data/storage
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
`BACKUP_PATHS` accepts colon-separated or newline-separated paths. Every path must exist. Suspicious broad paths such as `/`, `/var`, `/etc`, and `/root` are refused unless `KAMAL_BACKUP_ALLOW_SUSPICIOUS_PATHS=true`.
|
|
163
|
+
When `kamal-backup backup` runs, it does five things:
|
|
132
164
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
PGPASSWORD=change-me
|
|
139
|
-
```
|
|
165
|
+
1. Validates the app name, restic repository, database settings, and `BACKUP_PATHS`.
|
|
166
|
+
2. Creates a database backup with the database-native export tool.
|
|
167
|
+
3. Streams that database backup into restic with tags such as `type:database`, `adapter:<adapter>`, and `run:<timestamp>`.
|
|
168
|
+
4. Runs one `restic backup` for all configured `BACKUP_PATHS`, tagged as `type:files` with the same `run:<timestamp>`.
|
|
169
|
+
5. Optionally runs `restic forget --prune` and `restic check`.
|
|
140
170
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
```sh
|
|
144
|
-
DATABASE_ADAPTER=mysql
|
|
145
|
-
DATABASE_URL=mysql2://app@app-mysql:3306/app_production
|
|
146
|
-
MYSQL_PWD=change-me
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
SQLite:
|
|
150
|
-
|
|
151
|
-
```sh
|
|
152
|
-
DATABASE_ADAPTER=sqlite
|
|
153
|
-
SQLITE_DATABASE_PATH=/data/db/production.sqlite3
|
|
154
|
-
```
|
|
171
|
+
That shared `run:<timestamp>` tag lets you match the database backup and file backup from the same run.
|
|
155
172
|
|
|
156
|
-
|
|
173
|
+
## Restore
|
|
157
174
|
|
|
158
|
-
|
|
159
|
-
RESTIC_KEEP_LAST=7
|
|
160
|
-
RESTIC_KEEP_DAILY=7
|
|
161
|
-
RESTIC_KEEP_WEEKLY=4
|
|
162
|
-
RESTIC_KEEP_MONTHLY=6
|
|
163
|
-
RESTIC_KEEP_YEARLY=2
|
|
164
|
-
RESTIC_FORGET_AFTER_BACKUP=true
|
|
165
|
-
```
|
|
175
|
+
`restore` means "put data back."
|
|
166
176
|
|
|
167
|
-
|
|
177
|
+
`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:
|
|
168
178
|
|
|
169
|
-
|
|
179
|
+
- `APP_NAME`
|
|
180
|
+
- `DATABASE_ADAPTER`
|
|
181
|
+
- `RESTIC_REPOSITORY`
|
|
182
|
+
- `LOCAL_RESTORE_SOURCE_PATHS` from the accessory `BACKUP_PATHS`
|
|
170
183
|
|
|
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
|
-
```
|
|
184
|
+
For a normal Rails app, the local targets come from Rails conventions:
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
- the development database in `config/database.yml`
|
|
187
|
+
- `storage` as the local files target
|
|
188
|
+
- `tmp/kamal-backup` as the local drill state directory
|
|
179
189
|
|
|
180
|
-
|
|
181
|
-
AWS_ACCESS_KEY_ID=...
|
|
182
|
-
AWS_SECRET_ACCESS_KEY=...
|
|
183
|
-
AWS_DEFAULT_REGION=...
|
|
184
|
-
```
|
|
190
|
+
You still provide the local secrets yourself in env:
|
|
185
191
|
|
|
186
|
-
|
|
192
|
+
- `RESTIC_PASSWORD`
|
|
193
|
+
- `POSTGRES_PASSWORD` or `MYSQL_PWD` when needed
|
|
194
|
+
- `RESTIC_REPOSITORY` when it is not visible through `kamal config`
|
|
187
195
|
|
|
188
|
-
|
|
196
|
+
Example:
|
|
189
197
|
|
|
190
198
|
```sh
|
|
191
|
-
|
|
199
|
+
bundle exec kamal-backup -d production restore local latest
|
|
192
200
|
```
|
|
193
201
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
PostgreSQL restore:
|
|
202
|
+
`restore production` is the emergency path back into the live production database and live production file paths:
|
|
197
203
|
|
|
198
204
|
```sh
|
|
199
|
-
|
|
200
|
-
--env KAMAL_BACKUP_ALLOW_RESTORE=true \
|
|
201
|
-
--env RESTORE_DATABASE_URL=postgres://app@app-db:5432/app_restore \
|
|
202
|
-
"kamal-backup restore-db latest"
|
|
205
|
+
bundle exec kamal-backup -d production restore production latest
|
|
203
206
|
```
|
|
204
207
|
|
|
205
|
-
|
|
208
|
+
It prompts locally, then shells out through Kamal to the backup accessory.
|
|
206
209
|
|
|
207
|
-
|
|
208
|
-
bin/kamal accessory exec backup \
|
|
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"
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
SQLite restore:
|
|
210
|
+
## Restore Drills
|
|
215
211
|
|
|
216
|
-
|
|
217
|
-
bin/kamal accessory exec backup \
|
|
218
|
-
--env KAMAL_BACKUP_ALLOW_RESTORE=true \
|
|
219
|
-
--env RESTORE_SQLITE_DATABASE_PATH=/restore/db/restore.sqlite3 \
|
|
220
|
-
"kamal-backup restore-db latest"
|
|
221
|
-
```
|
|
212
|
+
`drill` means "restore, check, and record the result."
|
|
222
213
|
|
|
223
|
-
|
|
214
|
+
`drill local` is often the fastest proof for a small app:
|
|
224
215
|
|
|
225
216
|
```sh
|
|
226
|
-
bin/
|
|
227
|
-
--env KAMAL_BACKUP_ALLOW_RESTORE=true \
|
|
228
|
-
"kamal-backup restore-files latest /restore/files"
|
|
217
|
+
bundle exec kamal-backup -d production drill local latest --check "bin/rails runner 'puts User.count'"
|
|
229
218
|
```
|
|
230
219
|
|
|
231
|
-
|
|
220
|
+
`drill production` restores into scratch targets on production infrastructure. It does not touch the live production database:
|
|
232
221
|
|
|
233
222
|
```sh
|
|
234
|
-
|
|
223
|
+
bundle exec kamal-backup -d production drill production latest \
|
|
224
|
+
--database app_restore_20260423 \
|
|
225
|
+
--files /restore/files \
|
|
226
|
+
--check "test -d /restore/files/data/storage"
|
|
235
227
|
```
|
|
236
228
|
|
|
237
|
-
|
|
229
|
+
Every drill writes `last_restore_drill.json` under `KAMAL_BACKUP_STATE_DIR`, and `kamal-backup evidence` includes that latest result.
|
|
238
230
|
|
|
239
|
-
|
|
240
|
-
KAMAL_BACKUP_ALLOW_IN_PLACE_FILE_RESTORE=true
|
|
241
|
-
```
|
|
231
|
+
## Evidence for CASA and Similar Reviews
|
|
242
232
|
|
|
243
|
-
|
|
233
|
+
`evidence` is the JSON summary you can attach to an ops record or security review.
|
|
244
234
|
|
|
245
|
-
|
|
235
|
+
It includes:
|
|
246
236
|
|
|
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
237
|
- latest database and file snapshots
|
|
255
|
-
-
|
|
256
|
-
-
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
Secrets, passwords, access keys, and database URL credentials are redacted.
|
|
238
|
+
- latest `restic check` result
|
|
239
|
+
- latest restore drill result
|
|
240
|
+
- retention settings
|
|
241
|
+
- tool versions
|
|
260
242
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
```sh
|
|
264
|
-
bin/kamal accessory exec backup "kamal-backup evidence"
|
|
265
|
-
```
|
|
243
|
+
For many reviews, the useful sequence is:
|
|
266
244
|
|
|
267
|
-
|
|
245
|
+
1. scheduled backups
|
|
246
|
+
2. repository checks
|
|
247
|
+
3. a real restore drill
|
|
248
|
+
4. `kamal-backup evidence`
|
|
268
249
|
|
|
269
|
-
|
|
250
|
+
That reads much better to a reviewer than "the backup job is green."
|
|
270
251
|
|
|
271
|
-
|
|
272
|
-
bin/test
|
|
273
|
-
```
|
|
252
|
+
## Configuration Highlights
|
|
274
253
|
|
|
275
|
-
|
|
254
|
+
Core accessory environment:
|
|
276
255
|
|
|
277
256
|
```sh
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
Published docs are configured for `https://kamal-backup.dev`.
|
|
284
|
-
|
|
285
|
-
Build the image:
|
|
286
|
-
|
|
287
|
-
```sh
|
|
288
|
-
docker build -t kamal-backup .
|
|
257
|
+
APP_NAME=chatwithwork
|
|
258
|
+
DATABASE_ADAPTER=postgres
|
|
259
|
+
RESTIC_REPOSITORY=s3:https://s3.example.com/chatwithwork-backups
|
|
260
|
+
RESTIC_PASSWORD=change-me
|
|
261
|
+
BACKUP_PATHS=/data/storage
|
|
289
262
|
```
|
|
290
263
|
|
|
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:
|
|
264
|
+
PostgreSQL:
|
|
296
265
|
|
|
297
266
|
```sh
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
267
|
+
DATABASE_ADAPTER=postgres
|
|
268
|
+
DATABASE_URL=postgres://app@app-db:5432/app_production
|
|
269
|
+
PGPASSWORD=change-me
|
|
301
270
|
```
|
|
302
271
|
|
|
303
|
-
|
|
272
|
+
MySQL/MariaDB:
|
|
304
273
|
|
|
305
274
|
```sh
|
|
306
|
-
|
|
275
|
+
DATABASE_ADAPTER=mysql
|
|
276
|
+
DATABASE_URL=mysql2://app@app-mysql:3306/app_production
|
|
277
|
+
MYSQL_PWD=change-me
|
|
307
278
|
```
|
|
308
279
|
|
|
309
|
-
|
|
280
|
+
SQLite:
|
|
310
281
|
|
|
311
282
|
```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
|
|
283
|
+
DATABASE_ADAPTER=sqlite
|
|
284
|
+
SQLITE_DATABASE_PATH=/data/db/production.sqlite3
|
|
323
285
|
```
|
|
324
286
|
|
|
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
|
|
287
|
+
Optional local config files:
|
|
340
288
|
|
|
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.
|
|
289
|
+
- `config/kamal-backup.yml`
|
|
290
|
+
- `config/kamal-backup.local.yml`
|
|
347
291
|
|
|
348
|
-
|
|
292
|
+
`config/kamal-backup.local.yml` is only for nonstandard local targets. Keep secrets such as `RESTIC_PASSWORD`, cloud credentials, and local DB passwords in environment variables, not in YAML files.
|
|
349
293
|
|
|
350
|
-
|
|
351
|
-
- Not a replacement for database point-in-time recovery.
|
|
352
|
-
- Not a physical replication tool.
|
|
353
|
-
- Not a secret manager.
|
|
294
|
+
## Docs
|
|
354
295
|
|
|
355
|
-
|
|
296
|
+
Full docs live in [`docs/`](docs/):
|
|
356
297
|
|
|
357
|
-
|
|
298
|
+
- [`docs/_guide/getting-started.md`](docs/_guide/getting-started.md)
|
|
299
|
+
- [`docs/_guide/configuration.md`](docs/_guide/configuration.md)
|
|
300
|
+
- [`docs/_guide/restore.md`](docs/_guide/restore.md)
|
|
301
|
+
- [`docs/_guide/restore-drills.md`](docs/_guide/restore-drills.md)
|
|
302
|
+
- [`docs/_reference/commands.md`](docs/_reference/commands.md)
|