Chapter 8 — Containers
Day 1 — ECR: Pushing and Pulling Images
1. Concept Primer
ECR (Elastic Container Registry) is a private Docker registry. Before ECS/EKS can run an
image, it needs to exist in a repository they can pull from — authentication uses a
short-lived token from get-login-password.
2. Hands-on Exercise
Create a repository, tag a local image, log in, and push it.
3. Exact Commands
floci start && eval $(floci env)
aws ecr create-repository --repository-name day1-app
REPO_URI=$(aws ecr describe-repositories --repository-names day1-app \
--query 'repositories[0].repositoryUri' --output text)
echo "$REPO_URI"
aws ecr get-login-password | docker login --username AWS --password-stdin $REPO_URI
# Use any small existing image for the exercise
docker pull alpine:latest
docker tag alpine:latest $REPO_URI:latest
docker push $REPO_URI:latest
aws ecr list-images --repository-name day1-app
4. Gotchas
REPO_URItypically resolves to alocalhost:4566/...-style address locally — this won't match the<account>.dkr.ecr.<region>.amazonaws.comformat you'd see against real AWS, so don't hardcode assumptions about the URI shape into scripts you intend to reuse against a real account.- Docker must already be running (same requirement as Lambda/RDS) since ECR pushes are real image layer transfers.
5. Self-Check
Why does docker login need a token from get-login-password instead of a fixed
username/password pair?
Day 2 — ECS: Task Definitions and Running a Task
1. Concept Primer
An ECS task definition is a blueprint (container image, CPU/memory, ports, env vars). A cluster is where tasks actually run. Fargate launch type means no EC2 instances to manage; EC2 launch type runs tasks on instances you register into the cluster.
2. Hands-on Exercise
Register a task definition using the image pushed in Day 1, create a cluster, and run one task on it.
3. Exact Commands
eval $(floci env)
REPO_URI=$(aws ecr describe-repositories --repository-names day1-app \
--query 'repositories[0].repositoryUri' --output text)
cat > task-def.json << EOF
{
"family": "day2-task",
"networkMode": "bridge",
"containerDefinitions": [{
"name": "day2-container",
"image": "$REPO_URI:latest",
"memory": 128,
"cpu": 128,
"essential": true
}]
}
EOF
aws ecs register-task-definition --cli-input-json file://task-def.json
aws ecs create-cluster --cluster-name day2-cluster
aws ecs run-task \
--cluster day2-cluster \
--task-definition day2-task \
--launch-type EC2
aws ecs list-tasks --cluster day2-cluster
4. Gotchas
- Fargate launch type support tends to be the trickiest part of ECS emulation across
LocalStack-style tools — if
--launch-type FARGATEbehaves oddly, fall back toEC2launch type (as above) while you're still learning the task/cluster model, and confirm current Fargate support in Floci's docs before relying on it. networkMode: bridgeis the simplest option to get a task running locally;awsvpcmode (required for Fargate) adds ENI provisioning that's more to debug while learning.
5. Self-Check
What's the core difference in what you're responsible for managing between the EC2 and
FARGATE launch types?