Upload an image

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:

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.

  1. Run the List regions operation.

  2. Review the label values to select your desired region. Store its id as your regionId.

    {
      "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.

  1. 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 the regionId 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 to true 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"
    }
    
  2. From the response, store the upload_to value as your UPLOAD_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 your imageId, 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 the upload_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.