Create ECR Repositories
Ensure your environment variables are set from the AWS Setup guide:
export AWS_REGION="eu-west-1"
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export ECR_BASE="$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com"
aws ecr create-repository \
--repository-name adma/backend \
--region $AWS_REGION \
--image-scanning-configuration scanOnPush=true
aws ecr create-repository \
--repository-name adma/frontend \
--region $AWS_REGION \
--image-scanning-configuration scanOnPush=true
{
"repositories": [
{
"repositoryName": "adma/backend",
"repositoryUri": "123456789012.dkr.ecr.eu-west-1.amazonaws.com/adma/backend",
"registryId": "123456789012"
},
{
"repositoryName": "adma/frontend",
"repositoryUri": "123456789012.dkr.ecr.eu-west-1.amazonaws.com/adma/frontend",
"registryId": "123456789012"
}
]
}
Authenticate Docker to ECR
Before pushing images, authenticate your Docker client with ECR:Build and Push Backend Image
The backend uses a multi-stage Dockerfile that builds the Spring Boot application and packages it into a lightweight JRE container.docker build \
-t $ECR_BASE/adma/backend:latest \
-t $ECR_BASE/adma/backend:$(git rev-parse --short HEAD) \
.
Tagging Strategy: We use both
latest and the Git commit SHA. This allows easy rollbacks to specific versions.gradle:8.5-jdk21 to compile the Spring Boot applicationeclipse-temurin:21-jre-alpine for a minimal runtime imagedocker push $ECR_BASE/adma/backend:latest
docker push $ECR_BASE/adma/backend:$(git rev-parse --short HEAD)
Build and Push Frontend Image
The frontend build process is more complex because it requires the backend API URL at build time.export API_URL="https://api.yourdomain.com" # Your production backend URL
docker build \
--build-arg VITE_API_BASE_URL=$API_URL \
-t $ECR_BASE/adma/frontend:latest \
-t $ECR_BASE/adma/frontend:$(git rev-parse --short HEAD) \
.
node:20-alpine to install dependencies with Bunnginx:stable-alpinedocker push $ECR_BASE/adma/frontend:latest
docker push $ECR_BASE/adma/frontend:$(git rev-parse --short HEAD)
Build Arguments Reference
Backend Build Arguments
The backend Dockerfile doesn’t require build arguments. All configuration is provided via environment variables at runtime.Frontend Build Arguments
| Argument | Required | Example | Description |
|---|---|---|---|
VITE_API_BASE_URL | Yes | https://api.example.com | Backend API base URL (without trailing slash) |
Image Scanning Results
View vulnerability scan results for your images:ECR automatically scans images for CVEs (Common Vulnerabilities and Exposures) when
scanOnPush=true is enabled.CI/CD Integration
For automated builds in GitHub Actions, use this workflow:.github/workflows/build-push.yml
Updating Images
To deploy a new version of your application:aws ecr get-login-password --region $AWS_REGION \
| docker login --username AWS --password-stdin $ECR_BASE
# Backend
cd backend
docker build -t $ECR_BASE/adma/backend:latest .
docker push $ECR_BASE/adma/backend:latest
# Frontend (with API URL)
cd ../frontend
docker build \
--build-arg VITE_API_BASE_URL=$API_URL \
-t $ECR_BASE/adma/frontend:latest .
docker push $ECR_BASE/adma/frontend:latest
ECS performs rolling updates automatically. Old tasks remain running until new tasks pass health checks.
Troubleshooting
Authentication Errors
Problem:no basic auth credentials
Solution: Re-authenticate with ECR:
Build Fails - Out of Memory
Problem: Docker build fails with memory errors Solution: Increase Docker Desktop memory allocation:- Docker Desktop → Settings → Resources → Memory → Increase to 4GB+
Image Tag Already Exists
Problem: Cannot push image with existing tag Solution: ECR allows overwriting tags. This is normal behavior. Use commit SHA tags for immutable versions.Next Steps
With your Docker images in ECR:- Configure RDS Database - Set up PostgreSQL
- Set up ECS Fargate - Deploy containers
- Configure Load Balancer - Set up routing