Publish image for 05-assistive-chatbot #71
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "Build and push Docker image" | |
run-name: "Publish image for ${{inputs.dockerfile_folder}}" | |
on: | |
workflow_dispatch: | |
inputs: | |
dockerfile_folder: | |
description: 'Folder containing Dockerfile to build' | |
required: true | |
type: choice | |
options: | |
- '05-assistive-chatbot' | |
- '02-household-queries' | |
service_name: | |
description: 'Name of target AWS service.' | |
type: choice | |
default: 'container-service-2' | |
options: | |
- 'container-service-3' | |
- 'container-service-2' | |
- 'chatbot-chainlit-svc' | |
- 'secure-chatbot-svc' | |
- '' | |
build_image: | |
description: "Build and push image" | |
required: true | |
type: boolean | |
default: 'true' | |
deploy_image: | |
description: "Deploy image" | |
required: true | |
type: boolean | |
default: 'false' | |
# image_tag: | |
# description: 'Tag/Version of the image to push' | |
# required: true | |
# type: string | |
# default: '0.06' | |
create_new_svc: | |
description: "Create new Lightsail service" | |
required: true | |
type: boolean | |
default: 'false' | |
delete_images: | |
description: 'Delete previous images in AWS Lightsail' | |
required: true | |
type: boolean | |
default: 'false' | |
env: | |
AWS_REGION: us-east-1 | |
IMAGE_NAME: localimage | |
jobs: | |
publish-image: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check inputs | |
id: check_inputs | |
run: | | |
service_name="${{ inputs.service_name }}" | |
if [ "${service_name}" = "" ]; then | |
case "${{ inputs.dockerfile_folder }}" in | |
'02-household-queries') service_name='secure-chatbot-svc';; | |
'05-assistive-chatbot') service_name='chatbot-chainlit-svc';; | |
*) echo "Unknown dockerfile_folder: '${dockerfile_folder}'"; exit 2;; | |
esac | |
fi | |
echo "service_name=$service_name" >> $GITHUB_OUTPUT | |
# TODO: check if service_name exists | |
image_tag="${{ inputs.image_tag }}" | |
if [ "${image_tag}" = "" ]; then | |
case "${service_name}" in | |
# The image_tag is specific to the `*-svc` service | |
'secure-chatbot-svc') image_tag='0.01';; | |
'chatbot-chainlit-svc') image_tag='chatbot-chainlit';; | |
container-service-*) image_tag='not-used';; | |
*) echo "Unknown service_name: '${service_name}'"; exit 3;; | |
esac | |
fi | |
echo "image_tag=$image_tag" >> $GITHUB_OUTPUT | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: ${{ env.AWS_REGION }} | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
mask-aws-account-id: true | |
# TODO: secure credentials: https://github.com/aws-actions/amazon-ecr-login?tab=readme-ov-file#ecr-private | |
# https://github.com/docker/login-action?tab=readme-ov-file#aws-elastic-container-registry-ecr | |
# https://medium.com/@lukhee/automating-aws-lightsail-deployments-with-github-actions-53c73c9a1c1f | |
- name: "Upgrade AWS CLI version and setup lightsailctl" | |
run: | | |
# aws --version | |
# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" | |
# unzip awscliv2.zip | |
# sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update | |
# which aws | |
aws --version | |
sudo curl "https://s3.us-west-2.amazonaws.com/lightsailctl/latest/linux-amd64/lightsailctl" -o "/usr/local/bin/lightsailctl" | |
sudo chmod +x /usr/local/bin/lightsailctl | |
aws lightsail push-container-image help | |
- name: "Create new Lightsail container service" | |
if: inputs.create_new_svc | |
env: | |
SERVICE_NAME: ${{ steps.check_inputs.outputs.service_name }} | |
run: | | |
SERVICE_NAME=$SUBDOMAIN-csvc | |
aws lightsail create-container-service --service-name $SERVICE_NAME --power micro --scale 1 --public-domain-names navalabs-cert=$SUBDOMAIN.navalabs.co | |
# TODO: wait for service to be "READY" before updating | |
# TODO: update DNS assignment and service's custom domain | |
- name: "Delete previous container images" | |
if: inputs.delete_images | |
env: | |
SERVICE_NAME: ${{ steps.check_inputs.outputs.service_name }} | |
run: | | |
AWS_IMAGES=$(aws lightsail get-container-images --region "$AWS_REGION" --service-name "$SERVICE_NAME" --output text) | |
IMAGE_NAMES=$(echo $AWS_IMAGES | grep -Eo ':"$SERVICE_NAME"\.${{ inputs.image-name }}\.[0-9]+') | |
echo $IMAGE_NAMES | |
FIRST=0 | |
while read LINE; do | |
if [ "$FIRST" -ne 0 ]; then | |
aws lightsail delete-container-image --region "$AWS_REGION" --service-name "$SERVICE_NAME" --image $LINE; | |
fi | |
FIRST=1; | |
done <<< $IMAGE_NAMES | |
- name: "Login to Amazon ECR" | |
id: login-ecr | |
uses: aws-actions/amazon-ecr-login@v2 | |
with: | |
mask-password: true | |
- name: "Checkout source code" | |
if: inputs.build_image | |
uses: actions/checkout@v4 | |
- name: "Build image" | |
if: inputs.build_image | |
run: | | |
cd ${{ inputs.dockerfile_folder }} | |
# TODO: make this more easily editable and secure | |
# The DOT_ENV_FILE_CONTENTS contains LITERAL_API_KEY, OPENAI_API_KEY, RETRIEVE_K, LLM_MODEL_NAME, SUMMARIZER_LLM_MODEL_NAME | |
echo "${{secrets.DOT_ENV_FILE_CONTENTS}}" > .env | |
echo "BUILD_DATE=$(date +%Y-%m-%d-%T)" >> .env | |
echo "GIT_SHA=${{ github.sha }}" >> .env | |
docker build -t "$IMAGE_NAME" --build-arg GURU_CARDS_URL="https://docs.google.com/uc?export=download&id=${{ secrets.GURU_CARDS_URL_ID }}" . | |
- name: "Publish image to Lightsail" | |
if: inputs.build_image | |
id: pub_image_to_ls | |
env: | |
ECR_PATH: ${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPO }} | |
SERVICE_NAME: ${{ steps.check_inputs.outputs.service_name }} | |
IMAGE_TAG: ${{ steps.check_inputs.outputs.image_tag }} | |
# LABEL must match regex ^(?:[a-z0-9]{1,2}|[a-z0-9][a-z0-9-]+[a-z0-9])$ | |
LABEL: git-push | |
IMAGE_SHA_TAG: ${{ github.sha }} | |
run: | | |
echo "# Publishing image for $SERVICE_NAME" | |
aws lightsail push-container-image --region $AWS_REGION --service-name "$SERVICE_NAME" --label "$LABEL" --image "$IMAGE_NAME" | |
LS_DOCKER_IMAGE=$(aws lightsail get-container-images --service-name "$SERVICE_NAME" | jq -r .containerImages[0].image) | |
echo "Image name: '$LS_DOCKER_IMAGE'" | |
echo "LS_DOCKER_IMAGE='$LS_DOCKER_IMAGE'" >> $GITHUB_ENV | |
- name: Deploy container on AWS Lightsail | |
if: inputs.deploy_image | |
env: | |
SERVICE_NAME: ${{ steps.check_inputs.outputs.service_name }} | |
run: | | |
TEMPLATE='{ | |
"serviceName": "$SERVICE_NAME", | |
"containers": { | |
"chatbot": { | |
"image": "$LS_DOCKER_IMAGE", | |
"command": [], | |
"environment": { | |
"ENV": "PROD", | |
"BUILD_DATE": "$BUILD_DATE" | |
}, | |
"ports": { | |
"8000": "HTTP" | |
} | |
} | |
}, | |
"publicEndpoint": { | |
"containerName": "chatbot", | |
"containerPort": 8000, | |
"healthCheck": { | |
"healthyThreshold": 2, | |
"unhealthyThreshold": 4, | |
"timeoutSeconds": 20, | |
"intervalSeconds": 60, | |
"path": "/healthcheck", | |
"successCodes": "200-499" | |
} | |
} | |
}' | |
echo "$TEMPLATE" | BUILD_DATE=$(date +%Y-%m-%d-%T) envsubst > config.json | |
cat config.json | |
aws lightsail create-container-service-deployment --cli-input-json file://config.json | |
# aws lightsail create-container-service-deployment --region ${{ inputs.aws-region }} --cli-input-json '${{ inputs.aws-lightsail-service-config }}' > /dev/null | |
# aws lightsail update-container-service --service-name "$SERVICE_NAME" --no-is-disabled | |
# - name: "Update AWS Service" | |
# if: inputs.deploy_image | |
# env: | |
# CLUSTER_NAME: genai-experiments | |
# run: | | |
# aws ecs update-service --force-new-deployment --cluster "$CLUSTER_NAME" --service "${{ steps.check_inputs.outputs.service_name }}" |