Software Developer, Technology Enthusiast, Retro and Husband and Dad based in Melbourne.

AWS Lightsail Docker Volume

Summary

This guide shows you how to attach an AWS Lightsail block storage disk to an Ubuntu instance, format and mount it at /data, and configure Docker so its named volumes live on that disk. This keeps your WordPress and database data on the larger block storage volume and ensures it persists across reboots (and can survive instance rebuilds if you reattach the disk).

1. Confirm your Region and Availability Zone

Before you create the disk, you need the instance’s Availability Zone (AZ). The AWS Lightsail create-disk command won’t work unless you provide –availability-zone.

  • lightsail-instance-config.json: Get the Availability Zone from the lightsail-instance-config.json file created in Lightsail Instance for Docker
  • AWS CLI (pull the AZ directly from Lightsail):
aws lightsail get-instances --query "instances[?name=='MyUbuntuInstance'].location.availabilityZone | [0]" --output text --profile MyUbuntuProfile

Options explained

  • aws lightsail get-instances This command tells the AWS CLI to return details for all instances in the account/region tied to the selected profile.
  • --query "instances[?name=='MyUbuntuInstance'].location.availabilityZone | [0]" AWS CLI User Guide – Filtering output with –query.
  • --output text Prints the result as plain text.
  • --profile MyUbuntuProfile Selects which AWS CLI profile to use. This is helpful if you have multiple accounts or credentials configured.

2. Create the Lightsail disk

Create a new Lightsail block storage disk using the aws lightsail aws lightsail create-disk command, and provisioning in the same Availability Zone as your existing instance.

aws lightsail create-disk --disk-name MyUbuntuProfile-Docker-Volume-1 --region ap-southeast-2a --size-in-gb 32 --profile MyUbuntuProfile

Options explained

  • aws lightsail create-disk This command tells the AWS CLI to create a new block storage disk.
  • --disk-name MyUbuntuProfile-Docker-Volume-1 Choose a unique and descriptive name for the disk in your Lightsail account.
  • --region ap-southeast-2a Despite the flag name, Lightsail expects the AZ for block storage here (e.g., ap-southeast-2a).
  • --size-in-gb 32 Disk size. You choose based on WordPress + DB growth, uploads, backups, etc.
  • --profile MyUbuntuProfile Selects which AWS CLI profile to use. This is helpful if you have multiple accounts or credentials configured.

3. Attach the disk to your instance

Now that the disk is created MyUbuntuProfile-Docker-Volume-1, attach it to the instance MyUbuntuInstance so Ubuntu can detect it as a new drive.

aws lightsail attach-disk --disk-name MyUbuntuProfile-Docker-Volume-1 --disk-path /dev/xvdf --instance-name MyUbuntuInstance --profile MyUbuntuProfile

Options explained

  • aws lightsail attach-disk This command tells the AWS CLI to attach a block storage disk to an instance.
  • --disk-name MyUbuntuProfile-Docker-Volume-1 The name of the Lightsail disk you created earlier. This must match exactly.
  • --disk-path /dev/xvdf Device name Ubuntu will see for the newly attached disk in Ubuntu instance. This is the attachment path; in Ubuntu, it may appear as /dev/xvdf or sometimes /dev/nvme, depending on the virtualization.
  • --instance-name MyUbuntuInstance Instance name you’re attaching the disk to.
  • --profile MyUbuntuProfile Selects which AWS CLI profile to use. This is helpful if you have multiple accounts or credentials configured.

4. Verify attachment

Now let’s confirm the command returns a quick status summary for the Lightsail block storage disk.

aws lightsail get-disk --disk-name MyUbuntuProfile-Docker-Volume-1 --query 'disk.{name:name,state:state,attachedTo:attachedTo,path:path,isAttached:isAttached}' --output table --profile MyUbuntuProfile

Options explained

  • aws lightsail get-disk This command tells the AWS CLI to retrieve details about one block storage disk.
  • --disk-name MyUbuntuProfile-Docker-Volume-1 Which disk to look up in Lightsail disk resource.
  • --query 'disk.{name:name,state:state,attachedTo:attachedTo,path:path,isAttached:isAttached}' Using a JMESPath query extracting from the top-level disk object.
  • --output table Render the result as a human-readable ASCII table – Setting the output format in the AWS CLI
  • --profile MyUbuntuProfile Selects which AWS CLI profile to use. This is helpful if you have multiple accounts or credentials configured.

Output

-----------------------------------------------------------------
|                            GetDisk                            |
+------------+--------------------------------------------------+
|  attachedTo|  MyUbuntuProfile-Docker-Volume-1-docker-1        |
|  isAttached|  True                                            |
|  name      |  MyUbuntuProfile-Docker-Volume-1                 |
|  path      |  /dev/xvdf                                       |
|  state     |  in-use                                          |
+------------+--------------------------------------------------+

5. Connect to the Ubuntu instance via SSH

Next, connect to the Lightsail instance via SSH so we can format and mount the disk on the Ubuntu server.

ssh MyUbuntuInstance

6. Identify the new disk in the Ubuntu Instance

Next, we need to identify the disk that will be mounted on the system.

sudo lsblk

Options explained

  • sudo Run the command with administrator privileges.
  • lsblk Run the command to display all disks, partitions, and mount points currently available on the Ubuntu server.

Output

NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS

nvme1n1      259:5    0   32G  0 disk

7. Create a filesystem on the new disk (only if empty)

Next we need to format the disk /dev/nvme1n1 with the XFS filesystem.

sudo mkfs -t xfs /dev/nvme1n1

Options explained

  • sudo Run the Linux command with administrator privileges.
  • mkfs Is the Linux command make filesystem, create a new filesystem on the target disk.
  • -t xfs Create the disk using the XFS filesystem type.
  • /dev/nvme1n1 Disk device being formatted.

Output

meta-data=/dev/nvme1n1           isize=512    agcount=16, agsize=524288 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=1
         =                       reflink=1    bigtime=1 inobtcount=1 nrext64=0
data     =                       bsize=4096   blocks=8388608, imaxpct=25
         =                       sunit=1      swidth=1 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=16384, version=2
         =                       sectsz=512   sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

8. Create a mount point (folder) and mount the disk

First, create a folder that will be used as the disk’s mount location.

sudo mkdir -p /data

Next, mount the disk to that folder.

sudo mount /dev/nvme1n1 /data

Options explained

  • sudo Run the command with administrator privileges.
  • mount Is the Linux command used to attach a storage device to the filesystem.
  • /dev/nvme1n1 is the block device representing the disk that was identified.
  • /data This is the folder where the disk will be accessible and mounted.

Finally, confirm that the disk is mounted successfully using df utility command.

df -h | grep /data

Options explained

  • df Shows disk usage and mounted filesystems.
  • -h Displays sizes in GB, MB, etc.
  • grep /data Filters the output to show only the /data mount.

This mount is temporary and will disappear after a reboot. In the next step, the disk will be added to /etc/fstab so it automatically mounts when the server starts.

9. Persist the mount using /etc/fstab on reboot

Before modifying the filesystem table, it is recommended to create a backup of the file. If an error is introduced while editing /etc/fstab, the system may fail to mount disks correctly during startup.

sudo cp /etc/fstab /etc/fstab.orig

We need to use the UUID (Universally Unique Identifier) of the disk instead of the device name.
This is more reliable because device names like /dev/nvme1n1 can sometimes change after reboot.

sudo blkid /dev/nvme1n1 

Options explained

  • sudo Run the command with administrator privileges.
  • blkid Utility command that shows block device attributes, such as UUID , filesystem type and label.
  • /dev/nvme1n1 Block device representing the disk.

Output

/dev/nvme1n1: UUID="92a4a81e-d66f-420e-9f7a-234cbb5c681e" BLOCK_SIZE="512" TYPE="xfs"

Open the filesystem table configuration file, this file controls which disks are mounted automatically when the system boots.

sudo nano /etc/fstab

Add the following line to the bottom of the file, please tab.

UUID=92a4a81e-d66f-420e-9f7a-234cbb5c681e  /data  xfs   defaults,nofail  0  2

Options explained

  • UUID=92a4a81e-d66f-420e-9f7a-234cbb5c681e Unique identifier for the disk.
  • /data Folder where the disk will be mounted and made accessible.
  • xfs Filesystem type used when the disk was formatted.
  • defaults,nofail Standard mount options. nofail prevents boot errors if the disk is missing.
  • 0 Dump backup option, which is typically set to 0 to disable filesystem backups.
  • 2 Order for filesystem checks during boot.

10. Reboot test

Restart the server to confirm the disk mounted /data automatically.

sudo reboot

Next, reconnect to the Lightsail instance via SSH.

ssh MyUbuntuInstance

Finally, run the df command to confirm the disk is mounted successfully.

df -h | grep /data

Output

/dev/nvme1n1      32G  660M   32G   3% /data

11. Adding Docker Volume

We need to ensure Docker starts after /data is mounted. it is important that /data is available before Docker starts.

If Docker starts before /data is mounted during system boot, it may create empty directories under /data. This can cause containers to start with missing or incorrect data.

To prevent this issue, add a dependency so Docker waits until /data is mounted before starting.

Connect to the Lightsail instance via SSH.

ssh MyUbuntuInstance

Create a systemd override for Docker, this opens a small override file.

sudo systemctl edit docker

Add the dependency. This tells systemd that Docker must wait until the /data mount is available before starting.

[Unit]
RequiresMountsFor=/data

Reload systemd and restart Docker or reboot.

sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart docker

Or.

sudo reboot

12. Preparing Docker Volumes for WordPress for Lightsail

Create the folders under /data that will hold the persistent data for the WordPress files and MySQL database. Docker will later bind the named volumes to these locations.

Create the folders on /data that will hold the Docker volume data.

sudo mkdir -p /data/volumes/wp_html
sudo mkdir -p /data/volumes/mysql

Create named Docker volumes backed by those folders on /data.

docker -H ssh://MyUbuntuInstance volume create wp_html --driver local --opt type=none --opt device=/data/volumes/wp_html --opt o=bind
docker -H ssh://MyUbuntuInstance volume create mysql_data --driver local --opt type=none --opt device=/data/volumes/mysql --opt o=bind

Options explained

  • docker volume create creates a new Docker volume, wp_html and mysql_data are the names of the volumes.
  • --driver local tells Docker to use the local volume driver.
  • --opt type=none is used when creating a bind-backed volume.
  • --opt device=... points Docker to the folder on your machine.
  • --opt o=bind tells Docker to bind that folder into the volume.

Verify Volumes

Check that Docker is using your local folders.

docker -H ssh://MyUbuntuInstance volume inspect wp_html

Output

Docker will return JSON output describing each volume.

[
    {
        "CreatedAt": "2025-12-16T11:14:48Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/wp_html/_data",
        "Name": "wp_html",
        "Options": {
            "device": "/data/volumes/wp_html",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]
docker volume inspect mysql_data

Output

[
    {
        "CreatedAt": "2025-12-16T11:16:01Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mysql_data/_data",
        "Name": "mysql_data",
        "Options": {
            "device": "/data/volumes/mysql",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]

Further Reading

Using WordPress on AWS Lightsail and Docker

Leave a Reply