Using Docker on AWS

Lab setup data from the Pluralsight course on:

Using Docker on AWS


The Complete Obsolete Guide to Generative AI (from Manning) is a lighthearted look at programming with AI, as well as a rock-solid resource for getting the most out of these insanely powerful services. Let it be your guide to analyzing massive data sources, summarize pages and pages of text, and scour the live internet.

 


NOTE 1.0

These command snippets are meant for people working through the new, fully updated release of the Pluralsight course. If, somehow, you’ve been sent to this page from an older version that doesn’t cover Fargate or Kubernetes, then I would advise you to disregard what you’ve seen. The way AWS handles Docker container workloads has changed substantially since that older version was created and there’s a lot there that’ll just confuse you. Accept no substitutes!

Note 1.1

Although I often recommend running LXC containers as a fantastic virtual environment for experimenting, don’t even think about it for those demos that require Docker CE to be installed locally: since both technologies use abstractions of the host kernel, they’d be stepping all over each other’s feet trying to get things done. Instead, unless you choose to follow along with the command line-based demos directly on an actual physical PC, I would recommend installing VirtualBox, downloading the latest stable LTS Ubuntu ISO file (which would currently be 18.04), and firing up as many VMs as you like. I included a video on working with VirtualBox in my Linux Server Virtualization course.

Note 2.0

You’ll need to make a change to the Dockerfile that installs Apache2 on Ubuntu: instead of:

        • RUN apt-get -y install

The line should read:

        • RUN DEBIAN_FRONTEND=”noninteractive” apt-get -y install

If you don’t do that, the build will stall as it tries to set the system locale. Thanks to a sharp-eyed Pluralsight viewer for catching this and bringing it to my attention. I’ve updated the Dockerfiles themselves below.


Script for installing Docker on Ubuntu

#!/bin/bash
sudo apt-get update
# Prepare TLS encryption
sudo apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

# Add and verify official Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Add apt repo
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

sudo apt-get update

# Install Docker CE
sudo apt-get -y install docker-ce docker-ce.cli containerd.io

A simple Dockerfile

# Simple Dockerfile
#
FROM ubuntu:latest

RUN apt-get update
RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y apache2
RUN echo "Welcome to my web site" > /var/www/html/index.html
EXPOSE 80
Build and run a container
docker build -t "webserver" .
docker images
docker run -d -p 80:80 webserver /usr/sbin/apache2ctl -D FOREGROUND

WordPress stack.yml file for local deployment

version: '3.1'

services:

wordpress:
image: wordpress
ports:
- 80:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: examplepassword
WORDPRESS_DB_NAME: wpdb

db:
image: mysql:5.7
environment:
MYSQL_DATABASE: wpdb
MYSQL_USER: wpuser
MYSQL_PASSWORD: examplepassword
MYSQL_RANDOM_ROOT_PASSWORD: '1'

Prepare an EC2 launch type

ecs-cli configure \
--cluster ec2-test-App \
--region us-east-1 \
--default-launch-type EC2 \
--config-name ec2-test-App

ecs-cli configure profile \
--access-key <your-access-key> \
--secret-key <your-secret-key> \
--profile-name ec2-test-App

ecs-cli up \
--capability-iam \
--size 2 \
--instance-type t2.medium \
--cluster-config ec2-test-App
--ecs-profile ec2-test-App

docker-compose.yml for EC2 launch


version: '3'
services:
wordpress:
image: wordpress
ports:
- "80:80"
links:
- mysql
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD:

ecs-params.yml for EC2 launch


version: 1
task_definition:
services:
wordpress:
cpu_shares: 100
mem_limit: 524288000
mysql:
cpu_shares: 100
mem_limit: 524288000

Launch EC2 type

ecs-cli compose \
--project-name ec2-project service up \
--cluster-config ec2-test-App

ecs-cli ps --cluster-config ec2-test-App

[shut down:]
ecs-cli compose down --cluster-config ec2-test-App
ecs-cli down --force --cluster-config ec2-test-App

Prepare a Fargate launch

ecs-cli configure profile \
--profile-name wpfargate \
--access-key <your-access-key> \
--secret-key <your-secret-key>

ecs-cli configure \
--cluster wpfargate \
--region us-east-1 \
--default-launch-type FARGATE \
--config-name wpfargate

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}


aws iam \
--region us-east-1 create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document file://task-execution-assume-role.json

NOTE: You may need to also run this command for the later ecs-compose command to work:

aws iam \
--region us-east-1 attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

ecs-cli up --cluster-config wpfargate

aws ec2 create-security-group \
--group-name "wpfargate-sg" \
--description "My Fargate security group" \
--vpc-id "vpc-0fd8a0742962a4c7e"

aws ec2 authorize-security-group-ingress \
--group-id "sg-056e52a070c1aad48" \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0

YAML files for Fargate

nano docker-compose.yml

version: '3'
services:
wordpress:
image: wordpress
ports:
- "80:80"
logging:
driver: awslogs
options: 
awslogs-group: wpfargate
awslogs-region: us-east-1
awslogs-stream-prefix: wordpress


nano ecs-params.yml

version: 1
task_definition:
task_execution_role: ecsTaskExecutionRole
ecs_network_mode: awsvpc
task_size:
mem_limit: 0.5GB
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "subnet-0ea714f5de083febd"
- "subnet-03157b03dac355069"
security_groups:
- "sg-056e52a070c1aad48"
assign_public_ip: ENABLED

Launch Fargate type

ecs-cli compose \
--project-name wpfargate service up \
--create-log-groups \
--cluster-config wpfargate \
--cluster wpfargate

ecs-cli ps --cluster wpfargate

ecs-cli compose \
--project-name wpfargate service down \
--cluster-config wpfargate

ecs-cli down \
--force \
--cluster-config wpfargate


Install eksctl, kubectl, and aws-iam-authenticator
curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

sudo mv /tmp/eksctl /usr/local/bin
eksctl version

curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.19.6/2021-01-05/bin/linux/amd64/kubectl
ls
curl -o kubectl.sha256 https://amazon-eks.s3.us-west-2.amazonaws.com/1.19.6/2021-01-05/bin/linux/amd64/kubectl.sha256
ls
cat kubectl.sha256
openssl sha1 -sha256 kubectl

chmod +x ./kubectl
mkdir bin
cp kubectl bin
export PATH=$HOME/bin:$PATH
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
kubectl version --short --client

curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.12.7/2019-03-27/bin/linux/amd64/aws-iam-authenticator
curl -o aws-iam-authenticator.sha256 https://amazon-eks.s3-us-west-2.amazonaws.com/1.12.7/2019-03-27/bin/linux/amd64/aws-iam-authenticator.sha256
ls
openssl sha1 -sha256 aws-iam-authenticator
chmod +x ./aws-iam-authenticator
cp aws-iam-authenticator bin/
aws-iam-authenticator help

Build Kubernetes cluster and download YAML files

eksctl create cluster \
--name wp-cluster \
--version 1.12 \
--nodegroup-name standard-workers \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 4 \
--node-ami auto

kubectl create secret generic mysql-pass --from-literal=password=bigsecret
kubectl get secrets

curl https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/wordpress/mysql-deployment.yaml > mysql-deployment.yaml

curl https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/wordpress/wordpress-deployment.yaml > wordpress-deployment.yaml

Build Apache webserver container on Docker CE

# Simple Apache Dockerfile
#
FROM ubuntu:latest
RUN apt-get update
RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y apache2
CMD /usr/sbin/apache2ctl -D FOREGROUND
EXPOSE 80

docker build -t newserver .
docker run -d -p 80:80 newserver

Apache on ECS

docker-compose.yml

version: '3'
services:
apache:
image: dbclinton/newserver
ports:
- "80:80"

ecs-params.yml

version: 1
task_definition:
services:
apache:
cpu_shares: 100
mem_limit: 524288000

ecs-cli configure \
--cluster ec2cluster2 \
--region us-east-1 \
--default-launch-type EC2 \
--config-name ec2cluster2

ecs-cli configure profile \
--access-key <your-access-key> \
--secret-key <your-secret-key> \
--profile-name ec2cluster2


ecs-cli up \
--capability-iam \
--size 1 \
--instance-type t3.medium \
--cluster-config ec2cluster2


ecs-cli compose \
--project-name ec2cluster service up \
--cluster-config ec2cluster2

ECR authentication and administration

aws ecr get-login --no-include-email --region us-east-1

aws ecr create-repository --repository-name newrepo

aws ecr describe-repositories

docker images

docker-compose.yml

version: '3'
services:
apache:
image: 297972716276.dkr.ecr.us-east-1.amazonaws.com/newrepo:latest
ports:
- "80:80"

ecs-params.yml

version: 1
task_definition:
services:
apache:
cpu_shares: 100
mem_limit: 524288000

ecs-cli configure \
--cluster ec2cluster \
--region us-east-1 \
--default-launch-type EC2 \
--config-name ec2cluster

ecs-cli configure profile \
--access-key <your-access-key> \
--secret-key <your-secret-key> \
--profile-name ec2cluster


ecs-cli up \
--capability-iam \
--size 1 \
--instance-type t3.medium \
--cluster-config ec2cluster


ecs-cli compose \
--project-name ec2cluster service up \
--cluster-config ec2cluster

ecs-cli ps --cluster-config ec2cluster

ecs-cli compose \
--project-name ec2cluster service down \
--cluster-config ec2cluster

ecs-cli down --force --cluster-config ec2cluster