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