How to Upload an Image to a Linode Storage Bucket in Node.js Backend
Published: 2023-06-21 01:55:54

When I face to upload the image to [Linode object storage](https://www.linode.com/), I tried with several way to upload images

**Prerequisites**
Before you begin, you should have:

A basic Node.js express application: I’m assuming you have a Node.js Express application already. If you don’t, follow the instructions from the official getting started guide to create one.

Node.js and npm installed: If you don't have them installed, you can download them by following these tutorials for Windows and Linux.

A code editor. I'm using VS Code.


**Setting Up Linode**
First things first, sign up for a Linode account following these instructions:

Go to the Linode website and click the "Sign Up" button in the top right corner of the homepage to sign up.

Follow the prompts to verify your account.

Choose your preferred payment method, either credit card or PayPal, and enter the relevant details. If you are a first-time user, you will be given a $100 credit (It’s been enough for me to experiment so far).

Agree to Linode's terms of service and privacy policy by clicking on the checkboxes.

Click on the "Create Account" button to complete the process.

Verify your email then log in to Linode.

**Creating a Linode Object Storage Bucket**
The object storage bucket is where you’ll store the images. You could store them in a database, but your database performance would end up being slow since media files take up a lot of space. Storing the images in a storage bucket and then saving the file metadata like its filenames and file paths in the database is better for performance.

Create a Linode storage bucket by following these steps:

Log in to the Linode Cloud Manager at [cloud.linode.com](http://cloud.linode.com/).

In the left-hand sidebar, click on "Object Storage" under the "Storage" section.

Click the "Create a Bucket" button in the top right corner.

Enter a name for your bucket and select the region where you want it to be stored.

Click the "Create Bucket" button to create your new storage bucket.

Navigate to your new bucket and on the Access tab, select “Public-read” from the access list dropdown to allow everyone including your application to read the objects in the bucket. This will be useful when you start serving the images on your site.

Once you’ve created the bucket, create an access key that you’ll use to interact with the bucket by clicking the “Create access key” button on your object storage dashboard.

On the modal that opens, copy the access key id and the secret access key and save them in a .env file in your application.

In the next section, we’ll create a form that accepts images from users.

**Making scripts in Backend**
In lib folder, you need to create file `lib/s3Client.ts`


1. Install the @aws-sdk/client-s3 libraries using npm by running the following command:

`npm install @aws-sdk/client-s3`
2. Create an S3 client object using your Linode credentials.

```
import  { S3Client } from "@aws-sdk/client-s3";

const s3Client = new S3Client({
  endpoint: 'your_bucket_cluster_url',
  region: 'your_cluster_region',
  credentials: {
    accessKeyId: 'your_access_key_id',
    secretAccessKey: 'your_secret_access_key',
  },
});

export default s3Client;

```
3. Go to your controller and follow the bellow commands.

`import s3Client from '../lib/s3Client';`

`import { PutObjectCommand } from '@aws-sdk/client-s3';`

Use this block of code for image upload in your controller's file upload function.

```
export interface fileInterface {
    fieldname: string;
    originalname: string;
    encoding: string;
    mimetype: string;
    buffer: Buffer;
    size: number;
}

const editProfile = async (req: Request, res: Response) => {
const files= req.files as Express.Multer.File[];
try {
    const fileUrl: string[] = []
    files && files.every(async (file: fileInterface) => {
            const filePath = randomNumber + file.originalname;
            const putObjectCommand = new PutObjectCommand({
                Bucket: 'your_bucket_name',
                Body:  file.buffer,
                Key: filePath,
                ContentType: file.mimetype,
                ACL: "public-read", // This allows anyone to access the uploaded image
            });
            const result = await s3Client.send(putObjectCommand);
            if( result.$metadata.httpStatusCode === 200 ){
                fileUrl.push([bucket_url]+filePath); you can get bucket_url in linode object storage
            }
    })
    return res.json({
      fileUrl: fileUrl
    });
} catch (err) {
   return res.json({ error: error.message });
    
}
}
```
After run this code, please check your Linode object storage
You can see the uploaded images

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4mb1wlzednlp8h5b88u.png)

that's all
Hope this is helpful for your development
Thank you