subcollection | copyright | lastupdated | lasttested | content-type | services | account-plan | completion-time | use-case | ||
---|---|---|---|---|---|---|---|---|---|---|
solution-tutorials |
|
2024-01-05 |
2023-09-06 |
tutorial |
CDN, cloud-object-storage |
paid |
2h |
ApplicationPerformance |
{{site.data.keyword.attribute-definition-list}}
{: #static-files-cdn} {: toc-content-type="tutorial"} {: toc-services="CDN, cloud-object-storage"} {: toc-completion-time="2h"}
This tutorial may incur costs. Use the Cost Estimator to generate a cost estimate based on your projected usage. {: tip}
This tutorial walks you through how to host and serve website assets (images, videos, documents) and user-generated content in a {{site.data.keyword.cos_full_notm}}, and how to use a {{site.data.keyword.cdn_full}} (CDN) for fast and secure delivery to users around the world. {: shortdesc}
Web applications have different types of content: HTML content, images, videos, cascading style sheets (CSS), JavaScript files, user-generated content. Some content changes often, other not so much, some is accessed very often, other occasionally. As the audience for the application grows, you may want to offload serving these media objects to another component, freeing resources for your main application. You may also want to have these files served from a location close to your application users, wherever they are in the world.
There are many reasons why you would use a Content Delivery Network in these situations:
- the CDN will cache the content, pulling the content from the origin (your servers) only if it is not available in its cache or if it has expired;
- with multiple data centers across the world, the CDN will serve the cached content from the closest location for your users;
- running on a different domain than your main application, the browser will be able to load more content in parallel - most browsers have a limit in the number of connections per hostname.
{: #static-files-cdn-objectives}
- Upload files to an {{site.data.keyword.cos_full_notm}} bucket.
- Make content globally available with a Content Delivery Network (CDN).
- Expose files by using a static website application.
{: caption="Figure 1. Architecture diagram of the tutorial" caption-side="bottom"} {: style="text-align: center;"}
- The user accesses the application
- The application includes content distributed through a Content Delivery Network
- If the content is not available in the CDN or has expired, the CDN pulls the content from the origin.
{: #static-files-cdn-prereqs}
This tutorial requires:
- {{site.data.keyword.cloud_notm}} CLI with the {{site.data.keyword.cos_full_notm}} plugin (
cloud-object-storage
), git
to clone the source code repository,jq
to query JSON files.
You will find instructions to download and install these tools for your operating environment in the Getting started with tutorials guide.
To avoid the installation of these tools you can use the {{site.data.keyword.cloud-shell_short}}{: external} from the {{site.data.keyword.cloud_notm}} console. {: tip}
In addition, you need the following permissions on Classic Infrastructure:
These permissions are required to be able to order and view the CDN service.
{: #static-files-cdn-get_code} {: step}
Let's consider a simple web application with different types of content like images, videos and cascading style sheets. You will store the content in a storage bucket and configure the CDN to use the bucket as its origin.
To start, retrieve the application code:
git clone https://github.com/IBM-Cloud/webapp-with-cos-and-cdn
cd webapp-with-cos-and-cdn
{: pre}
{: #static-files-cdn-create_cos} {: step}
{{site.data.keyword.cos_full_notm}} provides flexible, cost-effective, and scalable cloud storage for unstructured data.
- Go to the catalog{: external} in the console, and select Object Storage{: external} from the Storage section.
- Provide a Service Name.
- Select the desired resource group
- Click Create to create a new instance of {{site.data.keyword.cos_full_notm}}
Next, create a storage bucket.
- In the service dashboard, click Buckets, then Create bucket followed by choosing Customize your bucket.
- Set a unique bucket name such as
username-mywebsite
avoid dots (.) in the bucket name. - Set the Resiliency to Regional.
- Set the Location appropriately. Choose us-south or make substitutions in the instructions below when you see us-south.
- Pick Smart Tier for Storage class.
- Scroll down to Static website hosting and click Add.
- Routing rules (individual) should be selected.
- Enter index.html into the Index document text box.
- Click Public access to On.
- Click Save above in the Static website hosting title.
- Scroll down and click Create bucket.
- The bucket will be displayed after creation completes. Click on the Configuration tab. Notice the Endpoint section and take note of the Public endpoint which will be needed later to both configure ibmcloud CLI and the CDN. As example for a bucket with resiliency set to Regional in the us-south region, the public endpoint would be s3.us-south.cloud-object-storage.appdomain.cloud.
{: #static-files-cdn-upload} {: step}
In this section, you will use the {{site.data.keyword.cos_short}} plugin to upload files to the bucket.
-
Set a variable for the COS endpoint URL and a variable for the bucket name:
PUBLIC_ENDPOINT=s3.us-south.cloud-object-storage.appdomain.cloud
{: pre}
BUCKET_NAME=<YOUR_BUCKET_NAME>
{: pre}
-
If you are not logged in, use
ibmcloud login
oribmcloud login --sso
to log in interactively. Target the region where the bucket was created. As example for a bucket created inus-south
:ibmcloud target -r us-south
{: pre}
If you had used the cloud-object-storage (cos) plugin before, you might need to reconfigure the crn and set it to the current service. {: tip}
-
Upload the files named
index.html
,a-css-file.css
,a-picture.png
, anda-video.mp4
from the content directory of the web application code you downloaded previously. Upload the files to the root of the bucket.ibmcloud cos upload --bucket $BUCKET_NAME --key index.html --file index.html ibmcloud cos upload --bucket $BUCKET_NAME --key a-picture.png --file a-picture.png ibmcloud cos upload --bucket $BUCKET_NAME --key a-css-file.css --file a-css-file.css ibmcloud cos upload --bucket $BUCKET_NAME --key a-video.mp4 --file a-video.mp4
{: pre}
-
View your files from your dashboard. {: caption="Bucket Content" caption-side="bottom"}
-
Access the files through your browser or by using curl:
curl http://$BUCKET_NAME.$PUBLIC_ENDPOINT/index.html echo open http://$BUCKET_NAME.$PUBLIC_ENDPOINT/index.html
It will look like:
<html> <head> <title>Files hosted in Cloud Object Storage and accessible through a Content Delivery Network</title> ... </html> open http://fredflinstone-mywebsite.s3.us-south.cloud-object-storage.appdomain.cloud/index.html
{: screen}
{: #static-files-cdn-5} {: step}
In this section, you will create a CDN service. The CDN service distributes content to where it is needed. The first time content is requested, it’s pulled from the host server (your bucket in {{site.data.keyword.cos_full_notm}}) to the delivery network and stays there for other users to access it quickly without the network latency to reach the host server again.
{: #static-files-cdn-6}
-
Go to the catalog in the console, and select Content Delivery Network{: external} from the Network section. This CDN is powered by Akamai. Click Create.
-
On the next dialog, set the Hostname to a DNS subdomain like
static.example.com
(option a, see below) or simply a unique name (option b).The Hostname has two purposes. It is a unique name that identifies the CDN instance. It can also be the DNS subdomain{: external}. When filling out this form you will choose one of the following options:
-
To use a DNS subdomain in a domain that you control:
- Fill in the hostname as the DNS subdomain. For example if you control
example.com
thenstatic.example.com
would be a valid choice. - Choose HTTP port if required by your application.
- Choose HTTPS port if required by your application and chose the SSL certificate DV SAN certificate.
- CDN Content will be available at your subdomain,
static.example.com
, for example. - CDN Content is also available on the generated CNAME.
- Fill in the hostname as the DNS subdomain. For example if you control
-
Use the IBM generated DNS subdomain:
- Fill in a unique hostname to identify the DNS instance, this will not be used in the URL for the CDN content.
- Choose HTTP port if required by your application.
- Choose HTTPS port - this is required.
- Choose SSL certificate Wildcard - this is required.
- CDN Content will be available in the generated CNAME.
-
-
Leave the Custom CNAME prefix blank, it will default to a unique name.
-
Next, under Configure your origin, leave Host header and Path empty.
-
Select Object Storage to configure the CDN for COS.
-
Set the Endpoint to your bucket public endpoint ($PUBLIC_ENDPOINT). Above this was: s3.us-south.cloud-object-storage.appdomain.cloud.
-
Set Bucket name to the bucket name from above.
-
Enable HTTP (80).
-
Enable HTTPS (443) for https access.
- If using a subdomain that you control (option a):
- HTTPS is optional.
- If HTTPS is selected it is required to select DV SAN Certificate for the SSL certificate.
- If not using a subdomain (option b):
- Select HTTPS. It is required.
- Select Wildcard Certificate for the SSL certificate.
- If using a subdomain that you control (option a):
-
Accept the Master Service Agreement and click Create.
{: #static-files-cdn-7}
-
Select the CDN instance in the list{: external}.
-
If you earlier picked DV SAN Certificate, you are likely seeing
Requesting certificate
. It can take as long as 24 hours for this state to complete. When available follow the steps shown when clicking on View domain validation. Note, that this can take a few hours. If you want to continue with this tutorial just create a new CDN and this time do not enable HTTPS or select a wildcard certificate. Do not forget to select a different hostname. -
The Details panel shows both the Hostname and the IBM CNAME for your CDN
-
Go to your DNS provider and create a CNAME record for the HOSTNAME for IBM CNAME. For me it was
static.example.com
->cdnakawazw9dpv33.cdn.appdomain.cloud
.Often, it takes some minutes for DNS changes to become active. You might need to wait before proceeding to the next step. {: tip}
-
Access your files with
http://<static.example.com>/index.html
.
You can demonstrate the performance improvement. Access via the CDN. Check the output of the first curl to verify successful connection:
SUBDOMAIN=static.example.com
curl http://$SUBDOMAIN/index.html
while sleep 1; do curl --output /tmp/fast http://$SUBDOMAIN/a-video.mp4; done
{: screen}
Access via COS:
curl http://$PUBLIC_ENDPOINT/$BUCKET_NAME/index.html
while sleep 1; do curl --output /tmp/slow http://$PUBLIC_ENDPOINT/$BUCKET_NAME/a-video.mp4 ; done
If you are using {{site.data.keyword.cloud-shell_short}} you can change the location to a region with more distance from the bucket to see a more substantial performance change.
{: #static-files-cdn-8}
All of the content is now distributed through the CDN. Website content can be broken into static content and dynamic content. To demonstrate this a file cdn.html
has references to the CDN related files through the prefix CDN/. Edit cdn.html and replace the occurrences of CDN with your CNAME, http://static.example.com
, in the example above. If you open the file in the vim
editor the command :%s#CDN#http://static.yourwebsite.com#
will do the trick.
Upload cdn.html by replacing the file index.html:
ibmcloud cos upload --bucket $BUCKET_NAME --key index.html --file cdn.html
{: pre}
Back in the {{site.data.keyword.cloud_notm}} console in the bucket Configuration panel scroll down to the Static website hosting endpoints section and copy the Public URL into a browser tab. Since you configured this earlier to redirect to index.html
the web application will be displayed and content will be delivered through the CDN. For me the URL was fredflinstone-mywebsite.s3-web.us-south.cloud-object-storage.appdomain.cloud
, notice the s3-web
.
{: #static-files-cdn-9}
Accessing the website at the URL provided by the COS bucket is great, but access via a custom domain, like web.example.com, is even better. Follow the instructions at Domain Routing for IBM Cloud Object Storage static web hosting. Paste web.example.com into the browser which will default to https:// which will display the page correctly, but the CDN content will only be rendered if it also accessed via an https:// URL. You can explicitly specify http://example.com or better yet ensure that HTTPS was selected when creating the CDN and https:// URL references to the CDN content were pasted into the index.html file in the previous step.
{: #static-files-cdn-10} {: step}
To clean up resource, perform the following steps:
- Delete the {{site.data.keyword.cdn_full}} service.
- Delete the {{site.data.keyword.cos_full_notm}} bucket and / or service.
Depending on the resource it might not be deleted immediately, but retained (by default for 7 days). You can reclaim the resource by deleting it permanently or restore it within the retention period. See this document on how to use resource reclamation. {: tip}
{: #static-files-related-content}