Deploy multi-container service on AWS LightSail
AWS introduced LightSail as a cost-effective, fixed monthly plan Virtual Private Service in 2016 for easy development on LAMP stack , Nginx, MEAN stack etc but they have recently upped their game and finally provided support for containerized applications. I have tried out LightSail Container Service and also set up a CICD Pipeline for a :
— containerized Flask Application,
— with Redis for caching mechanism and
— CircleCI
as pipeline orchestrator.
You can easily see the pricing models for LightSail below. In my example , with a nano VPS, LightSail charges will be fixed at US $7 for a month.
This article focuses on the different challenges I faced along the way while setting up a deployment pipeline. My containerized application just displays Canada’s new COVID cases for the day and that’s it, it is pretty straight-forward but deploying it via a pipeline onto LightSail has some hoops to jump through.
My code is here . Following is the config.yml
for CircleCI pipeline:
Notes:
No resources on Terraform or CloudFormation for LightSail Container Services so I could not use any of them. Currently there is an open Pull Request for Terraform.
- You need to deploy using
awsctl
and for someaws lightsail
commands you are gonna needlightsailctl
- Finally , you need to pass a dynamic json containing LightSail image version , something like this:
:aws-lightsail-app.python-app.10
I created a json template and at runtime providing the image version in my GitHub code.
- Deployments are versioned, so newer deployments will make old deployments and images inactive.
Steps:
- Create a LightSail Container Service , either from console or with
awsctl
:
aws lightsail create-container-service --service-name <service_name> --power nano --scale 1
- Push Application Image to a public docker repository and that may be a dealbreaker in many scenarios. In this example , images are being pushed to AWS LightSail Container Images.
aws lightsail push-container-image --service-name <service_name> --label <any_label> --image <image:tagname>
- Once image is pushed, next step is to create a deployment but for that we need a json template, you can define health-checks, timeouts, success code validation etc in this json :
{
“serviceName”: “aws-lightsail-app”,
“containers”: {
“app”: {
“image”: “”,
“ports”: {
“8080”: “HTTP”
}
}
},
“publicEndpoint”: {
“containerName”: “app”,
“containerPort”: 8080
}
}
In runtime, that image
parameter will be updated with the actual image version retrieved from LightSail console.
Now we can create a deployment :
aws lightsail create-container-service-deployment — cli-input-json file://<updated_json>.json
LightSail UI:
- Container images are available under Images , once deployment is complete we can delete the unused images as shown below:
- Deployment typically takes 3–4 mins to complete and you can see the progress here:
Once deployment is complete, our application will be reachable on the public domain:
You can monitor CPU and Memory under metrics but you cannot add any alerts on them :(
LightSail is a good starting point for AWS journey , whether you deploy a containerized service or a small website , test out your applications etc. But scalability can be a hindrance. Although it was never the point for LightSail, as on the outset, it was supposed to be a cost-effective, easy-set up measure from AWS and it serves that purpose.