feat(databases): backup import — upload .tar.gz as a restore point

D5. POST /databases/:id/backups/import accepts a gzipped tar archive
(multipart `file` field or raw application/gzip body, 2 GiB ceiling),
stages it to a temp file, streams it into the backup volume via the
started holder container, and registers a completed backup row — a
first-class restore point that also ships offsite when a target is
assigned. External databases rejected.

Also fixes `containr databases restore` — it never sent database_id,
which the API requires, so every CLI restore failed validation.

CLI: databases import-backup <id> <file|-> (stdin support via new
client.DoRaw). UI: Import button in the backups row. OpenAPI + docs.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-10-08 23:07:27 +02:00
1 parent 109f79268f
commit 15045b8dd3
11 files changed
+409 -10

No files matched your search

+60
View File
@@ -2388,6 +2388,66 @@ paths:
schema:
$ref: '#/components/schemas/MessageResponse'
/databases/{id}/backups/import:
post:
tags:
- Databases
summary: Import a backup archive
description: >-
Upload a `.tar.gz` archive (multipart field `file` or a raw
application/gzip body) to create a new restore point. The archive
lands in the backup volume and, when a backup target is assigned,
is also shipped offsite. Managed databases only; 2 GiB ceiling.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
description: Database ID
schema:
type: string
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
application/gzip:
schema:
type: string
format: binary
responses:
'201':
description: Backup imported
content:
application/json:
schema:
type: object
properties:
backup_id:
type: string
size:
type: string
status:
type: string
'400':
description: Invalid archive
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'413':
description: Archive too large
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/databases/{id}/backups/{bid}/download:
get:
tags:
+3 -1
View File
@@ -47,7 +47,9 @@ deployments list|get|logs|rollback|cancel
logs <service-id> [--follow] runtime logs (SSE follow)
exec <service-id> -- <cmd> one-off container command
variables list|set|unset env vars (secrets masked; --redeploy applies them)
databases list|get|create|update|delete|action|backup|restore|download-backup
databases list|get|create|update|delete|action|backup|restore|download-backup|import-backup
import-backup <id> <file.tar.gz|-> uploads an archive as a restore
point; ships offsite too when a backup target is assigned
create --public exposes the port on all interfaces;
update <id> --public/--public=false toggles it (container recreates, data persists)
databases register <name> register an external database (--type --host --port --database --username --password --ssl; probed before storing)