Containerize the Mythical Mysfits monolith

Containerize the Mythical Mysfits monolith

Containerize monolith

Meaning of an INSTRUCTION in Dockerfile.

  • FROM: Used to indicate which image is built from the original image. Depending on the application that needs to be packaged, we will use a different original image.
  • RUN: Used to run a command when building an image.
  • WORKDIR: Used to set the working directory. Any subsequent RUN, CMD, ENTRYPOINT, COPY and ADD instructions will take place inside this WORKDIR directory.
  • COPY: COPY the source directory from the host machine to the filesystem of the image.
  • CMD: Used to provide the default command that will be run when the Docker Container starts from the built Image, there can only be 1 CMD directive.
  1. Check Dockerfile.draft
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y python3-pip python-dev build-essential
RUN pip3 install --upgrade pip
#[TODO]: Copy python source files and requirements file into container image

#[TODO]: Install dependencies listed in the requirements.txt file using pip3

#[TODO]: Specify a listening port for the container

#[TODO]: Run mythicalMysfitsService.py as the final step. We want this container to run as an executable. Looking at ENTRYPOINT and CMD for this?

Containerize the Mythical Mysfits monolith

  1. Complete Dockerfile
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y python3-pip python-dev build-essential
RUN pip3 install --upgrade pip
#[TODO]: Copy python source files and requirements file into container image
COPY ./service /MythicalMysfitsService
WORKDIR /MythicalMysfitsService
#[TODO]: Install dependencies listed in the requirements.txt file using pip3
RUN pip3 install -r ./requirements.txt
#[TODO]: Specify a listening port for the container
EXPOSE 80
#[TODO]: Run the mythicalMysfitsService.py as the final step
ENTRYPOINT["python3"]
CMD ["mythicalMysfitsService.py"]

Containerize the Mythical Mysfits monolith

  1. If the Dockerfile is complete, rename your file from “Dockerfile.draft” to “Dockerfile” and continue to the next step.
cd ~/environment/amazon-ecs-mythicalmysfits-workshop/workshop-1/app/monolith-service/
mv Dockerfile.draft Dockerfile

Containerize the Mythical Mysfits monolith

  1. Execute build image with command docker build [OPTIONS] PATH | URL | - .

This command needs to be run in the same directory where your Dockerfile is located.

  • Note the time after that for the build command to look in the current directory for the Dockerfile.
docker build -t monolith-service .

Containerize the Mythical Mysfits monolith

  1. You should see a bunch of results as Docker builds all the layers of the image.

If something goes wrong during the build, the build will fail and stop (red text and warnings along the way as long as the build doesn’t fail).

Removing intermediate container a71540b615b4
 ---> 5ab93ce927c8
Step 8/10 : EXPOSE 80
 ---> Running in 27074f1d4c3a
Removing intermediate container 27074f1d4c3a
 ---> f528fe7756d5
Step 9/10 : ENTRYPOINT ["python3"]
 ---> Running in 8ef1757aadb0
Removing intermediate container 8ef1757aadb0
 ---> a1d1ed159fb2
Step 10/10 : CMD ["mythicalMysfitsService.py"]
 ---> Running in da0c544e601b
Removing intermediate container da0c544e601b
 ---> b283e0821fc9
Successfully built b283e0821fc9
Successfully tagged monolith-service:latest

Containerize the Mythical Mysfits monolith

  1. Your Dockerfile has been successfully created, but the Dockefile has not been optimized for microservices.

Since you convert monoliths into microservices, you will edit the source code (eg mythicalMysfitsService.py) and build this image a few times.

  • Check Dockerfile

Containerize the Mythical Mysfits monolith

  1. Dockerfile optimization
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y python3-pip python-dev build-essential
RUN pip3 install --upgrade pip
COPY ./service/requirements.txt .
RUN pip3 install -r ./requirements.txt
COPY ./service /MythicalMysfitsService
WORKDIR /MythicalMysfitsService
EXPOSE 80
ENTRYPOINT["python3"]
CMD ["mythicalMysfitsService.py"]

Containerize the Mythical Mysfits monolith

  1. To see the benefits of Dockerfile optimization, you need to first rebuild the monolith image using the new Dockerfile.
docker build -t monolith-service .

Containerize the Mythical Mysfits monolith

  1. Then we make changes to mythicalMysfitsService.py by adding a comment at the end of the file.
# This is a comment to force a Docker-rebuild

Containerize the Mythical Mysfits monolith

  1. Docker cached the requests on the first rebuild after reordering.
docker build -t monolith-service .

Containerize the Mythical Mysfits monolith

  1. Perform rebuild monolith image again. Cache reference in this second rebuild

Containerize the Mythical Mysfits monolith

  1. Use docker images [OPTIONS] [REPOSITORY[:TAG]] to list images
docker images

Containerize the Mythical Mysfits monolith

  1. Run the container and test
TABLE_NAME=$(aws dynamodb list-tables | jq -r .TableNames[0])
docker run -p 8000:80 -e AWS_DEFAULT_REGION=$AWS_REGION -e DDB_TABLE_NAME=$TABLE_NAME monolith-service

Note: You can find your DynamoDB table names in the workshop-1/cfn-output.json file which is derived from the CloudFormation Stack output.

Containerize the Mythical Mysfits monolith

  1. To test the basic functionality of a monolith service, query the service using a utility like cURL included with Cloud9.
  • Click the plus sign next to your tabs and select New Terminal or click Window -> New Terminal from the Cloud9 menu to open a new shell session to run the following curl command.
curl http://localhost:8000/mysfits
  • You will see a JSON array with data about Mythical Mysfits

Note: Processes running inside a Docker container can authenticate with DynamoDB because they can access the EC2 Metadata API endpoint running at 169.254. attached to our Cloud9 environment in the initial setup script. Processes in the container cannot access the ~/.aws/credentials file in the host filesystem (unless it’s explicitly attached to the container).

Containerize the Mythical Mysfits monolith

  1. Back to the monolith container running tab
  • Monolith container running in the foreground with stdout/stderr print to the screen, when receiving the request, will display 200 “OK”
 * Serving Flask app "mythicalMysfitsService" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
172.17.0.1 - - [26/May/2022 16:49:43] "GET /mysfits HTTP/1.1" 200 -
INFO:werkzeug:172.17.0.1 - - [26/May/2022 16:49:43] "GET /mysfits HTTP/1.1" 200 -

Containerize the Mythical Mysfits monolith

  1. In the tab running monolith container, use the key combination Ctrl + C to stop running the container.

Note: Container runs in the foreground with stdout/stderr printing to the console. In a production environment, when running the container in the background and having to configure the destination of the logs. We can run the container in the background using -d.

TABLE_NAME=$(aws dynamodb list-tables | jq -r .TableNames[0])
docker run -d -p 8000:80 -e AWS_DEFAULT_REGION=$AWS_REGION -e DDB_TABLE_NAME=$TABLE_NAME monolith-service

Containerize the Mythical Mysfits monolith

  1. List docker containers to check running containers
docker ps

Containerize the Mythical Mysfits monolith

  1. See the running monolith in the list (store the Container ID to use docker logs). Repeat the curl command, then do a log check
docker logs <CONTAINER_ID>

Containerize the Mythical Mysfits monolith

  1. Now, we have Docker image working, we do tag assignment and push to ECR. AWS ECR is a fully managed AWS Docker container registry service that simplifies the storage, management, and deployment of Docker container images. ECR can be integrated with Amazon Elastic Container Service (ECS) to simplify deployment execution flow setup for production systems as well as eliminate management complexity. Repository manager for container images. Next, we use the ECS pull image from the ECR.
  • Go to ECS and select Repositories
  • We will have 2 repositories: STACK_NAME-mono-xxx and STACK_NAME-like-xxx
  • Select the icon to copy URL of Mono repository (use in the next steps)

Note: repository URI is unique

Containerize the Mythical Mysfits monolith

  1. Implement tag assignment and push container image and monolith repository
MONO_ECR_REPOSITORY_URI=$(aws ecr describe-repositories | jq -r .repositories[].repositoryUri | grep mono)
docker tag monolith-service:latest $MONO_ECR_REPOSITORY_URI:latest
docker push $MONO_ECR_REPOSITORY_URI:latest

Containerize the Mythical Mysfits monolith

  1. Visit the ECR repository page, the image is uploaded and tagged as the latest.

Containerize the Mythical Mysfits monolith