Skip to content

Commit c4200f1

Browse files
committed
feat: update push to ecr script
1 parent de54635 commit c4200f1

File tree

4 files changed

+253
-106
lines changed

4 files changed

+253
-106
lines changed

README.md

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,37 +82,59 @@ this [example](https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examp
8282
2. Check whether you are in the [supported region](#supported-region), then click on the **Create parameter** button.
8383
3. Fill in the parameters below, leaving other options as default:
8484

85-
- **Name**: Enter a parameter name (e.g., "SwiftChatAPIKey", will be used as `ApiKeyParam` in Step 2).
85+
- **Name**: Enter a parameter name (e.g., "SwiftChatAPIKey", will be used as `ApiKeyParam` in Step 3).
8686

8787
- **Type**: Select `SecureString`
8888

89-
- **Value**: Enter any string without spaces.(this will be your `API Key` in Step 3)
89+
- **Value**: Enter any string without spaces.(this will be your `API Key` in Step 4)
9090

9191
4. Click **Create parameter**.
9292

93-
### Step 2: Deploy stack and get your API URL
93+
### Step 2: Build and push container images to ECR
9494

95-
1. Go to [CloudFormation Console](https://console.aws.amazon.com/cloudformation/home#/stacks/create/template?stackName=SwiftChat) and select **Upload a template file** under **Specify template**, then use one of the following templates to deploy. (Make sure you are in the same region where your API Key was created.)
95+
1. Clone this repository:
96+
```bash
97+
git clone https://github.com/aws-samples/swift-chat.git
98+
cd swift-chat
99+
```
96100

97-
- **App Runner**
101+
2. Run the build and push script:
102+
```bash
103+
cd server/scripts
104+
bash ./push-to-ecr.sh
105+
```
98106

99-
Open [SwiftChatAppRunner.template](https://github.com/aws-samples/swift-chat/blob/main/server/template/SwiftChatAppRunner.template), then download and upload the file.
107+
3. Follow the prompts to configure:
108+
- ECR repository name (or use default: `swift-chat-api`)
109+
- Image tag (or use default: `latest`)
110+
- AWS region (or use default: `us-east-1`)
100111

101-
- **Lambda** (Note: For AWS customer use only)
112+
4. The script will build and push the Docker image to your ECR repository.
102113

103-
Open [SwiftChatLambda.template](https://github.com/aws-samples/swift-chat/blob/main/server/template/SwiftChatLambda.template) then download and upload the file.
114+
5. **Important**: Copy the image URI displayed at the end of the script output. You'll need this in the next step.
104115

105-
2. Click **Next**, On the "Specify stack details" page, provide the following information:
106-
- Fill the `ApiKeyParam` with the parameter name you used for storing the API key (e.g., "SwiftChatAPIKey").
107-
- For App Runner, choose an `InstanceTypeParam` based on your needs.
108-
3. Click **Next**, Keep the "Configure stack options" page as default, Read the Capabilities and Check the "I
116+
### Step 3: Deploy stack and get your API URL
117+
118+
1. Download the CloudFormation template you want to use:
119+
- For App Runner: [SwiftChatAppRunner.template](https://github.com/aws-samples/swift-chat/blob/main/server/template/SwiftChatAppRunner.template)
120+
- For Lambda: [SwiftChatLambda.template](https://github.com/aws-samples/swift-chat/blob/main/server/template/SwiftChatLambda.template)
121+
122+
2. Go to [CloudFormation Console](https://console.aws.amazon.com/cloudformation/home#/stacks/create/template?stackName=SwiftChatAPI) and select **Upload a template file** under **Specify template**, then upload the template file you downloaded. (Make sure you are in the same region where your API Key was created.)
123+
124+
3. Click **Next**, On the "Specify stack details" page, provide the following information:
125+
- **Stack name**: Keep the default "SwiftChatAPI" or change if needed
126+
- **ApiKeyParam**: Enter the parameter name you used for storing the API key (e.g., "SwiftChatAPIKey")
127+
- **ContainerImageUri**: Enter the ECR image URI from Step 2 output
128+
- For App Runner, choose an **InstanceTypeParam** based on your needs
129+
130+
4. Click **Next**, Keep the "Configure stack options" page as default, Read the Capabilities and Check the "I
109131
acknowledge that AWS CloudFormation might create IAM resources" checkbox at the bottom.
110-
4. Click **Next**, In the "Review and create" Review your configuration and click **Submit**.
132+
5. Click **Next**, In the "Review and create" Review your configuration and click **Submit**.
111133

112-
Wait about 3-5 minutes for the deployment to finish, then click the CloudFormation stack and go to **Outputs** tab, you
134+
Wait about 10-15 minutes for the deployment to finish, then click the CloudFormation stack and go to **Outputs** tab, you
113135
can find the **API URL** which looks like: `https://xxx.xxx.awsapprunner.com` or `https://xxx.lambda-url.xxx.on.aws`
114136

115-
### Step 3: Open the App and setup with API URL and API Key
137+
### Step 4: Open the App and setup with API URL and API Key
116138

117139
1. Launch the App, open the drawer menu, and tap **Settings**.
118140
2. Paste the `API URL` and `API Key`(The **Value** you typed in Parameter Store) Under Amazon Bedrock -> SwiftChat

server/scripts/push-to-ecr.sh

Lines changed: 158 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,173 @@
11
# NOTE: The script will try to create the ECR repository if it doesn't exist. Please grant the necessary permissions to the IAM user or role.
22
# Usage:
3-
# cd scripts
3+
# cd server/scripts
44
# bash ./push-to-ecr.sh
55

66
set -o errexit # exit on first error
77
set -o nounset # exit on using unset variables
88
set -o pipefail # exit on any error in a pipeline
99

10-
# Define variables
11-
TAG="latest"
12-
ARCHS=("amd64" "arm64")
13-
AWS_REGIONS=("us-east-1") # List of AWS region, use below list if you don't enable ECR repository replication
14-
# AWS_REGIONS=("us-west-2" "us-east-1" "ap-south-1" "ap-southeast-1" "ap-southeast-2" "ap-northeast-1" "ca-central-1"
15-
# "eu-central-1" "eu-west-2" "eu-west-3" "sa-east-1") # List of supported AWS regions
10+
# Check prerequisites
11+
echo "================================================"
12+
echo "SwiftChat - Build and Push to ECR"
13+
echo "================================================"
14+
echo ""
1615

17-
build_and_push_images() {
16+
echo "Checking prerequisites..."
17+
18+
# Check if Docker is available
19+
if ! command -v docker &> /dev/null; then
20+
echo "❌ ERROR: Docker is not installed or not in PATH."
21+
echo "Please install Docker Desktop or Docker Engine before running this script."
22+
exit 1
23+
fi
24+
25+
# Check if Docker daemon is running
26+
if ! docker info >/dev/null 2>&1; then
27+
echo "❌ ERROR: Docker daemon is not running."
28+
echo "Please start Docker Desktop or Docker daemon before running this script."
29+
exit 1
30+
fi
31+
32+
# Check if AWS CLI is available
33+
if ! command -v aws &> /dev/null; then
34+
echo "❌ ERROR: AWS CLI is not installed or not in PATH."
35+
echo "Please install AWS CLI before running this script."
36+
exit 1
37+
fi
38+
39+
# Check if AWS credentials are configured
40+
if ! aws sts get-caller-identity >/dev/null 2>&1; then
41+
echo "❌ ERROR: AWS credentials are not configured."
42+
echo "Please run 'aws configure' or set up your AWS credentials before running this script."
43+
exit 1
44+
fi
45+
46+
echo "✅ All prerequisites are met."
47+
echo ""
48+
49+
# Prompt user for inputs
50+
51+
# Get repository name
52+
read -p "Enter ECR repository name (default: swift-chat-api): " REPO_NAME
53+
REPO_NAME=${REPO_NAME:-swift-chat-api}
54+
55+
# Get image tag
56+
read -p "Enter image tag (default: latest): " TAG
57+
TAG=${TAG:-latest}
58+
59+
# Get AWS region
60+
read -p "Enter AWS region (default: us-east-1): " AWS_REGION
61+
AWS_REGION=${AWS_REGION:-us-east-1}
62+
63+
echo ""
64+
echo "Configuration:"
65+
echo " Repository: $REPO_NAME"
66+
echo " Image Tag: $TAG"
67+
echo " AWS Region: $AWS_REGION"
68+
echo ""
69+
read -p "Continue with these settings? (y/n): " CONFIRM
70+
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
71+
echo "Aborted."
72+
exit 1
73+
fi
74+
echo ""
75+
76+
# Acknowledgment about ECR repository creation
77+
echo "ℹ️ NOTICE: This script will automatically create ECR repository if it doesn't exist."
78+
echo " The repository will be created with the following default settings:"
79+
echo " - Image tag mutability: MUTABLE (allows overwriting tags)"
80+
echo " - Image scanning: Disabled"
81+
echo " - Encryption: AES256 (AWS managed encryption)"
82+
echo ""
83+
echo " You can modify these settings later in the AWS ECR Console if needed."
84+
echo " Required IAM permissions: ecr:CreateRepository, ecr:GetAuthorizationToken,"
85+
echo " ecr:BatchCheckLayerAvailability, ecr:InitiateLayerUpload, ecr:UploadLayerPart,"
86+
echo " ecr:CompleteLayerUpload, ecr:PutImage, ecr-public:GetAuthorizationToken"
87+
echo ""
88+
read -p "Do you acknowledge and want to proceed? (y/n): " ACK_CONFIRM
89+
if [[ ! "$ACK_CONFIRM" =~ ^[Yy]$ ]]; then
90+
echo "Aborted."
91+
exit 1
92+
fi
93+
echo ""
94+
95+
build_and_push_image() {
1896
local IMAGE_NAME=$1
1997
local TAG=$2
20-
local ENABLE_MULTI_ARCH=${3:-true} # Parameter for enabling multi-arch build, default is true
21-
local DOCKERFILE_PATH=${4:-"../src/Dockerfile"} # Parameter for Dockerfile path, default is "../src/Dockerfile_ecs"
22-
23-
# Build Docker image for each architecture
24-
if [ "$ENABLE_MULTI_ARCH" == "true" ]; then
25-
for ARCH in "${ARCHS[@]}"
26-
do
27-
# Build multi-architecture Docker image
28-
docker buildx build --platform linux/$ARCH -t $IMAGE_NAME:$TAG-$ARCH -f $DOCKERFILE_PATH --load ../src/
29-
done
30-
else
31-
# Build single architecture Docker image
32-
docker buildx build --platform linux/${ARCHS[0]} -t $IMAGE_NAME:$TAG -f $DOCKERFILE_PATH --load ../src/
98+
local DOCKERFILE_PATH=$3
99+
local REGION=$AWS_REGION
100+
local ARCH="amd64" # Single architecture for simplicity
101+
102+
echo "Logging in to AWS Public ECR..."
103+
# Log in to AWS Public ECR for pulling base images
104+
if ! aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws; then
105+
echo "❌ ERROR: Failed to login to AWS Public ECR. Please check your AWS credentials."
106+
exit 1
107+
fi
108+
109+
echo "Building $IMAGE_NAME:$TAG..."
110+
111+
# Build Docker image
112+
if ! docker buildx build --platform linux/$ARCH -t $IMAGE_NAME:$TAG -f $DOCKERFILE_PATH --load ../src/; then
113+
echo "❌ ERROR: Failed to build Docker image."
114+
exit 1
115+
fi
116+
117+
echo "Getting AWS account ID..."
118+
# Get the account ID
119+
if ! ACCOUNT_ID=$(aws sts get-caller-identity --region $REGION --query Account --output text 2>/dev/null); then
120+
echo "❌ ERROR: Failed to get AWS account ID. Please check your AWS credentials and region."
121+
exit 1
122+
fi
123+
124+
# Create repository URI
125+
REPOSITORY_URI="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${IMAGE_NAME}"
126+
127+
echo "Creating ECR repository if it doesn't exist..."
128+
# Create ECR repository if it doesn't exist
129+
aws ecr create-repository --repository-name "${IMAGE_NAME}" --region $REGION >/dev/null 2>&1 || true
130+
131+
echo "Logging in to ECR..."
132+
# Log in to ECR
133+
if ! aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $REPOSITORY_URI; then
134+
echo "❌ ERROR: Failed to login to ECR. Please check your AWS credentials and permissions."
135+
exit 1
136+
fi
137+
138+
echo "Tagging image for ECR..."
139+
# Tag the image for ECR
140+
if ! docker tag $IMAGE_NAME:$TAG $REPOSITORY_URI:$TAG; then
141+
echo "❌ ERROR: Failed to tag Docker image."
142+
exit 1
33143
fi
34144

35-
# Push Docker image to ECR for each architecture in each AWS region
36-
for REGION in "${AWS_REGIONS[@]}"
37-
do
38-
# Get the account ID for the current region
39-
ACCOUNT_ID=$(aws sts get-caller-identity --region $REGION --query Account --output text)
40-
41-
# Create repository URI
42-
REPOSITORY_URI="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${IMAGE_NAME}"
43-
44-
# Create ECR repository if it doesn't exist
45-
aws ecr create-repository --repository-name "${IMAGE_NAME}" --region $REGION || true
46-
47-
# Log in to ECR
48-
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $REPOSITORY_URI
49-
50-
# Push the image to ECR for each architecture
51-
if [ "$ENABLE_MULTI_ARCH" == "true" ]; then
52-
for ARCH in "${ARCHS[@]}"
53-
do
54-
# Tag the image for the current region
55-
docker tag $IMAGE_NAME:$TAG-$ARCH $REPOSITORY_URI:$TAG-$ARCH
56-
# Push the image to ECR
57-
docker push $REPOSITORY_URI:$TAG-$ARCH
58-
# Create a manifest for the image
59-
docker manifest create $REPOSITORY_URI:$TAG $REPOSITORY_URI:$TAG-$ARCH --amend
60-
# Annotate the manifest with architecture information
61-
docker manifest annotate $REPOSITORY_URI:$TAG "$REPOSITORY_URI:$TAG-$ARCH" --os linux --arch $ARCH
62-
done
63-
64-
# Push the manifest to ECR
65-
docker manifest push $REPOSITORY_URI:$TAG
66-
else
67-
# Tag the image for the current region
68-
docker tag $IMAGE_NAME:$TAG $REPOSITORY_URI:$TAG
69-
# Push the image to ECR
70-
docker push $REPOSITORY_URI:$TAG
71-
fi
72-
73-
echo "Pushed $IMAGE_NAME:$TAG to $REPOSITORY_URI"
74-
done
145+
echo "Pushing image to ECR..."
146+
# Push the image to ECR
147+
if ! docker push $REPOSITORY_URI:$TAG; then
148+
echo "❌ ERROR: Failed to push image to ECR."
149+
exit 1
150+
fi
151+
152+
echo "✅ Successfully pushed $IMAGE_NAME:$TAG to $REPOSITORY_URI"
153+
echo ""
154+
155+
# Return the image URI for later use
156+
echo "$REPOSITORY_URI:$TAG"
75157
}
76158

77-
build_and_push_images "swift-chat-api" "$TAG" "true" "../src/Dockerfile"
159+
echo "Building and pushing SwiftChat image..."
160+
IMAGE_URI=$(build_and_push_image "$REPO_NAME" "$TAG" "../src/Dockerfile")
161+
162+
echo "================================================"
163+
echo "✅ Image successfully pushed!"
164+
echo "================================================"
165+
echo ""
166+
echo "Your container image URI:"
167+
echo " $IMAGE_URI"
168+
echo ""
169+
echo "Next steps:"
170+
echo " 1. Download the CloudFormation templates from server/template/ folder"
171+
echo " 2. Update the ContainerImageUri parameter with your image URI above"
172+
echo " 3. Deploy the stack via AWS CloudFormation Console"
173+
echo ""

server/template/SwiftChatAppRunner.template

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
"2 vCPU 4 GB"
1919
],
2020
"Description": "Select CPU and Memory configuration"
21+
},
22+
"ContainerImageUri": {
23+
"Type": "String",
24+
"Description": "The ECR image URI for the App Runner service (e.g., 123456789012.dkr.ecr.us-east-1.amazonaws.com/swift-chat-api:latest)"
2125
}
2226
},
2327
"Resources": {
@@ -190,7 +194,54 @@
190194
{
191195
"Ref": "AWS::Region"
192196
},
193-
":366590864501:repository/swift-chat-api"
197+
":",
198+
{
199+
"Fn::Select": [
200+
0,
201+
{
202+
"Fn::Split": [
203+
".",
204+
{
205+
"Fn::Select": [
206+
0,
207+
{
208+
"Fn::Split": [
209+
"/",
210+
{
211+
"Ref": "ContainerImageUri"
212+
}
213+
]
214+
}
215+
]
216+
}
217+
]
218+
}
219+
]
220+
},
221+
":repository/",
222+
{
223+
"Fn::Select": [
224+
0,
225+
{
226+
"Fn::Split": [
227+
":",
228+
{
229+
"Fn::Select": [
230+
1,
231+
{
232+
"Fn::Split": [
233+
"/",
234+
{
235+
"Ref": "ContainerImageUri"
236+
}
237+
]
238+
}
239+
]
240+
}
241+
]
242+
}
243+
]
244+
}
194245
]
195246
]
196247
}
@@ -321,20 +372,7 @@
321372
]
322373
},
323374
"ImageIdentifier": {
324-
"Fn::Join": [
325-
"",
326-
[
327-
"366590864501.dkr.ecr.",
328-
{
329-
"Ref": "AWS::Region"
330-
},
331-
".",
332-
{
333-
"Ref": "AWS::URLSuffix"
334-
},
335-
"/swift-chat-api:latest-amd64"
336-
]
337-
]
375+
"Ref": "ContainerImageUri"
338376
},
339377
"ImageRepositoryType": "ECR"
340378
}

0 commit comments

Comments
 (0)