Skip to main content
Amazon Elastic Container Registry (ECR) stores your Docker images for the ADMA application. You need to create repositories for both the frontend and backend, then build and push the images.

Create ECR Repositories

1
Set Environment Variables
2
Ensure your environment variables are set from the AWS Setup guide:
3
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"
4
Create Backend Repository
5
Create the ECR repository for the Spring Boot backend:
6
aws ecr create-repository \
  --repository-name adma/backend \
  --region $AWS_REGION \
  --image-scanning-configuration scanOnPush=true
7
The scanOnPush=true flag enables automatic vulnerability scanning when images are pushed.
8
Create Frontend Repository
9
Create the ECR repository for the React frontend:
10
aws ecr create-repository \
  --repository-name adma/frontend \
  --region $AWS_REGION \
  --image-scanning-configuration scanOnPush=true
11
Verify Repositories
12
List your ECR repositories to confirm creation:
13
aws ecr describe-repositories --region $AWS_REGION
14
Expected output:
15
{
    "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:
aws ecr get-login-password --region $AWS_REGION \
  | docker login --username AWS --password-stdin $ECR_BASE
Expected output:
Login Succeeded
The ECR authentication token expires after 12 hours. If you see authentication errors, re-run this command.

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.
2
cd /path/to/adma-sa2-sa3/backend
3
Build Backend Image
4
Build the Docker image with proper tags:
5
docker build \
  -t $ECR_BASE/adma/backend:latest \
  -t $ECR_BASE/adma/backend:$(git rev-parse --short HEAD) \
  .
6
Tagging Strategy: We use both latest and the Git commit SHA. This allows easy rollbacks to specific versions.
7
The build process:
8
  • Uses gradle:8.5-jdk21 to compile the Spring Boot application
  • Creates an optimized JAR file
  • Packages it into eclipse-temurin:21-jre-alpine for a minimal runtime image
  • 9
    Push Backend Image
    10
    Push both tags to ECR:
    11
    docker push $ECR_BASE/adma/backend:latest
    docker push $ECR_BASE/adma/backend:$(git rev-parse --short HEAD)
    
    12
    Verify Backend Image
    13
    List images in the backend repository:
    14
    aws ecr describe-images \
      --repository-name adma/backend \
      --region $AWS_REGION
    

    Build and Push Frontend Image

    The frontend build process is more complex because it requires the backend API URL at build time.
    Critical: VITE_API_BASE_URL is baked into the JavaScript bundle during the Docker build. If you change your backend URL later, you must rebuild and redeploy the frontend image.
    2
    cd /path/to/adma-sa2-sa3/frontend
    
    3
    Build Frontend Image
    4
    Build with the API URL as a build argument:
    5
    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) \
      .
    
    6
    The build process:
    7
  • Uses node:20-alpine to install dependencies with Bun
  • Builds the React application with Vite
  • Packages the static files into nginx:stable-alpine
  • Configures nginx for single-page application routing
  • 8
    Push Frontend Image
    9
    Push both tags to ECR:
    10
    docker push $ECR_BASE/adma/frontend:latest
    docker push $ECR_BASE/adma/frontend:$(git rev-parse --short HEAD)
    
    11
    Verify Frontend Image
    12
    List images in the frontend repository:
    13
    aws ecr describe-images \
      --repository-name adma/frontend \
      --region $AWS_REGION
    

    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

    ArgumentRequiredExampleDescription
    VITE_API_BASE_URLYeshttps://api.example.comBackend API base URL (without trailing slash)

    Image Scanning Results

    View vulnerability scan results for your images:
    # Backend scan results
    aws ecr describe-image-scan-findings \
      --repository-name adma/backend \
      --image-id imageTag=latest \
      --region $AWS_REGION
    
    # Frontend scan results
    aws ecr describe-image-scan-findings \
      --repository-name adma/frontend \
      --image-id imageTag=latest \
      --region $AWS_REGION
    
    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
    name: Build and Push to ECR
    
    on:
      push:
        branches: [main]
    
    env:
      AWS_REGION: eu-west-1
      ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.eu-west-1.amazonaws.com
    
    jobs:
      build:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
    
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Configure AWS credentials
            uses: aws-actions/configure-aws-credentials@v4
            with:
              role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role
              aws-region: ${{ env.AWS_REGION }}
    
          - name: Login to Amazon ECR
            uses: aws-actions/amazon-ecr-login@v2
    
          - name: Build and push backend
            run: |
              docker build \
                -t $ECR_REGISTRY/adma/backend:${{ github.sha }} \
                -t $ECR_REGISTRY/adma/backend:latest \
                ./backend
              docker push $ECR_REGISTRY/adma/backend:${{ github.sha }}
              docker push $ECR_REGISTRY/adma/backend:latest
    
          - name: Build and push frontend
            run: |
              docker build \
                --build-arg VITE_API_BASE_URL=${{ secrets.VITE_API_BASE_URL }} \
                -t $ECR_REGISTRY/adma/frontend:${{ github.sha }} \
                -t $ECR_REGISTRY/adma/frontend:latest \
                ./frontend
              docker push $ECR_REGISTRY/adma/frontend:${{ github.sha }}
              docker push $ECR_REGISTRY/adma/frontend:latest
    

    Updating Images

    To deploy a new version of your application:
    1
    Re-authenticate if Needed
    2
    aws ecr get-login-password --region $AWS_REGION \
      | docker login --username AWS --password-stdin $ECR_BASE
    
    3
    Rebuild and Push
    4
    # 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
    
    5
    Force ECS to Pull New Images
    6
    aws ecs update-service \
      --cluster adma-cluster \
      --service adma-backend \
      --force-new-deployment \
      --region $AWS_REGION
    
    aws ecs update-service \
      --cluster adma-cluster \
      --service adma-frontend \
      --force-new-deployment \
      --region $AWS_REGION
    
    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:
    aws ecr get-login-password --region $AWS_REGION \
      | docker login --username AWS --password-stdin $ECR_BASE
    

    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:
    1. Configure RDS Database - Set up PostgreSQL
    2. Set up ECS Fargate - Deploy containers
    3. Configure Load Balancer - Set up routing

    Build docs developers (and LLMs) love