# Volumes & volume backups
URL: https://synquic.tech/docs/guides/volumes-backups.md

Create named Docker volumes that keep data across every deploy, move, detach and delete them safely, and back up, schedule, restore and download each volume on its own.

import { Step, Steps } from 'fumadocs-ui/components/steps';

A **volume** is a named Docker volume on your project's server. Anything your app or service writes under the
volume's **mount path** is kept when the container is replaced, and each volume can be backed up and restored
on its own. The **Volumes** manager lists them with their size, who uses them and their backups, for single
apps and for every service of a compose or monorepo project alike.

<Callout title="What you need first">
- A project deployed with Docker to one of your own servers.
- For backups, a destination (S3-compatible storage, SFTP, FTP, Dropbox, Google Drive, an existing server or
  a local folder). See [Backup destinations](/docs/dashboard/backups) to add one.
</Callout>

## Where volumes are

Open the project and choose **Storage** in the project menu. The **Volumes** card is at the top. Press
**Refresh** to re-read sizes and status from the server.

Each row shows:

- the volume's **status**: **Attached**, **Created on next deploy** (declared, not created on the server yet)
  or **Detached**;
- where it is mounted, and by which service (or **App** for a single app), with **read-only** when it is;
- the containers that use it (**Used by ...**), its **Size** on disk and when it was **Created**;
- its backup line: the schedule (or **Manual backups**), the last backup's time and size, or **Not backed up
  yet**.

If the server can't be reached, the list still shows the declared volumes, with sizes and live status
unknown.

## Why the data survives

For new apps and services, a volume's Docker name is `synq-<project-slug>-<volume-name>`. Services that
existed before Synq scoped volume names by project, services cloned from another project, and services
brought in by a migration from another server or tool keep their original volume names instead. Either way,
nothing about a deployment, a container or an image is part of the name, so every way a container is replaced
mounts the same volume again:

- a redeploy or an image change,
- a rollback to an older release,
- a zero-downtime swap (the new container mounts the volume before the old one stops),
- a restart that recreates the container, or a scale-out.

Renaming a project doesn't change its slug, so it doesn't orphan its volumes. Data is only removed when you
delete a volume yourself, or when you ask for it while deleting the project (see below).

## Create a volume

<Steps>

<Step>

### Press Create volume

Fill in:

- **Name**: letters, numbers, dots, dashes and underscores, for example `uploads`. Synq adds the project
  prefix on the server.
- **Mount path**: the absolute path inside the container, for example `/data` or `/var/lib/postgresql/data`.
- **Mounted by**: for a project with several services, the service that mounts it.

Press **Create**.

</Step>

<Step>

### Redeploy

Synq creates the volume on the server right away, labelled with the project (`synq.project`, `synq.volume`,
`synq.managed`), so it can be backed up immediately. The toast adds **Redeploy to apply it to running
containers.** Running containers pick up the new mount on the next deploy.

</Step>

</Steps>

<Callout title="Mount path over existing files" type="info">
A new, empty volume mounted over a folder the image already fills starts with the image's files copied in
(Docker does this for named volumes). After that the volume's content wins, and later image versions don't
refresh it. Don't mount a volume over a folder that holds code.
</Callout>

## Edit, detach, attach and delete

- **Edit path** mounts the same volume at a new path. The name, and so the data, stays the same. It applies
  on the next deploy.
- **Detach** stops mounting the volume (**Detach name?**). The volume and its data stay on the server;
  running containers keep using it until the next deploy. It is then listed as **Detached**.
- **Attach** mounts a detached volume again, at the path and service you choose.
- **Delete** appears once nothing mounts the volume. The dialog **Delete volume** asks you to type the volume's
  name, then **Delete volume and data** removes it and everything in it from the server. Synq refuses while any
  container (running or stopped) still references it: detach, redeploy, then delete. The volume's backups
  are kept and its schedule is paused. Deleting needs admin permission on the project.

### Deleting the project keeps volumes by default

When you delete a whole project (**Advanced** → **Danger Zone** → **Delete Project**), the dialog scans its services and
volumes and shows **Also wipe service data (N volumes)**, **off** by default: containers are removed, but
their named volumes stay on disk, so you can attach them again later by name. Tick it only if you want the
data gone too. **Remove from Synq only** leaves everything on the server, app included.

## Service volumes

A service's own mount list is on its **Volumes** tab (**Apps & Services** → the service → **Volumes**).
Press **Edit volumes**, then **Add volume** for each entry:

- **On the host**: a saved volume name, a folder on the server (a **Host directory**), or blank for storage
  Synq manages automatically.
- **Inside the service**: the path the service reads and writes.

Press **Save volumes**. Volume changes apply on the next deployment. The tab shows each mount's kind (**Named
volume**, **Host directory**, **Anonymous volume**) and its usage; **Refresh usage** measures again.

## Back up a volume

<Steps>

<Step>

### Press Schedule backups on the volume

The dialog **Back up name** opens. Choose:

- **Destination**: where the backups go. With none yet, it says **Add a backup destination first.** and links
  to **Manage destinations**.
- **Schedule**: **Manual only**, **Every hour**, **Daily at 03:00**, **Sundays at 03:00**, **Monthly, on the
  1st**, or **Custom** with a five-field **Cron expression** (minute, hour, day of month, month, day of week),
  for example `30 2 * * *` for 02:30 every day.
- Retention: **Keep the last** N backups, **Keep for (days)**, or both. Leave a field empty for no limit of
  that kind.
- **Schedule enabled**: untick to pause the schedule without losing it.

</Step>

<Step>

### Save

Press **Save**, or **Save and back up now** to take the first backup straight away.

</Step>

</Steps>

**Back up now** on the row runs a backup at once. On a volume with no schedule yet, it opens the same
dialog first. **Edit schedule** reopens it, and **Remove schedule** deletes the schedule while keeping every
existing backup.

A volume schedule is an ordinary backup policy that backs up exactly that one volume, so it shows up
everywhere backups do: the project's **Backup** tab (**Volume backups**), the **Backups** page's volume list,
and each destination's **Used by** list. It runs alongside any database or service policy you already have.

<Callout title="Crash-consistent copies" type="warn">
Volume backups are taken while the service keeps running. For a database, prefer a database dump (see
[Backups & restore](/docs/guides/backups-restore)), or schedule the volume backup for a quiet time.
</Callout>

## Restore or download a snapshot

<Steps>

<Step>

### Press Restore on the volume

The dialog **Restore name** lists the volume's successful backups (**No successful backups of this volume
yet.** when there are none).

</Step>

<Step>

### Choose a snapshot and press Restore

The regular restore wizard opens: Synq verifies the archive (**Prepare**), asks you to type the volume's
name (**Confirm**), stops the container that uses the volume, replaces the volume's contents with the
snapshot, and starts the container again (**Apply**).

</Step>

</Steps>

<Callout type="warn" title="A restore replaces the volume">
Everything currently in the volume is replaced by the snapshot. Take a fresh backup first if you might need
today's data.
</Callout>

For an S3-compatible destination, **Download** creates short-lived links to the snapshot's archive files
(`volume-<name>.tar.zst`), so you can inspect or move the data outside Synq. Other destination kinds say
**Snapshots can be downloaded from S3-compatible destinations.**

## From the API

```bash
# List volumes with size, users and backup status
curl -H "Authorization: Bearer $SYNQ_TOKEN" \
  "$SYNQ_URL/api/projects/$PROJECT_ID/volumes"

# Create a volume mounted at /data
curl -X POST -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"data","mountPath":"/data"}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID/volumes"

# Schedule nightly backups of it, keeping the last 7
curl -X POST -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"volumeName":"data","destinationId":"'$DESTINATION_ID'","cronExpression":"0 3 * * *","retainCount":7}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID/backup-policies"

# Download links for one successful backup run (S3-compatible destinations)
curl -X POST -H "Authorization: Bearer $SYNQ_TOKEN" \
  "$SYNQ_URL/api/backup-runs/$RUN_ID/download"
```

`SYNQ_URL` is your panel address (for example `https://app.example.com`). `PATCH` on the same volumes path
changes a mount path, `POST .../volumes/detach` detaches, and `DELETE .../volumes` with
`{"name":"data","confirm":"data"}` deletes a detached volume.

## Related guides

<Cards>
  <Card title="Persistent storage" href="/docs/guides/persistent-storage" description="Framework defaults for kept paths, and S3 object storage for uploads." />
  <Card title="Backups & restore" href="/docs/guides/backups-restore" description="Database dumps, service policies and the restore wizard." />
  <Card title="Backup destinations" href="/docs/dashboard/backups" description="Add the S3 bucket, SFTP or FTP host, Dropbox, Google Drive or folder your backups go to." />
</Cards>
