# Add persistent storage to your server

Source: https://docs.quake.ai/docs/quickstart/create-block-volume
Markdown: https://docs.quake.ai/docs/quickstart/create-block-volume.md

---

# Add persistent storage to your server

In this tutorial, you create a block storage volume, attach it to a running virtual machine, format and mount it, and configure the server to remount it automatically after a reboot. By the end, you will have a persistent data disk that survives instance restarts and can be detached and reattached independently of the VM.

**What you will learn:**

- How block storage volumes differ from the ephemeral root disk
- How to create, attach, and verify a volume from the console
- How to format and mount a volume inside a Linux server
- How to use `/etc/fstab` with `nofail` to configure automatic mounting safely

**Time estimate:** 20 to 30 minutes

## Prerequisites

You need:

- A running Quake AI virtual machine with SSH access: complete [Launch your first server](/docs/quickstart/launch-your-first-server) if you do not have one yet
- Terminal access to your local machine (SSH client)
- A Quake AI account with an active project



This tutorial creates and attaches the data volume from the console. If you provisioned the prerequisite server with the OpenStack CLI or API instead, two platform behaviors apply.

Quake AI flavors have no local disk (`disk=0`): every server boots from a Cinder volume the platform attaches at create time. The console handles this for you. From the CLI, pass `--boot-from-volume ROOT_DISK_GB` to `openstack server create`, or set `block_device_mapping_v2` in your Heat or OpenTofu definitions. Omitting it returns `ForbiddenException: 403 ... Only volume-backed servers are allowed for flavors with zero disk`.

That root volume is not deleted when you delete the server, so it persists and counts against your project's Cinder quota. Delete the leftover volume with `openstack volume delete VOLUME_ID` after deleting the server, or create the server so the root volume is removed automatically. See [Create instances from the CLI](/reference/compute/instances-cli) for the exact flags.



## Why block storage

Your virtual machine's root disk is tied to the instance lifecycle. When the instance is deleted, the root disk is deleted with it. Block storage volumes are independent of the instance: you can detach them, reattach them to a different instance, and snapshot them for backup at any time.

This makes volumes the right storage primitive for databases, application data, and anything else that needs to outlive the instance it runs on.

## Step 1: Create a volume

1. In the Quake AI console, go to **Storage** > **Volumes** > **Create Volume**.
2. Set the **Data Source** to **None** (you are creating a blank volume).
3. Set the volume type to **Flash_Premium**, the only volume type available in your region (the console auto-selects it).
4. Set the capacity to **50 GiB**. You can resize volumes later, but you cannot shrink them, so starting with a reasonable size for your use case is important.
5. Set a name, for example `tutorial-data`.
6. Leave the count at `1` and select **OK**.

The volume appears in the list with status **Creating**, then transitions to **Available** within a few seconds. **Available** means the volume exists but is not yet attached to any instance.

## Step 2: Attach the volume to your server

A volume must be attached to an instance before the operating system inside the instance can see it.

1. Go to **Compute** > **Instances** and select your running instance.
2. Select **More** > **Attach Volume**.
3. Select `tutorial-data` from the volume list and select **OK**.

The attachment completes immediately. From the hypervisor's perspective, a new virtual block device has been added to the instance. The operating system inside the instance has not yet done anything with it; that happens in the next steps.

## Step 3: Locate the new device

SSH into your instance and list the block devices:

```bash
lsblk
```

Expected output:

```text
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda       8:0    0   20G  0 disk
├─sda1    8:1    0   19G  0 part /
├─sda14   8:14   0    4M  0 part
├─sda15   8:15   0  106M  0 part /boot/efi
└─sda16 259:0    0  913M  0 part /boot
sdb       8:16   0   50G  0 disk
```

`sdb` is the newly attached volume. It has no partitions and no filesystem yet; that is what the next two steps address.



Quake AI attaches volumes over virtio-scsi, so disks appear as SCSI devices: the root disk is `sda` and attached volumes appear as `sdb`, `sdc`, and so on, not `vdb`. If your instance lists different names, identify the new volume by the size you created (50 GiB here).



## Step 4: Format the volume

Before you can store files on the volume, you need a filesystem. Use `ext4`, a reliable general-purpose Linux filesystem.

```bash
sudo mkfs.ext4 /dev/sdb
```

This writes filesystem metadata across the entire volume and takes a few seconds. You only need to format a volume once. Formatting an already-used volume erases all data on it, so do not run this command on a volume that already contains data you need.

Expected output ends with a line similar to:

```text
Writing superblocks and filesystem accounting information: done
```

## Step 5: Mount the volume

Create a mount point and mount the volume:

```bash
sudo mkdir -p /mnt/data
sudo mount /dev/sdb /mnt/data
```

Verify the mount:

```bash
df -h /mnt/data
```

Expected output:

```text
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb         49G   24K   47G   1% /mnt/data
```

The volume is now accessible at `/mnt/data`. Any files written there are stored on the volume, not on the root disk.

## Step 6: Write data and verify persistence

Write a test file, unmount the volume, remount it, and confirm the file survived:

```bash
echo "volume persistence test" | sudo tee /mnt/data/test.txt
cat /mnt/data/test.txt
```

Now unmount and remount:

```bash
sudo umount /mnt/data
sudo mount /dev/sdb /mnt/data
cat /mnt/data/test.txt
```

The file is still there. The data lives on the volume, independent of whether it is mounted.

## Step 7: Configure automatic mounting

The current mount does not survive a reboot. Each time the instance restarts, you would need to mount the volume again manually. Fix this by adding an entry to `/etc/fstab`, the file that defines which filesystems should be mounted at boot.

Use the volume's UUID rather than its device name (`/dev/sdb`). Device names can change across reboots; UUIDs are stable.

Find the UUID:

```bash
sudo blkid /dev/sdb
```

Output:

```text
/dev/sdb: UUID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" TYPE="ext4"
```

Copy the UUID value, then open `/etc/fstab` in a text editor:

```bash
sudo nano /etc/fstab
```

Add this line at the end of the file, replacing `VOLUME_UUID` with the UUID from `blkid`:

```text
UUID=VOLUME_UUID  /mnt/data  ext4  defaults,nofail  0  2
```

Save the file and test it:

```bash
sudo mount -a
```

If no errors appear, the configuration is valid.



The `nofail` option tells the boot process to continue even if this volume fails to mount. Without it, if the volume is ever unavailable at boot (for example, while detached), the server will enter an emergency shell instead of booting normally. This is recoverable but disruptive. Always include `nofail` for non-root volumes.



To confirm automatic mounting works from creation to mount, reboot the instance:

```bash
sudo reboot
```

After reconnecting via SSH, verify the volume is mounted:

```bash
df -h /mnt/data
cat /mnt/data/test.txt
```

Both commands should return expected output without any manual mount step.

## What you learned

In this tutorial, you:

- **Created a block storage volume** independent of any instance, sized and named for your use
- **Attached the volume** to a running instance and confirmed the device appeared at the OS level
- **Formatted the volume** with ext4 and mounted it at a stable path
- **Verified data persistence** by writing, unmounting, and remounting
- **Configured automatic mounting** via `/etc/fstab` with the `nofail` safety option

Volumes have their own lifecycle. You can detach `tutorial-data` from this instance and attach it to a different one, or create a snapshot of it for point-in-time backup. Neither operation requires the filesystem to be reformatted.

## Next steps

- [Create a volume snapshot](/docs/block/how-to/create-snapshot): back up the volume before making changes
- [Extend a volume](/docs/block/how-to/extend-volume): increase capacity without reformatting
- [Store and retrieve files with S3-compatible object storage](/docs/quickstart/object-storage-upload): the next tutorial in this series
- [Block storage concepts](/docs/block/concepts/volumes): deeper background on volume types, snapshots, and lifecycle

## Clean up

To remove the resources you created:

1. Unmount the volume inside the instance:

```bash
sudo umount /mnt/data
```

2. Remove the `/etc/fstab` entry to avoid boot issues after detachment.

3. In the console, go to **Compute** > **Instances**, select your instance, and select **More** > **Detach Volume**. Select `tutorial-data` and confirm.

4. Go to **Storage** > **Volumes**, select `tutorial-data`, and select **Delete Volume**. Confirm the deletion.

The volume and its data are permanently deleted.
