Full-stack web app that stores workout routines for users, applying DevOps tools for deployment and infrastructure management
- Front End
- react.js
- next.js
- Tailwind CSS
- Shadcn
- Lucide
- react.js
- Back End
- node.js
- PostgreSQL
- CI/CD
- Github Actions
- Docker
- Docker Compose
- Terraform
- AWS
- EC2
- RDS
- VPC
- ECR
- Route 53
- Compute: EC2 t3.micro instance with Docker and Docker Compose
- Database: RDS PostgreSQL
- Networking: Custom VPC
- Container Registry: ECR repository
- DNS Management: Route53 zone for domain (pesodevops.com)
- Security: IAM roles and policies for EC2 to access ECR
- Secrets Management: AWS Secrets Manager for securely storing environment variables
- Dockerfile for Next.js
- Dockerfile for Nginx
Automated deployment pipeline triggered on pushes to main branch:
- CI
- test and lint next.js application
- build and push docker image to ecr
- checkout code from repository
- configure aws credentials for ecr access
- login to aws ecr
- build and tag docker image for next.js app
- build and tag docker image for nginx
- push both docker images to ecr
- CD
- deploy latest docker images on ec2 instance
- ssh into ec2
- pull latest container images from ecr
- remove existing
docker-compose.ymlfile on ec2 - copy new
docker-compose.ymlto ec2 instance - stop and remove running application with
docker-compose down - clean up old images with
docker image prune -f - restart application with
docker-compose up -d
- deploy latest docker images on ec2 instance
- choose auth provider
- install and setup auth.js
- setup Google OAuth provider
- setup GitHub OAuth provider
- define database schema
- setup postgresql database schema with goose
- sign up page
- log in page
- add log in and sign out buttons in layout
- block unauthorized users from accessing pages that require authentication
- api post exercise
- api get exercises
- api put exercise
- api delete exercise
- test api endpoints with curl
- create exercise page
- component exercises list
- create exercise button
- delete exercise button
- edit exercise button
- api post workout
- exercises search box
- add exercise to workout
- remove exercise from workout
- api get workouts
- api put workout
- delete exercise from current workout
- change exercise order from workout
- api delete workout
- test api endpoints with curl
- workout components
- workout list
- form to create and edit workout
- search form to find exercise that will be added to workout
- workout page
- dockerfile to run application
- add tests
- add lint GitHub Actions workflow
- add workflow to run tests
- add workflow to build and push docker image to aws ecr
- define env vars to create infrastructure
- setup terraform file for aws IaC
- ec2 instance (don't forget to create it with a key-pair)
- install docker and docker-compose
- vpc
- gateway
- security groups
- rds database
- ecr
- IAM policies
- terraform plan and apply
- ec2 instance (don't forget to create it with a key-pair)
- implement dockerfile to build and run application
- implement github actions workflow to build and push docker image to ecr
- workflow to build and push docker image to aws ecr
- workflow to deploy server in ec2
- implement database schema on rds
- get access ec2
- configure ec2
- install docker on ec2:
sudo apt update && sudo apt -y install docker.io - start docker service on ec2:
sudo service docker start - access rds database:
psql -h host_url.region.rds.amazonaws.com -U myuser -d db_name -p db_port(creates database if it doesn't exist) - add user_data in terraform to quickly setup new ec2 instance
- install docker on ec2:
- apply schema in rds with goose using .env vars (easier to use credentials safely)
- run database migrations with Goose
- implement
nginx.confwith the following requirements:- reverse proxy for next.js full-stack dynamic web app that connects to an rds postgresql database
- update domain's DNS record to point to ip address where app is hosted (ec2's docker container)
- pass env vars to aws parameter store or secrets manager in terraform file (without hardcoding them)
- implement Dockerfile to run the application and nginx
- add iam policy to give ec2 intance access to aws secrets manager variables
- create policy
- attach policy to iam role (if one already exists, if not make a new one)
- add role to ec2
- verify if ec2 has access to parameter store
- make nginx + next.js deployment work locally
- register domain in route 53 (pesodevops.com)
- workflow pushes container images to ecr repo
- fix google authentication not redirecting back to application after login
- deploy app in ec2 instance without ssl certificates
- deploy app in ec2 instance with ssl certificates
- docker pull from ecr
- add security groups and credentials to allow pull
aws ecr get-login-password --region sa-east-1 | docker login --username AWS --password-stdin 072216710152.dkr.ecr.sa-east-1.amazonaws.com
- make registered domain point to your ec2 instance's public ip
- add records to the hosted zone
- records contain information about how to route traffic for your domain and any subdomains
- docker-compose for local development environment
- setup ec2 t3.small
- make domain point to ec2
- configure google oauth
- set up cert-manager in nginx container
- fix google authorized redirect uris
- deploy on ec2 with ssh
- deploy on ec2 with docker-compose
- sets up next.js app using ecr image
- sets up nginx as reverse proxy the next.js servers
- make nginx + next.js deployment work in the cloud
- make nginx/docker-compose setup ssl certificates automatically
- deploy app with github actions only
- add ci/cd badge
- style profile page with tailwind
- add exercises by users
- add stock image as background in home page
- add browser icon
- add layout buttons for mobile screens
- how do i block a page from unauthorized users in next.js?
- if you're using auth.js for authentication:
- front end:
useSession(),if (!session) { redirect("/api/auth/signin?callbackUrl=/exercises"); } - back end: wrap api function for a specific http verb (e.g.
PUT,GET, etc) withauth()- e.g.
export const POST = auth(async function POST(req: Request)
- e.g.
- front end:
- if you're using auth.js for authentication:
- what is the directory structure for components?
- everything is explained in next.js docs
- my explanation
- how do i setup terraform for aws?
- how do i store credentials/secrets safely?
- store env vars in aws secrets manager
- export aws credentials:
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY - run
terraform initin project's root directory - implement main.tf with desired aws resources
terraform plan -var-file="terraform.tfvars" -out=tfplanterraform apply tfplan
- how do i store credentials/secrets safely?
- how do i give access between rds and ec2?
- security groups define which traffic is allowed between aws resources
- ec2 will also need credentials (connection string) to make requests to rds
- how much should i know about policies?
- basic structure of the configuration file
- ID
- statements
- effect
- actions
- conditions
- how do i configure nginx?
- implement basic nginx.conf and a Dockerfile that will run nginx
- do i need to use two container images?
- yes, one image for next.js and another to run nginx
- how do i start nginx inside ec2's docker container? docker compose
- how do i run migrations in rds?
- add your computer to the ingress rules
- connect to postgresql database using
psqlwith credentials - migrate with goose
- where do i store each credential? (e.g. aws secrets manager, github secrets, my own computer)
- NEVER in github repo
- aws credentials
- database credentials
- google auth credentials
- ec2 setup
- don't forget to configure security groups in terraform file
- install aws cli, docker, docker compose
- is aws internet gateway necessary for architecture? connects my vpc to the public internet
- allows vpc to send and receive traffic from the internet
- it must be attached to the vpc
- route tables must explicitly route traffic through it
- route table: set of rules that control how network traffic leaves or enters a subnet inside vpc
- how do i get ssl certificate? use certbot
- should i scp to copy my .env vars to ec2 instance or use aws secrets manager?
- aws secrets manager is safer
- should i use nginx or other aws service to serve as reverse-proxy with my deployment? nginx container
- what is the purpuse of
certbot/wwwandcertbot/confdirectory?certbot/www: temporary challenge files for domain verification- what are challenge files?
- temporary verification files that certbot creates to prove that you own a domain before issuing an SSL certificate
- when certbot needs to prove domain ownership, it places challenge files inside this directory
- what are challenge files?
certbot/conf: stores certbot’s configuration- stores SSL certificates and renewal settings
- after a certificate is issued, the private key, full chain and other related files are stored here
- when the certificate needs renewal, certbot updates this directory
- how frequently should i renew certificate?
- Let's Encrypt certificates are valid for 90 days
- it's recommended to renew them each 60 days
- which ec2 base image should i use? (maybe create container image for it and store in IAM)
- OS: Ubuntu
- how do i obtain ssl certificate for nginx?
certbot - how do i register a domain (pesodevops.com)?
- route 53
- register domain
- set hosted zones to point to registered domain
- can i do it with only terraform?
- it's better to register the domain with aws console
- define records within terraform
- after pushing docker image to ecr, how does ec2 pull it?
aws ecr get-login-password --region sa-east-1 | docker login --username AWS --password-stdin [AWS_ACCOUNT_ID].dkr.ecr.sa-east-1.amazonaws.com- how long does this authentication last? 12 hours
- does it work inside ec2 instance? how?
- yes, because i attached an iam role to the ec2 instance with permissions allowing to pull from ecr
- how should i add my .env to aws secrets manager? terraform variables in
terraform.tfvarsthat are initialized inmain.tf - how do i create a domain for my website? register desired domain with aws route 53