I’ve setup an application load balancer with a simple "Hello World" greeting that was built on a Dockerfile.
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY ./src .
EXPOSE 3000
CMD [ "node", "app.js" ]
My buildspec.yaml to push this image to AWS ECR repo is below
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
- apt-get update
- apt-get install -y nginx
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS
-- password-stdin 1234567.dkr.ecr.us-east-1.amazonaws.com
- docker image build -t 1234567.dkr.ecr.us-east-1.amazonaws.com/demo-ecs-poc-ui .
- docker push 1234567.dkr.ecr.us-east-1.amazonaws.com/demo-ecs-poc-ui
My app.js file in /src folder is:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
This works fine when I visit the load balancer DNS.
Now I changed this and added few react components and my Dockerfile looks like this now.
FROM node:lts-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
# Copy public directory to /app
COPY public/ /app/public
# Copy src directory to /app
COPY src/ /app/src
COPY package*.json .
RUN npm install
RUN npm i react-scripts
EXPOSE 3000
CMD ["npm", "start"]
There is no change to the buildspec.yaml and I am using the same image.
When I used this Dockerfile, the new image(with react stuff) is pushed successfully to ECR, but when I visit the ALB DNS, it still uses the old image and prints that "Hello World!" instead of the react stuff I put in.
Is there any change I need to make to make my ALB point to the latest image in the ECR repo?
I thought it will always pick up the latest image from the ECR and serve that, probably I am wrong.
I am using 2 different pipeline stacks (one for creating aws resources and the other one for application where the Docker stuff comes into play).
Sorry not a Docker expert, any help is much appreciated.
2
Answers
AWS Load Balancers don’t "run" docker images. An AWS Load Balancer just sends traffic to a target server. You would run a docker container from that image in either the ECS, EKS, or EC2 service, and configure the load balancer to send traffic to that running container. From your previous questions it looks like you are using ECS. Just pushing an updated image to ECR does not deploy a new docker container with that image. You need to update your ECS task definition to reference the new image, and then trigger an ECS service deployment with the new task definitin.
If you want ECS to "automatically update with the latest image" you could define the
latest
tag on your image and set this tag in the Task Definition as well. This way every time a new service spins up with the Task Def, the latest container image from ECR will be pulled. As Mark B mentioned, Load Balancers don’t actually pull anything from ECR, they simply route traffic to their Target Groups.