Introduction to AWS Lightsail and Advantages of Simplified Cloud Platforms

Introduction

Amazon Lightsail is a Cloud Platform (PaaS/IaaS) service designed to simplify the deployment of web applications and virtual servers for users. It is an ideal solution for developers, small businesses, or those new to AWS who do not want to deal with the complexity of EC2.

Advantages

  • Simple to use: Provides pre-configured blueprints for popular platforms such as WordPress, Node.js, or LAMP stack with just a few clicks.
  • Predictable costs: Lightsail uses a flat-rate monthly pricing model, including storage (SSD), bandwidth, and RAM, helping you easily manage your budget.
  • Intuitive interface: The Console is streamlined, focusing on core features like Instance, Database, and Networking management.
  • Easy to scale: When the application outgrows Lightsail's scale, you can easily export a snapshot to Amazon EC2 to take full advantage of the AWS ecosystem.
  • Built-in services: Comes with essential features like DNS management, Static IP, basic Firewall, and Load Balancer.


Prerequisites

In this article, I will deploy an application using React Vite. As in previous articles, you can also use your project if you want to change it. Here, I'm just updating the Nginx config to handle the refresh error when using React Router.

Create a file named nginx.conf with the following content to cache resource files and redirect traffic to the index file when accessing the web application's routes directly:

server {
    listen 80;
    server_name _;

    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
       
        if ($request_uri ~* ^/index\.html$|^/$) {
            add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
        }
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/x-javascript
        application/xml
        application/rss+xml
        application/atom+xml
        image/svg+xml;
}


Update the Dockerfile as follows:

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Then, rebuild the Docker image and push it to AWS ECR before continuing with the next section.


Detail

Continue using AWS CDK, create the file lib/lightsail-stack.ts with the following content:

import * as cdk from "aws-cdk-lib"
import * as lightsail from "aws-cdk-lib/aws-lightsail"
import { Construct } from "constructs"

export class LightsailStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    const imageUri = process.env.IMAGE || ""
    const serviceName = "my-lightsail-service"
    const containerName = "web-container"
    const containerService = new lightsail.CfnContainer(
      this,
      "LightsailService",
      {
        serviceName,
        power: "nano",
        scale: 1,
        publicDomainNames: [],
        privateRegistryAccess: {
          ecrImagePullerRole: {
            isActive: true,
          },
        },
        containerServiceDeployment: {
          containers: [
            {
              containerName,
              image: imageUri,
              ports: [{ port: "80", protocol: "HTTP" }],
            },
          ],
          publicEndpoint: {
            containerName,
            containerPort: 80,
            healthCheckConfig: {
              path: "/",
              successCodes: "200-499",
              healthyThreshold: 2,
              unhealthyThreshold: 4,
              timeoutSeconds: 5,
              intervalSeconds: 10,
            },
          },
        },
      },
    )

    new cdk.CfnOutput(this, "LightsailServiceUrl", {
      value: containerService.attrUrl,
      description: "The URL of the deployed Lightsail Container Service",
    })
  }
}
  • Creating AWS Lightsail is also relatively simple, requiring only the use of lightsail.CfnContainer and providing the following main information:

    • power: this is the configuration of the machine you need, including levels like nano, micro, small, medium, large.
    • containerServiceDeployment: information about the Docker image and port you want to use.
    • publicEndpoint.containerPort is the port for external access.
    • healthCheckConfig: health check information. Here, I'm configuring it to consider success if accessing the web application returns a status code between 200-499.


Update the aws-cdk.ts file to use the newly created stack:

#!/usr/bin/env node
import 'dotenv/config';
import * as cdk from "aws-cdk-lib/core"
import { LightsailStack } from '../lib/lightsail-stack';

const app = new cdk.App()
new LightsailStack(app, "LightsailStack")


Result after deployment:

 LightsailStack
 Deployment time: 202.16s

Outputs:
LightsailStack.LightsailServiceUrl = https://my-lightsail-service.emtdnpeq3c0hy.ap-southeast-1.cs.amazonlightsail.com/

 Total time: 226.3s


Resource has been created on AWS Lightsail



View logs during the deployment process and the operation of the web application


After deployment, the cache mechanism is operational as per the Nginx configuration




Happy coding!

See more articles here.

Comments

Popular posts from this blog

All practice series

Deploying a NodeJS Server on Google Kubernetes Engine

Setting up Kubernetes Dashboard with Kind

Using Kafka with Docker and NodeJS

Monitoring with cAdvisor, Prometheus and Grafana on Docker

Kubernetes Practice Series

Kubernetes Deployment for Zero Downtime

Practicing with Google Cloud Platform - Google Kubernetes Engine to deploy nginx

NodeJS Practice Series

Helm for beginer - Deploy nginx to Google Kubernetes Engine