AWS Cluster
Setting up AWS (EC2 instance)
- Sign in AWS Console
- Note: Account ID = 2131-5779-2220
- Search up EC2 (Virtual Servers in the Cloud) in the university search bar
- Launch EC2 instance, click “Launch Instance”
- Quick Start: Pick “Ubuntu” as the AMI = Amazon Machine Image (AMI)
- Select
t3.microas the Instance type (Free tier eligible) (on-demand ubuntu is 0.0167 USD per hour) - Configure ssh keypair:
- Key pair name: dev01
- Key pair type: RSA
- Private key format: .pem (don’t use .ppk la)
- Network Settings
- SSH: port 22 (allow IP for remote access from anywhere)
- HTTPS: port 80 (allow IP for remote access from anywhere)
- HTTP: port 443 (allow IP for remote access from anywhere)
- Quick summary:
- CreateSecurityGroup
aws ec2 create-security-group --group-name 'launch-wizard-1' --description 'launch-wizard-1 created 2025-11-29T14:35:47.187Z' --vpc-id 'vpc-0c539c8b10866e84d'
- AuthorizeSecurityGroupIngress
aws ec2 authorize-security-group-ingress --group-id 'sg-preview-1' --ip-permissions '{"IpProtocol":"tcp","FromPort":22,"ToPort":22,"IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"IpProtocol":"tcp","FromPort":443,"ToPort":443,"IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"IpProtocol":"tcp","FromPort":80,"ToPort":80,"IpRanges":[{"CidrIp":"0.0.0.0/0"}]}'
- RunInstances
aws ec2 run-instances --image-id 'ami-0b8d527345fdace59' --instance-type 't3.micro' --key-name 'dev01' --block-device-mappings '{"DeviceName":"/dev/sda1","Ebs":{"Encrypted":false,"DeleteOnTermination":true,"Iops":3000,"SnapshotId":"snap-01a53aa4eb0c4589e","VolumeSize":8,"VolumeType":"gp3","Throughput":125}}' --network-interfaces '{"AssociatePublicIpAddress":true,"DeviceIndex":0,"Groups":["sg-preview-1"]}' --credit-specification '{"CpuCredits":"unlimited"}' --metadata-options '{"HttpEndpoint":"enabled","HttpPutResponseHopLimit":2,"HttpTokens":"required"}' --private-dns-name-options '{"HostnameType":"ip-name","EnableResourceNameDnsARecord":true,"EnableResourceNameDnsAAAARecord":false}' --count '1'
- CreateSecurityGroup
- Quick summary:
- Launch instnace button –> Success: Successfully initiated launch of instance (i-039f8736dffa921f5)
Setting up SSH access
- the .pem private key is added to
the-docsrepo LOCALLY - Go back to the Insatnce page and retrive the
Public IPv4 address - Resolve .pem key permission by
chmod 600 dev01.pem- permission originally:
0644- Owner (you) have ability to read + write
- Group: read only
- others: read only
- permission now:
0600: OpenSSH on the server side strictly requires that the private key is not readable or writable by group or others- Owner (you) have ability to read + write
- Group: NOTHING
- others: NOTHING
- permission originally:
- Connect via:
ssh -i dev01.pem ubuntu@3.25.177.133. Done.
Setting up CICD for EC2 deployment
- I am NOT using
git clone…wtf… - Instead of using the personal
dev01.pemkey, Create a new deploy key !- Do this on your local machine
ssh-keygen -t ed25519 -C "github-actions-deploy@myproject" -f deploy_key -N ""
- Do this on your local machine
- Add the public key to your EC2 instance
cat deploy_key.pub | ssh -i dev01.pem ubuntu@3.25.177.133 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod chmod 600 ~/.ssh/authorized_keys"- I see that
authorized_keydir in EC2 is already600 - Proof:
ubuntu@ip-172-31-24-205:~$ ls -altr ~/.ssh/ total 12 drwx------ 2 ubuntu ubuntu 4096 Nov 29 14:54 . drwxr-x--- 4 ubuntu ubuntu 4096 Nov 29 18:31 .. -rw------- 1 ubuntu ubuntu 500 Nov 29 18:34 authorized_keys
Add the
deploy_key(the private one) to the Github Organization’s secrets- Ensure you have ansible installed on your dev machine locally.
- If not follow these steps:
- Step 1: Create ansible sub-dirs:
mkdir -p fastapi-deploy/{group_vars,inventory,roles}&&cd fastapi-deploy - Step 2: Install ansible via pip
python3 -m pip install --user ansible - Step 3: Set up the items to be installed onto EC2 using ansible found under the
ansible/directory
- Step 1: Create ansible sub-dirs:
- If not follow these steps:
Setup your dockerfile
setup your main.py for source code
setup your requirements.txt
And commit the following code to the main branch
name: Deploy FastAPI on: push: branches: [ main, dev ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Write SSH deploy key run: | mkdir -p ~/.ssh echo "${{ secrets.DEPLOY_KEY_DEV }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key echo -e "Host ${{ vars.DEPLOY_HOST_DEV }}\n HostName ${{ vars.DEPLOY_HOST_DEV }}\n User ${{ vars.DEPLOY_USER_DEV || 'ubuntu' }}\n IdentityFile ~/.ssh/deploy_key\n StrictHostKeyChecking no" >> ~/.ssh/config - name: Currently NOT IN USE - Login to Docker Hub (optional) if: env.DOCKERHUB_USERNAME uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build → Stream → Deploy to EC2 (zero registry, zero downtime) env: HOST: ${{ vars.DEPLOY_HOST_DEV }} USER: ${{ vars.DEPLOY_USER_DEV }} DEBUG_TOKEN: ${{ secrets.JWT_DEV_TOKEN }} SUPABASE_URL: ${{ vars.DEV_SUPABASE_URL }} run: | set -euo pipefail echo "Building Docker image..." docker buildx create --use --name mybuilder || true docker buildx build --load --platform linux/amd64 -t myfastapi:latest . echo "Deploying to ${HOST}..." docker save myfastapi:latest | gzip | ssh -i ~/.ssh/deploy_key \ -o StrictHostKeyChecking=no \ -o ServerAliveInterval=60 \ -o LogLevel=ERROR \ ${USER}@${HOST} \ "gunzip | docker load && \ docker rm -f fastapi || true && \ docker run -d \ --name fastapi \ --restart unless-stopped \ -p 127.0.0.1:8000:8000 \ -e DEBUG_TOKEN='${DEBUG_TOKEN}' \ -e SUPABASE_URL='${SUPABASE_URL}' \ myfastapi:latest \ uvicorn src.main:app --host 0.0.0.0 --port 8000 && \ echo 'DEPLOYED SUCCESSFULLY! Open http://${HOST} now' && \ echo 'Swagger: http://${HOST}/docs'" echo "" echo "LIVE → http://${HOST}" echo "Docs → http://${HOST}/docs"
Set up auth flow with supabase.com
- Head over to superbase, signed up with Github Auth –> create new org
- Password for Supabase –> **** (for PosgreDB access)
- Copy down also these 2 vars from the superbase:
anonkey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl3Z2pua2p0d2F4Y3NwYWhsa2lrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQ0NzE4NDksImV4cCI6MjA4MDA0Nzg0OX0.LDc08qC9o1keOCFKZw0oLkUamblGhCiQgHRGaoFEw30superbase_url: ‘https://ywgjnkjtwaxcspahlkik.supabase.co’