– Overview
Hello, I’m a lead developer at MeFriend.ai. Our service supports +5,000 characters, which means we need to deliver a high volume of images quickly and efficiently.
Mefriend.ai – Click Here!
However, building an image server isn’t as simple as it might seem.
Managing images, delivering large files swiftly, and maintaining cost efficiency all pose significant challenges in setting up and operating an image server.
Today, I’ll walk you through setting up a highly efficient image server using AWS S3 and CloudFront to achieve speed and simplicity.
By following this guide, you’ll be able to build an image server successfully and very easy. I hope this post is helpful to you!
– Steps
- How are we going to build it?
- Create S3 Bucket
- Create CloudFront Distribution
- Integrate S3 and CloudFront
- Let’s Test!
– How are we going to build it?
Setting up an image server is simple and can be done directly from the AWS Console without any coding.
Let’s first take a look at the project structure to understand the flow before diving in.

All images will be stored in AWS S3, a service known for providing affordable and secure file storage. However, because S3 is the actual storage location, we need to ensure that users can never access it directly.
Instead, AWS CloudFront will serve as the secure access point to fetch images from S3.
CloudFront is more than just a means of accessing S3—it caches images in temporary storage locations distributed globally, allowing images to be retrieved from the storage point closest to the requesting user. These temporary storage locations are referred to as “Distributions.”
This means users worldwide can access images quickly, regardless of their location.
Because we’re using fully managed AWS services, there’s no need for coding to set up this image server.
Here’s a quick summary of the flow:
- Users request an image to AWS CloudFront.
- CloudFront retrieves the image from the closest temporary storage to the user. If the image isn’t cached there, it fetches it from S3, caches it, and delivers it.
– Create S3 Bucket
1. Setting up Bucket Name

The bucket name must be unique across all AWS regions globally.
However, remember that the bucket itself is created in a specific region, so be sure to select the desired region carefully.
2. Disabling ACLs

3. Blocking All Public Access

The bucket should have all public access blocked. As explained earlier, this is to prevent direct access from clients.
4. [Optional] Enabling Bucket Versioning

Versioning can vary depending on your use case, but we’ve enabled it here as our users may upload custom-created characters. This allows us to keep track of different versions of these images.
If you think you don’t need it, you may turn off this setting.
5. [Optional] Tags and Encryption

Tags can help with object discovery and analysis, but they’re optional—if you don’t feel the need for them, you can skip this step without any issues.
As for encryption, the default settings are sufficient in most cases.
6. Done!

If you see like this, finished to create S3 bucket sucessfully!
– Create CloudFront Distribution
1. Setting up Origin Domain

Set the Origin Domain to the S3 bucket you created earlier.
You don’t have to write all things, if you click input field, bucket lists are shown. Just selecting your image bucket! Name field is also automatically filled.
2. [Important] Creating new OAC

You may remember that we blocked all public access to S3.
So to make only this CloudFront distribution accessible to S3, we must set up origin access control(OAC).
3. [Optional] Setting CNAME

Using the default CloudFront domain in a real service isn’t ideal for management, so if you plan to operate an image server, it’s best to set up a CNAME, such as cdn.mefriend.ai, for easier management.
While setting up a CNAME isn’t essential for building the image server, it’s recommended for a live setup.
4. Done!

If you see like this, finished to create CloudFront distribution successfully!
– Integrate S3 and CloudFront

↓

If you followed these steps successfully, you may see this yellow warning in CloudFront distribution info.
The S3 bucket policy needs to be updated.
Click [Copy policy] button and go to S3 bucket you created.

In Permissions tab, you may see Bucket policy section.

Click Edit button and paste policy like below.

That is all! Now we can access S3 files via CloudFront domain.
– Let’s Test!
1. Upload Test File to S3

In real service, we process uploading in server side, but to test image server let’s upload file manually to S3.
2. Check CloudFront Domain

You can check CloudFront public domain in distribution general setting.
In my case, domain is
https://donkrfm96qaOn.cloudfront.net
Root address indicates a root directory of S3 bucket. So, if you uploaded a file in root directory, you can access the file via
https://donkrfm96qaOn.cloudfront.net/{filename}
3. Check Image

Because I uploaded profile.png on root directory of my bucket, I can access to this file via url below:
https://donkrfm96qaOn.cloudfront.net/profile.png
4. Change Image

Let’s upload another file with same name.
After uploading and if you enter the same url, you may see the same image.

This is because CloudFront still holds the cached data.
Even if you update a file in S3, CloudFront will continue to serve the same image until the cache expiration period passes.
5. [Optional] Invalidating Caches

So, to make CloudFront serve the latest image, you may notify your file has been changed. This can be achieved by invalidating caches.
By expiring caches immediately, CloudFront re-caches your file and can serve the latest version of your file.

In invalidation tab in your CloudFront distribution settings, you can make CloudFront re-cache files you want.

After finishing invalidation, and entering the same address, you may see the new image!

So far, we’ve walked through how we set up the image server for MeFriend.ai.
The combination of S3 + CloudFront isn’t limited to image servers—it’s widely used for deploying frontend apps and much more. While we connected CloudFront to S3, it can also be integrated with other services like AWS Lambda or Elastic Load Balancers, making it incredibly versatile.
As AWS stands at the forefront of cloud technology, learning these cloud skills will be highly beneficial for your growth.
Thank you for reading this detailed post!
(AWS resources created in this post are all for tests.)
Click here to read more deep contents!
AWS Cost Optimization by Reducing Image Cost – Click Here!
