Skip to main content

AWS Lightsail Container Service: Container Deployment via AWS CLI

822 words·
AWS AWS CLI Lightsail Container Service Docker
Table of Contents

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