Deploy a Container Web App on Amazon Lightsail

GETTING STARTED GUIDE

Module 4: Deploy a New Container Version

In this module, you will learn to update a container that has already been deployed

Introduction

In the life of an application, it will be updated many times. In this module, you will learn how to update your deployment and how to rollback a deployment, in case the new application version has issues.

What You Will Learn

  • Update the application code and build a new local container image
  • Push the updated container image to Amazon Lightsail
  • Deploy the new version of your application
  • Rollback a deployment, in case something goes wrong

 Time to Complete

10 minutes

 Module Prereqs

  • AWS Account with administrator-level access**
  • Recommended browser: The latest version of Chrome or Firefox

[**]Accounts created within the past 24 hours might not yet have access to the services required for this tutorial.

Implementation

Update Your Application Code and Build a New Container Image

Let's pretend the city name on the application front page is incorrect and needs to be modified.

Open the file code/templates/index.html. Search for "Las Vegas" and replace it with "Paris".

Then, build and test the container as explained in module 2. Open a terminal and type the following commands:

# build the container
docker build -t demo-flask-signup .

# run the container for local testing
docker run -p 8080:80               \
           --rm                     \
           -v ~/.aws:/root/.aws     \
           demo-flask-signup:latest

Now that the container is running, open a browser and point it at http://localhost:8080. You should see the application home screen, with the new city name.

gsg-build-lightsail-4

Push the Updated Container Image to Amazon Lightsail

Now the container is built, the next step is to push this new container image to Amazon Lightsail.

Open a terminal and type the following commands:

aws lightsail push-container-image    \
    --region eu-west-3                \
    --service-name signup-application \
    --label latest                    \
    --image demo-flask-signup:latest

# the command outputs the following lines
df0f7d33bb59: Pushed 
951ffe99d911: Pushed 
cee40450fe90: Pushed 
1327150a5178: Pushed 
4bc5d67b6427: Layer already exists 
ce8ffb5c560e: Layer already exists 
4226d5d0360f: Layer already exists 
9d1af766c818: Layer already exists 
d97733c0a3b6: Layer already exists 
c553c6ba5f13: Layer already exists 
48b4a40de359: Layer already exists 
ace9ed9bcfaf: Layer already exists 
764055ebc9a7: Layer already exists 
Digest: sha256:42d2e19ee7340bc7f028593318e9b7406e9e70fb4785618d3f6c78443e097a87
Image "demo-flask-signup:latest" registered.
Refer to this image as ":signup-application.latest.2" in deployments. 

The last line of the output displays the internal name of your container. Keep a note of it, as we will need this name to deploy the container onto the container service. In case you want to access the container name at a later stage, you can type the following command:

aws lightsail get-container-images    \
    --region eu-west-3                \
    --service-name signup-application

# the command outputs the following lines
{
    "containerImages": [
        {
            "image": ":signup-application.latest.2",
            "digest": "sha256:42d2e19ee7340bc7f028593318e9b7406e9e70fb4785618d3f6c78443e097a87",
            "createdAt": "2021-07-17T18:34:00+02:00"
        },
        {
            "image": ":signup-application.latest.1",
            "digest": "sha256:128f84907d30a1fb47c1888720485fa8050cc99bc1034e0cfd1f46d3b6e57e19",
            "createdAt": "2021-07-17T15:11:49+02:00"
        }
    ]
}

Notice the "state": "DEPLOYING" status. After a while, the state will become ACTIVE. The deployment takes a few minutes to complete. You can check the state of your deployment using the following command:

# while deploying
aws lightsail get-container-services      \
    --region eu-west-3                    \
    --query "containerServices[].nextDeployment.state"

# once deployed
aws lightsail get-container-services      \
    --region eu-west-3                    \
    --query "containerServices[].currentDeployment.state" 

Test your Deployment

To test your deployment, first retrieve the URL Lightsail created for you. Open a terminal and type the following command:

aws lightsail get-container-services        \
    --region eu-west-3                      \
    --query "containerServices[].url" 

# the command outputs something like the below 
[
    "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
]

We now have two versions of our container image - :signup-application.latest.1 and :signup-application.latest.2.

Deploy a New Version of Your Application

Now that the container image is stored on Amazon Lightsail, we can deploy that image to the container service, using similar commands as described in the previous module: Deploy a Container.

Edit the lc.json file and replace the name of the image to use - :signup-application.latest.1 - by the new version :signup-application.latest.2.

The new lc.json file should look like this:

{
    "serviceName": "signup-application",
    "containers": {
        "signup-app-container": {
            "image": ":signup-application.latest.2",
            "ports": {
                "80": "HTTP"
            }
        }
    },
    "publicEndpoint": {
        "containerName": "signup-app-container",
        "containerPort": 80
    }
}

Then, deploy the container by typing the following command:

aws lightsail create-container-service-deployment \
    --region eu-west-3                            \
    --cli-input-json file://lc.json

# the command outputs the following 

Test your Deployment

To test the deployment, switch to your browser window and refresh the page on the Container Service URL provided in the previous module.

You can retrieve the URL by typing this command in a terminal:

aws lightsail get-container-services        \
    --region eu-west-3                      \
    --query "containerServices[].url" 

# the command outputs something like the below 
[
    "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
]

Rollback a Deployment

The last deployment did not override the first version of the application, it just created a new version.

To verify the versions available, open a terminal and type the following command:

aws lightsail get-container-service-deployments \
    --region eu-west-3                          \
    --service-name signup-application

# the command outputs a JSON similar to this one 
{
    "deployments": [
        {
            "version": 2,
            "state": "ACTIVE",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.2",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2021-07-17T18:40:58+02:00"
        },
        {
            "version": 1,
            "state": "INACTIVE",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.1",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2021-07-17T15:31:01+02:00"
        }
    ]
}

Reading the output of the previous command, you can observe there are two deployments made. Version 1 is in an INACTIVE state, while version 2 is ACTIVE.

The following command gives a less detailed overview of your deployments:

aws lightsail get-container-service-deployments \
    --region eu-west-3                          \
    --service-name signup-application           \
    --query 'deployments[].{version: version, state: state, image: containers."signup-app-container".image}'

# the command outputs something similar to 
[
    {
        "version": 2,
        "state": "ACTIVE",
        "image": ":signup-application.latest.2"
    },
    {
        "version": 1,
        "state": "INACTIVE",
        "image": ":signup-application.latest.1"
    }
]

Now imagine the last version of the application you just deployed is not behaving correctly. Maybe a bug has not surfaced during the testing.

To access the log of your containers, open a terminal and type the following command:

aws lightsail get-container-log             \
    --region eu-west-3                      \
    --service-name signup-application       \
    --container-name signup-app-container   \
    --output text

# the command outputs log lines similar to this 
LOGEVENTS       2021-07-17T18:14:51+02:00       [pid: 26|app: 0|req: 5821/5821] 172.26.7.236 () {34 vars in 401 bytes} [Sat Jul 17 16:14:51 2021] GET / => generated 4579 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0)
LOGEVENTS       2021-07-17T18:14:51+02:00       [pid: 23|app: 0|req: 5824/5824] 172.26.7.236 () {34 vars in 402 bytes} [Sat Jul 17 16:14:51 2021] GET / => generated 4579 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0)
LOGEVENTS       2021-07-17T18:14:51+02:00       172.26.7.236 - - [17/Jul/2021:16:14:51 +0000] "GET / HTTP/1.1" 200 4579 "-" "ELB-HealthChecker/2.0" "-"

To quickly rollback your deployment and re-deploy the previous version of the application, change the lc.json file to the make it use the first version of the container image and redeploy this image.

Modify the lc.json file to the following:

# update the lc.json file
{
    "serviceName": "signup-application",
    "containers": {
        "signup-app-container": {
            "image": ":signup-application.latest.1",
            "ports": {
                "80": "HTTP"
            }
        }
    },
    "publicEndpoint": {
        "containerName": "signup-app-container",
        "containerPort": 80
    }
}

Then run the following command in the terminal:

aws lightsail create-container-service-deployment \
    --region eu-west-3                            \
    --cli-input-json file://lc.json

# the command outputs the following 
{
    "containerService": {
        "containerServiceName": "signup-application",
        "arn": "arn:aws:lightsail:eu-west-3:486652066693:ContainerService/528a0bcf-fd14-42d4-a09a-943a241adc51",
        "createdAt": "2021-07-17T13:38:40+02:00",
        "location": {
            "availabilityZone": "all",
            "regionName": "eu-west-3"
        },
        "resourceType": "ContainerService",
        "tags": [],
        "power": "nano",
        "powerId": "nano-1",
        "state": "DEPLOYING",
        "scale": 2,
        "currentDeployment": {
            "version": 2,
            "state": "ACTIVE",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.2",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2021-07-17T18:40:58+02:00"
        },
        "nextDeployment": {
            "version": 3,
            "state": "ACTIVATING",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.1",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2021-07-17T19:40:42+02:00"
        },
        "isDisabled": false,
        "principalArn": "arn:aws:iam::577312533299:role/amazon/lightsail/eu-west-3/containers/signup-application/1jetjd21p8qshe57seuh71tnrnn29ps77lnno20sbgl2ghbuc0r0",
        "privateDomainName": "signup-application.service.local",
        "url": "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
    }
}

After a while, deployment v3, using container image v1 is ACTIVE. Deployments v2 and v1 are INACTIVE.

You can verify the first version is deployed by opening your browser and pointing it at the container service URL.

gsg-build-lightsail-3

Conclusion

This is the end of this guide. Before taking a well-deserved break, be sure to clean up the environment to not accrue charges on your AWS account.

Up Next: Clean-up Resources

Let us know how we did.

Thank you for your feedback
We're glad this page helped you. Would you like to share additional details to help us continue to improve?
Close
Thank you for your feedback
We're sorry this page didn't help you. Would you like to share additional details to help us continue to improve?
Close