Aurapan is a women's clothing e-commerce website that features a fully operational microservices architecture. Built on the Next.js framework for the client-side, while the server-side is developed with TypeScript and Express framework, the website is developed on the Google Cloud Platform environment and integrated with automation testing through GitHub Action workflows. Deployed on a DigitalOcean cluster with a Let's Encrypt certificate, Aurapan delivers a secure and seamless shopping experience.
- Aurapan
- Table of contents
- Demo
- Features
- Usage
- Installation
- Setup Kubernetes Secret
- Deployment
- Technology
- Disclaimer
The Live demo is currently terminated due to the high-cost maintenance for paying Kubernetes cluster to host a microservices website. π
You can still run it manually with docker-desktop on your local machine.
Aurapan's features include:
-
A fully operational microservices-architecture website with user, product, order, payment, and expiration services completely separated.
-
All user, product, order, and payment data is stored in separate MongoDB collections.
-
User authentication secured by encrypting passwords using JWT and cookies.
-
A customer account settings dashboard to update profile information or see all orders.
-
An admin management dashboard with the authority to add, edit, and delete a product, user, or order.
-
Detailed product information with multiple options, such as color and size, displayed in a fashionable design with the Swiper library.
-
A full-featured shopping cart, including the ability to add, edit, and remove items.
-
A fully functional checkout process, including login, shipping address selection, and payment method selection.
-
Acceptance of both PayPal and Stripe integration payment methods.
-
Ability for an admin to mark orders as delivered.
-
The ability for customers to make product reviews and ratings with instant calculation of new ratings.
-
The ability to accept coupon promotions.
-
A cool navigation bar and breadcrumb for easy navigation.
-
Implementation of the Optimistic concurrency control concept with Mongoose to handle concurrency issues with event flow.
-
Optimization of Next.js features to maximize performance and quality in the Lighthouse report.
-
A safely secured HTTPS protocol with Let's Encrypt certificate.
-
Integration of Google Analytics 4 script to track significant events on the website.
This readme file provides an overview of the usage of the Aurapan website. Here are some instructions on how to use the website's features:
- To create an account, visit the signup page.
- Enter your email, password, name, gender, and age (these can be fictional since Aurapan is a fictional store).
- Use the following card number:
4242 4242 4242 4242
. - Use any future date for
MM/YY
. - Use any number for
CVC
.
- You will need a PayPal account.
- Create a PayPal developer account by visiting https://developer.paypal.com/tools/sandbox/accounts/.
- Choose the PayPal payment method and sign in with your sandbox account to pay for an order (with fake money).
- Only an admin can change an order status to
delivered
. - You will never receive any real products (even if your order has been marked as
delivered
). π
- To access the admin dashboard, sign in with an admin account.
- Access the dashboard through the management menu in the profile dropdown menu.
Unfortunately, this feature is not yet available on Aurapan. π
To perform CRUD operations on the product database, you need permission to access this function as an admin.
Follow these steps to run the project on Google Cloud Platform:
-
Clone the cloud branch to your local machine.
-
Sign up for a free account with $300 on GCP and create a Docker Hub account.
-
Run the
setup.sh
script by executing the following command in the root directory of this project:
source setup.sh
The script will prompt you to enter your Docker registry account name and will build and push the Docker images for each folder that contains a Dockerfile
.
-
Create a new project on GCP and enable Kubernetes Engine API and Cloud Build API. After successfully enabling API services, grant permission for the Cloud Build service account permission on Cloud Build API.
-
Create a new Kubernetes cluster with the minimum resource of 3 nodes (recommended) and select the region closest to your location.
-
Install GCP SDK to connect our images to the GCP cluster context. (Learn how to install Google Cloud SDK on macOS here)
-
Open the Google Cloud SDK and log in. Initiate and then choose the correct options to proceed by running the following commands:
gcloud auth login
gcloud init
- Create a Kubernetes context on your desktop by running this command (replace
<YOUR_CLUSTER_NAME>
with the name of the cluster you created on GCP):
gcloud container clusters get-credentials <YOUR_CLUSTER_NAME>
- See the list of contexts and then select a new context by running these commands:
kubectl config get-contexts
kubectl config use-context <CONTEXT_NAME>
-
Install ingress-nginx and ingress-nginx for GCP.
-
Find your load balancing port, which GCP automatically generated, in the Network Services tab in GCP.
-
For Windows users, open the host file at
C:\Windows\System32\drivers\etc\hosts
. For Mac users, open the host file at\etc\hosts
. Then, edit the file by addingYOUR_LOAD_BALANCING_PORT YOUR_CUSTOM_URL
and save as an administrator (e.g.,56.125.456.45 custom.com
). -
Configure all the YAML files to match your GCP project ID.
-
Create all Kubernetes secrets.
-
Run the following command and authenticate the GCP account via a web browser:
gcloud auth application-default login
- Ensure that you are using the correct context before running this command at the root directory:
skaffold dev
- Open a web browser and enter your custom URL with
https://
to see the project come to life
Please note that the setup.sh
script is designed to streamline the installation process by automatically building and pushing Docker images for each folder that contains a Dockerfile
. This helps simplify the steps required to set up the project on GCP.
Follow the below steps to run this project on Docker Desktop:
-
Clone the
dev
branch on your computer. -
Install the following software:
-
Enable Kubernetes in Docker Desktop preferences.
-
Run this script by executing the following command in the root directory of this project:
source setup.sh
The script will prompt you to enter your Docker registry account name and will build and push the Docker images for each folder that contains a Dockerfile
.
If you prefer to do it manually.
Run the following command in each folder that contains a Dockerfile
.
docker build -t <YOUR_DOCKER_ACCOUNT_NAME>/<CONTAINER_NAME> .
docker push <YOUR_DOCKER_ACCOUNT_NAME>/<CONTAINER_NAME>
- View the list of Kubernetes contexts and select a new context by running these commands:
kubectl config get-contexts
kubectl config use-context docker-desktop
-
Install ingress-nginx and enable Kubernetes in Docker Desktop software. (choose don't have Helm version)
-
For Windows users, open the host file at
C:\Windows\System32\drivers\etc\hosts
. For Mac users, open the host file at/etc/hosts
. Then, add127.0.0.1 YOUR_CUSTOM_URL
and save the file as an admin. For example,127.0.0.1 custom.com
. -
Configure the
infra/k8s-dev/ingress-srv.yaml
file at line 10 to be your custom URL. (ex. mywebsite.com) -
Create all Kubernetes secrets.
-
Run this script in the root directory of this project, and make sure to use the correct context before running the command.
skaffold dev
- Open a web browser and enter your custom URL with
https://
to see this project come to life!
Please note that the setup.sh
script is designed to streamline the installation process by automatically building and pushing Docker images for each folder that contains a Dockerfile
. This helps simplify the steps required to set up the project on Docker Desktop.
Create all these Kubernetes secrets in the Kubernetes context:
MONGO_URI_USER, MONGO_URI_PRODUCT, MONGO_URI_ORDER, MONGO_URI_PAYMENT : MongoDB
kubectl create secret generic mongo-secret \
"--from-literal=MONGO_URI_PRODUCT=<YOUR_MONGO_DB_URI>" \
"--from-literal=MONGO_URI_USER=<YOUR_MONGO_DB_URI>" \
"--from-literal=MONGO_URI_ORDER=<YOUR_MONGO_DB_URI>" \
"--from-literal=MONGO_URI_PAYMENT=<YOUR_MONGO_DB_URI>"
Example for YOUR_MONGO_DB_URI: mongodb+srv://admin:<password>@aurapan.ygmpl.mongodb.net/<your_database_name>?retryWrites=true&w=majority
JWT_KEY : --whatever you want--
kubectl create secret generic jwt-secret --from-literal=JWT_KEY=<YOUR SECRET>
STRIPE_KEY : Stripe
kubectl create secret generic stripe-secret --from-literal=STRIPE_KEY=<YOUR_STRIPE_KEY>
PAYPAL_CLIENT_ID : Paypal
kubectl create secret generic paypal-secret --from-literal=PAYPAL_CLIENT_ID=<YOUR_PAYPAL_CLIENT_ID>
-
sign up a free account with a $200 for 60 days trial and create a Kubernetes cluster in a new project on Digital Ocean
-
generate a new access token on Digital Ocean to connect with Digital Ocean via doctl, go to the API menu then click generate a new token, set expiration date and enable both read and write scopes, copy the token code for use in the next step
doctl auth init --access-token <API_TOKEN_CODE>
- connect with Digital Ocean k8s cluster context by running this command and authorize with your credentials
doctl kubernetes cluster kubeconfig save <YOUR_CLUSTER_NAME>
- switch Kubernetes context to the new context by running
kubectl config use-context <CONTEXT_NAME>
-
setup all Kubernetes secrets following this step
-
create _GitHub workflow for building an initial docker image on push event at the main branch and perform automated testing in every service on pull request event trigger with trying to merge with the main branch
name: deploy-client
on:
push:
# watch for pull request into main branch
branches:
- main
# watch for changes in client folder
paths:
- "client/**"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# build an image
- run: cd client && docker build -t <YOUR_ACCOUNT_NAME>/<YOUR_IMAGE_NAME> .
# login on docker hub
- run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
# push an image to docker hub
- run: docker push <YOUR_ACCOUNT_NAME>/<YOUR_IMAGE_NAME>
-
generate another new access token on Digital Ocean for authentication via GitHub Action, go to the API menu then click generate a new token, set expiration date and enable both read and write scopes, copy the token code for use in the next step as a
DIGITALOCEAN_ACCESS_TOKEN
-
add GitHub action secrets for docker credentials and digitalocean access token key at the security setting in the repository
DIGITALOCEAN_ACCESS_TOKEN =
DOCKER_USERNAME =
DOCKER_PASSWORD =
-
edit files in every service then commit code to the main branch for triggering Github Action workflows to build and push all images to your Docker Hub
-
install ingress-nginx to automatically create DigitalOcean Load Balancer
-
separate k8s folder to k8s-dev and k8s-prod then copy
ingress-srv.yaml
file to both folders and edit the host URL to a new domain name -
create a GitHub workflow for telling the Kubernetes cluster to use images we built by adding these lines
- uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- run: doctl kubernetes cluster kubeconfig save <YOUR_CLUSTER_NAME>
- run: kubectl rollout restart deployment <YOUR_DEPLOYMENT_NAME>
-
purchase a domain name with a promotion that can be very cheap as $1 for the 1st year such as Namecheap, Porkbun, or Dynadot
-
config custom domain name nameserver with your domain name registration website by custom adding these lines
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
- add a domain name in the Digital Ocean at networking tab then create a new record
// A record
HOSTNAME: @
WILL DIRECT TO: <YOUR_LOAD_BALANCER>
TTL: 30
// CNAME record
HOSTNAME: www
IN AN ALIAS OF: @
TTL: 30
- add your cluster name at
deploy-manifests.yaml
file then redo step 7. again
name: deploy-manifests
on:
push:
# watch for pull request into main branch
branches:
- main
# watch for changes in infra folder
paths:
- "infra/**"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# use and cliententicate doctl
- uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
# use and cliententicate doctl
- run: doctl kubernetes cluster kubeconfig save <YOUR_CLUSTER_NAME>
# apply deployment yaml files (k8s-prod is for production!)
- run: kubectl apply -f infra/k8s && kubectl apply -f infra/k8s-prod
-
change
do-loadbalancer-hostname
andhost
at fileinfra/k8s-prod/ingress-srv.yaml
to your domain name -
change the URL in
client/api/build-client.js
to your domain name -
after that, we will follow step 4 of this guide How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes to make our website ready for HTTPS requests with the certificate issued by Let's encrypt
-
begin with installing the cert-manager namespace by running the command
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml
- change your directory to
infra/issuer/
there will be 2 files that you need to change the email and name of a secret key as you wish then run the command
kubectl create -f staging_issuer.yaml
kubectl create -f production_issuer.yaml
- at file
infra/k8s-prod/ingress-srv.yaml
change cert-manager.io/cluster-issuer to"letsencrypt-staging"
then run this command atinfra/k8s-prod/
directory
kubectl apply -f ingress-srv.yaml
- then change cert-manager.io/cluster-issuer back to
"letsencrypt-prod"
and run this command atinfra/k8s-prod/
directory
kubectl apply -f ingress-srv.yaml
- waiting around 2-15 minutes for setting up then browse your website with HTTPS protocol
This project is built using the following technologies:
- Next.js
- TypeScript
- React-Bootstrap
- MongoDB
- Docker
- Kubernetes
- Github Action
- NATS Streaming Server
- Skaffold
- NPM package
All images used in this project are for educational purposes only. π