Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
611c3ac
Create Readme.md
Ayaan49 Sep 21, 2025
8988ec8
Create workflows
Ayaan49 Sep 21, 2025
625e1ac
Delete .github directory
Ayaan49 Sep 21, 2025
0fb39e1
Create main.yml
Ayaan49 Sep 21, 2025
a17ba74
Update main.yml
Ayaan49 Sep 21, 2025
eb38208
create sonarqube file
Sep 22, 2025
9180e4c
update wokrflows with sonarqube and snyk
Sep 22, 2025
ecf6b80
update sonar properties file
Sep 22, 2025
ea66ec3
Update sonar-project.properties
Ayaan49 Sep 23, 2025
37f9c51
Update Dockerfile
Ayaan49 Sep 23, 2025
1821477
Update Dockerfile
Ayaan49 Sep 23, 2025
d63d17b
Update Dockerfile
Ayaan49 Sep 23, 2025
49d552d
Update main.yml
Ayaan49 Sep 23, 2025
d1d2173
Update main.yml
Ayaan49 Sep 23, 2025
2d18e1d
Create docker-compose.yml
Ayaan49 Sep 24, 2025
d8073d3
Update main.yml
Ayaan49 Sep 24, 2025
2d30e58
Update main.yml
Ayaan49 Sep 24, 2025
1c89b88
Update main.yml
Ayaan49 Sep 24, 2025
bb760c3
Update main.yml
Ayaan49 Sep 24, 2025
c513b84
Update main.yml
Ayaan49 Sep 24, 2025
e3998a3
Update main.yml
Ayaan49 Sep 24, 2025
dc52f67
Update main.yml
Ayaan49 Sep 24, 2025
74214b6
Update main.yml
Ayaan49 Sep 24, 2025
e5e9614
Update main.yml
Ayaan49 Sep 24, 2025
323c3db
Update main.yml
Ayaan49 Sep 24, 2025
ad6a390
Update main.yml
Ayaan49 Sep 24, 2025
6476eea
Update main.yml
Ayaan49 Sep 24, 2025
ca817c3
Update main.yml
Ayaan49 Sep 24, 2025
e4509d0
Update main.yml
Ayaan49 Sep 24, 2025
2a4ce72
Update docker-compose.yml
Ayaan49 Sep 24, 2025
768ba7a
Update main.yml
Ayaan49 Sep 24, 2025
1e1cd1e
Update main.yml
Ayaan49 Sep 24, 2025
4ce3f31
Update docker-compose.yml
Ayaan49 Oct 3, 2025
b0ceaef
Update counter-app.py
Ayaan49 Oct 3, 2025
cd5ee56
Update main.yml
Ayaan49 Oct 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: Build and Push Docker image to AWS ECR

on:
push:
branches:
- development
paths-ignore:
- 'README.md'
jobs:
build-and-push:
runs-on: ubuntu-latest

steps:
- name: Check out the repo
uses: actions/checkout@v2
with:
fetch-depth: 0 # Necessary to fetch all tags and history

################################################################
### SONAR CLOUD SCAN ###
### Drops the build if any bugs or vulnerabilities are found.###
### Using the default quality gate. ###
### Connected to my personal Sonar Cloud account ###
################################################################

- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

- name: Setup Git
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@github.com'

################################################################
### DETERMINE NEXT VERSION ###
### Used for creating new releases and image tags ###
################################################################

- name: Determine Next Version
id: next_version
run: |
# Fetch all tags
git fetch --tags

# Get the latest tag, assume semver, and sort.
LATEST_TAG=$(git tag -l | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1)

# If there's no tag yet, start with v0.0.0. Used for new repos
if [ -z "$LATEST_TAG" ]; then
LATEST_TAG="v0.0.0"
fi

# Increment the patch version
NEXT_TAG=$(echo $LATEST_TAG | awk -F. '{print $1"."$2"."$3+1}')

# Output the next version
echo "::set-output name=tag::$NEXT_TAG"
echo "Next version: $NEXT_TAG"

################################################################
### CREATE RELEASE ###
### Creating release with the tag from the previous step ###
################################################################

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN_2 }}
with:
tag_name: ${{ steps.next_version.outputs.tag }}
release_name: Release ${{ steps.next_version.outputs.tag }}
draft: false
prerelease: false

################################################################
### BUILD DOCKER IMAGE ###
### Build Docker image from the Dockefile ###
################################################################

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Extract repository name
id: repo-name
run: |
REPO_NAME="${GITHUB_REPOSITORY##*/}"
echo "REPO_NAME=$REPO_NAME" >> $GITHUB_ENV
echo "::set-output name=repo_name::$REPO_NAME"

- name: Build Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.REPO_NAME }}
IMAGE_TAG: ${{ steps.next_version.outputs.tag }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
echo "IMAGE_NAME=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_ENV

###########################################################
### Docker image Snyk scan | If fails, drop the action ###
### Connected to my personal Snyk account ###
### The code owner receives an email notification ###
### Possible to configure Slack notification if needed ###
###########################################################

- name: Run Snyk to check Docker image for vulnerabilities
uses: snyk/actions/docker@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
image: ${{ env.IMAGE_NAME }}
args: --severity-threshold=high --policy-path=.snyk
continue-on-error: false

###########################################################
### PUSH IMAGE TO ECR ###
### Tag Docker image as "latest" and push to ECR ###
###########################################################

- name: Push Docker image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: py-aws-cicd
IMAGE_TAG: ${{ steps.next_version.outputs.tag }}
run: |
# Tag the image as latest
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
# Push the specific version tag
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
# Push the latest tag
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

- name: Deploy to EC2
env:
EC2_PEM_KEY: ${{ secrets.EC2_PEM_KEY }}
EC2_HOST: ${{ secrets.EC2_HOST }}
EC2_USER: ${{ secrets.EC2_USER }}
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: py-aws-cicd
IMAGE_TAG: ${{ steps.next_version.outputs.tag }}
run: |
# Save PEM key to file and set permissions
echo "$EC2_PEM_KEY" > ec2.pem
chmod 400 ec2.pem

# SSH, SCP commands
SSH_COMMAND="ssh -i ec2.pem -o StrictHostKeyChecking=no $EC2_USER@$EC2_HOST"
SCP_COMMAND="scp -i ec2.pem -o StrictHostKeyChecking=no"

#Login to Docker registry
$SSH_COMMAND "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY aws ecr get-login-password --region us-east-1 | sudo docker login --username AWS --password-stdin $ECR_REGISTRY"

# Create app dir if missing
$SSH_COMMAND "mkdir -p /home/$EC2_USER/docker/data"

# Copy docker-compose.yml to EC2 server
$SCP_COMMAND docker-compose.yml $EC2_USER@$EC2_HOST:/home/$EC2_USER/docker/

# Run compose with env vars injected into the remote shell
$SSH_COMMAND "cd /home/$EC2_USER/docker && \
sudo --preserve-env=ECR_REGISTRY,ECR_REPOSITORY,IMAGE_TAG \
env ECR_REGISTRY='$ECR_REGISTRY' \
ECR_REPOSITORY='$ECR_REPOSITORY' \
IMAGE_TAG='$IMAGE_TAG' \
docker compose up -d --pull always --force-recreate"

# Cleanup PEM key
rm -f ec2.pem

5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
ARG PYTHON_VERSION=3.12.8
FROM python:${PYTHON_VERSION}-alpine3.19 AS base
FROM python:${PYTHON_VERSION}-alpine3.21 AS base

# Make sure system packages are always up-to-date
RUN apk update && apk upgrade --no-cache

# Prevents Python from writing pyc files.
ENV PYTHONDONTWRITEBYTECODE=1
Expand Down
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a demo file
2 changes: 1 addition & 1 deletion counter-app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
app = Flask(__name__)

# Define the path for the counter file to store the data in Docker Volume
COUNTER_FILE = "data/counter.txt"
COUNTER_FILE = "/data/counter.txt"

def read_counter():
"""
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '2.4' # The last version of Docker Compose file format that directly supports mem_limit and cpus
services:
counter-service:
container_name: py-aws-cicd
image: "${ECR_REGISTRY}/${ECR_REPOSITORY}:${IMAGE_TAG}"
volumes:
- ./data:/data
ports:
- "80:8080"
restart: always
mem_limit: 256M
cpus: 0.6
18 changes: 18 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
sonar.projectKey=Ayaan49_py-aws-cicd
sonar.organization=ayaan49

# Display name and version in SonarCloud UI
sonar.projectName=py-aws-cicd
sonar.projectVersion=1.0

# Where your source code is (adjust if not in root)
sonar.sources=.

# Disable C/C++/Obj-C analysis (since this is Python)
sonar.c.file.suffixes=-
sonar.cpp.file.suffixes=-
sonar.objc.file.suffixes=-

# Encoding
# sonar.sourceEncoding=UTF-8

Loading