Here we cover how to upload your custom disk and save it as an image. This stores it for you so you can use it to create a new Linodes.
This is intended for advanced system administrators. In most cases, you might be better suited capturing an image directly from an existing Linode, or through our Packer Builder tool. Both of these methods ensure maximum compatibility with our services, and are easier to follow.
Additionally, you can create a new image and upload image data using a single process through Cloud Manager or the Linode CLI.
Before you begin
First, you need to prepare the disk you want to use for your image:
- Your disk needs to meet several requirements.
- You need to set up the file you want to use for your image.
- You need to compress your finalized image file.
- You need to determine your image file's decompressed size.
Get region details
Next, you need to identify the specific data center (region) where you want to upload your image.
Only core compute regions that support our Object Storage service can be used to store an uploaded image. You can't upload an image to a distributed compute region.
-
Run the List regions operation.
-
Review the
label
values to select your desired region. Store itsid
as yourregionId
.{ "data": [ { "capabilities": [ "Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Placement Groups", "Block Storage Encryption", "Linode Interfaces" ], "country": "us", "id": "us-mia", <== Store to upload image to the Miami data center. "label": "Miami, FL, USA", ... }, { "capabilities": [ ... ], "page": 1, "pages": 1, "results": 1 }
Create an image container
This creates a container to house your uploaded image.
-
Run the Upload an image operation. Include the following values in the request:Store the
id
value that's generated for it.-
region
. This is theregionId
you stored, for the target region for the upload. -
label
. Optionally give your upload image an easily recognizable name. If this is left out, the name of the image will default to<compute_instance_label>-<disk_name>
. -
tags
. For organizational purposes, you can optionally enter one or more tags to group similar objects under these specific values. Once you set one, you can set it again with other images. -
description
. Optionally add some text to describe your uploaded image. -
cloud_init
. Set totrue
if you want the image to support cloud-init. Many Linode-supported distributions are compatible with it by default, or you may have installed cloud-init on the disk, yourself. Our Metadata service is designed to be consumed by cloud-init.
{ "region": "us-mia", "label": "Golden Image 1", "tags": [ "gold", "primary" ], "description": "Uploaded primary golden image for Ubuntu Linux", "cloud_init": "true" }
-
-
From the response, store the
upload_to
value as yourUPLOAD_URL
.{ { "image": { "capabilities": [ "cloud-init", "distributed-sites" ], "created": "2021-08-14T22:44:02", "created_by": "John Q. Linode", "deprecated": false, "description": "Uploaded primary golden image for Ubuntu Linux.", "eol": "2026-07-01T04:00:00", "expiry": null, "id": "linode/debian11", "is_public": true, "label": "Golden Image 1", "regions": [ { "region": "us-mia", "status": "available" } ], "size": 2500, "status": "creating", "tags": [ "gold", "primary" ], "total_size": 1234567, "type": "manual", "updated": "2021-08-14T22:44:02", "vendor": "Debian" }, "upload_to": "<URL for upload>" <== Store. }
You should also store the
id
as yourimageId
, to interact with it other API operations.
Upload the image file
You need to upload image data within 24 hours of creation or the API cancels the upload and deletes the image container.
When you upload a new image, we automatically encrypt it for its protection, even if you've already encrypted it. Your images remain encrypted when in storage, in caching, and in transit. When you deploy an image, we'll automatically decrypt the encryption we've applied. If you've also encrypted the image, you'll need to manually decrypt it.
Finally, you need to generate a separate PUT request to upload your image to your container. The request needs to include the following:
-
The
Content-type: application/octet-stream
header -
upload-file
. This is the complete path to a compatible image file, for example on your local system -
$UPLOAD_URL
. This requires that you stored theupload_to
value from the previous phase of the process.
Here's a rough example, using cURL
:
curl --request PUT \
-H "Content-Type: application/octet-stream" \
--upload-file example.img.gz \
$UPLOAD_URL \
--progress-bar \
--output /dev/null
Check the status
The upload can take some time to complete. You can check on it by running the Get an image, using the imageId
you stored after creating it.
When the status
is available
, the image is ready for use.
Deploy your image
When you're ready to add your image as a disk to a Linode, you can follow this workflow.