Prerequisites #
Install AWS CLI #
# Update packages
sudo apt update
# Unstall zip tool
sudo apt install unzip -y
# Download AWS CLI zip file
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# Unzip
unzip awscliv2.zip
# Install
sudo ./aws/install
# Verify installation / check version
/usr/local/bin/aws --version
Configure AWS CLI #
# Start AWS CLI configuration
aws configure
Install AWS Lightsailctl Plugin #
# Download Lightsailctl binary
sudo curl "https://s3.us-west-2.amazonaws.com/lightsailctl/latest/linux-amd64/lightsailctl" -o "/usr/local/bin/lightsailctl"
# Change permissions
sudo chmod +x /usr/local/bin/lightsailctl
 
AWS Lightsail #
Create a Container Service #
Create a Lightsail container service, with the following specs: 
Micro (1 GB RAM, 0.25 vCPUs) ×1 node
# Create a Lightsail container service
aws lightsail create-container-service \
  --service-name container-app \
  --power micro \
  --scale 1 \
  --region eu-central-1
# Shell output:
{
    "containerService": {
        "containerServiceName": "container-app",
        "arn": "arn:aws:lightsail:eu-central-1:012345678912:ContainerService/bf603d37-aa8c-4bb3-9c9d-7b8c923741dd",
        "createdAt": "2024-12-15T14:59:54+00:00",
        "location": {
            "availabilityZone": "all",
            "regionName": "eu-central-1"
        },
        "resourceType": "ContainerService",
        "tags": [],
        "power": "micro",
        "powerId": "micro-1",
        "state": "PENDING",
        "scale": 1,
        "isDisabled": false,
        "principalArn": "",
        "privateDomainName": "container-app.service.local",
        "url": "https://container-app.xrbgnh1c0a538.eu-central-1.cs.amazonlightsail.com/",
        "privateRegistryAccess": {
            "ecrImagePullerRole": {
                "isActive": false,
                "principalArn": ""
            }
        }
    }
}
Verify the Container Service #
Verify the state of the container service is “READY”, this can take several minutes:
# Verify the state of the container service
aws lightsail get-container-services \
  --service-name container-app \
  --region eu-central-1
# Shell output:
{
    "containerServices": [
        {
            "containerServiceName": "container-app",
            "arn": "arn:aws:lightsail:eu-central-1:012345678912:ContainerService/bf603d37-aa8c-4bb3-9c9d-7b8c923741dd",
            "createdAt": "2024-12-15T14:59:54+00:00",
            "location": {
                "availabilityZone": "all",
                "regionName": "eu-central-1"
            },
            "resourceType": "ContainerService",
            "tags": [],
            "power": "micro",
            "powerId": "micro-1",
            "state": "READY",
            "scale": 1,
            "isDisabled": false,
            "principalArn": "arn:aws:iam::557133367334:role/amazon/lightsail/eu-central-1/containers/container-app/mmjkl61m9rp3ei57i4diah4uc410ku6srp2u0iud8pr5vmpojb80",
            "privateDomainName": "container-app.service.local",
            "url": "https://container-app.xrbgnh1c0a538.eu-central-1.cs.amazonlightsail.com/",
            "privateRegistryAccess": {
                "ecrImagePullerRole": {
                    "isActive": false,
                    "principalArn": ""
                }
            }
        }
    ]
}
Example Application #
- Dockerfile
 
# Use the official Caddy image as the base
FROM caddy:alpine
# Create a non-root user "caddy"
RUN addgroup -S caddy && adduser -S -G caddy caddy
# Adjust permissions
RUN mkdir -p /usr/share/caddy && \
    chown -R caddy:caddy /usr/share/caddy /config /data
# Copy website files into the container
COPY index.html /usr/share/caddy/
# Switch to the non-root user
USER caddy
# Expose the default Caddy port
EXPOSE 80
- index.html
 
<!DOCTYPE html>
<html>
<head>
    <title>jklug.work</title>
</head>
<body>
    <h1>Some HTML</h1>
    <p>AWS Lightsail Example Application<br></p>
</body>
</html>
Build the Image #
# Build the image for the application
docker build -t caddy-web-app .
# Verify the images
docker images
# Shell output:
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
caddy-web-app   latest    96a1bbd57153   11 seconds ago   49.3MB
 
Push the Image to AWS Lightsail #
# Push the container image the AWS Lightsail container service
aws lightsail push-container-image \
  --service-name container-app \
  --label caddy-web-app \
  --image caddy-web-app:latest \
  --region eu-central-1
# Shell output:
Digest: sha256:796e54a6f749319df1d898110142a1c20a603ec08cdf0bbb540fe54a7fc66fb5
Image "caddy-web-app:latest" registered.
Refer to this image as ":container-app.caddy-web-app.7" in deployments.
Verify the Image #
Optional, verify the container image:
# Verify the AWS Lightsail container image
aws lightsail get-container-images \
  --service-name container-app \
  --region eu-central-1
# Shell output:
{
    "containerImages": [
        {
            "image": ":container-app.caddy-web-app.7",
            "digest": "sha256:796e54a6f749319df1d898110142a1c20a603ec08cdf0bbb540fe54a7fc66fb5",
            "createdAt": "2024-12-15T15:04:30+00:00"
        }
    ]
}
Deploy the Container as Service #
# Create a json configuration file
vi deployment-config.json
{
  "serviceName": "container-app",
  "containers": {
    "example-application": {
      "image": ":container-app.caddy-web-app.7",
      "ports": {
        "80": "HTTP"
      }
    }
  },
  "publicEndpoint": {
    "containerName": "example-application",
    "containerPort": 80
  }
}
# Deploy the service
aws lightsail create-container-service-deployment \
  --service-name container-app \
  --region eu-central-1 \
  --cli-input-json file://deployment-config.json
# Shell output:
{
    "containerService": {
        "containerServiceName": "container-app",
        "arn": "arn:aws:lightsail:eu-central-1:012345678912:ContainerService/bf603d37-aa8c-4bb3-9c9d-7b8c923741dd",
        "createdAt": "2024-12-15T14:59:54+00:00",
        "location": {
            "availabilityZone": "all",
            "regionName": "eu-central-1"
        },
        "resourceType": "ContainerService",
        "tags": [],
        "power": "micro",
        "powerId": "micro-1",
        "state": "DEPLOYING",
        "scale": 1,
        "nextDeployment": {
            "version": 1,
            "state": "ACTIVATING",
            "containers": {
                "example-application": {
                    "image": ":container-app.caddy-web-app.7",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "example-application",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2024-12-15T15:06:30+00:00"
        },
        "isDisabled": false,
        "principalArn": "arn:aws:iam::557133367334:role/amazon/lightsail/eu-central-1/containers/container-app/mmjkl61m9rp3ei57i4diah4uc410ku6srp2u0iud8pr5vmpojb80",
        "privateDomainName": "container-app.service.local",
        "url": "https://container-app.xrbgnh1c0a538.eu-central-1.cs.amazonlightsail.com/",
        "privateRegistryAccess": {
            "ecrImagePullerRole": {
                "isActive": false,
                "principalArn": ""
            }
        }
    }
}
Verify the Service Deployment #
Wait till the state changes to “RUNNING”:
# Verify the Lightsail service status
aws lightsail get-container-services \
  --service-name container-app \
  --region eu-central-1 \
  --no-cli-pager
# Shell output:
{
    "containerServices": [
        {
            "containerServiceName": "container-app",
            "arn": "arn:aws:lightsail:eu-central-1:012345678912:ContainerService/bf603d37-aa8c-4bb3-9c9d-7b8c923741dd",
            "createdAt": "2024-12-15T14:59:54+00:00",
            "location": {
                "availabilityZone": "all",
                "regionName": "eu-central-1"
            },
            "resourceType": "ContainerService",
            "tags": [],
            "power": "micro",
            "powerId": "micro-1",
            "state": "RUNNING",
            "scale": 1,
            "currentDeployment": {
                "version": 1,
                "state": "ACTIVE",
                "containers": {
                    "example-application": {
                        "image": ":container-app.caddy-web-app.7",
                        "command": [],
                        "environment": {},
                        "ports": {
                            "80": "HTTP"
                        }
                    }
                },
                "publicEndpoint": {
                    "containerName": "example-application",
                    "containerPort": 80,
                    "healthCheck": {
                        "healthyThreshold": 2,
                        "unhealthyThreshold": 2,
                        "timeoutSeconds": 2,
                        "intervalSeconds": 5,
                        "path": "/",
                        "successCodes": "200-499"
                    }
                },
                "createdAt": "2024-12-15T15:06:30+00:00"
            },
            "isDisabled": false,
            "principalArn": "arn:aws:iam::557133367334:role/amazon/lightsail/eu-central-1/containers/container-app/mmjkl61m9rp3ei57i4diah4uc410ku6srp2u0iud8pr5vmpojb80",
            "privateDomainName": "container-app.service.local",
            "url": "https://container-app.xrbgnh1c0a538.eu-central-1.cs.amazonlightsail.com/",
            "privateRegistryAccess": {
                "ecrImagePullerRole": {
                    "isActive": false,
                    "principalArn": ""
                }
            }
        }
    ]
}
Test the Container Application #
# Curl the URL
curl https://container-app.xrbgnh1c0a538.eu-central-1.cs.amazonlightsail.com/
# Shell out:
<!DOCTYPE html>
<html>
<head>
    <title>jklug.work</title>
</head>
<body>
    <h1>Some HTML</h1>
    <p>AWS Lightsail Example Application<br></p>
</body>
</html>
 
Cleanup #
Delete Lightsail Container Service #
# Delete the Lightsail container service
aws lightsail delete-container-service \
  --service-name container-app \
  --region eu-central-1
 
Links #
# AWS Lightsailctl Plugin installation
https://docs.aws.amazon.com/en_us/lightsail/latest/userguide/amazon-lightsail-install-software.html#install-lightsailctl-on-linux