Skip to content

Commit

Permalink
Production 1.1.0 (#120)
Browse files Browse the repository at this point in the history
  • Loading branch information
MinhhTien authored Jun 19, 2024
2 parents a38c5f0 + a40e131 commit 9b399d1
Show file tree
Hide file tree
Showing 164 changed files with 12,740 additions and 686 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/dist
107 changes: 107 additions & 0 deletions .github/workflows/develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: NestJS CI/CD

on:
push:
branches: ['develop']
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
tags:
description: 'Test scenario tags'
required: false
type: boolean
environment:
description: 'Environment to run tests against'
type: environment
required: true

jobs:
build:
runs-on: self-hosted
environment: develop
strategy:
matrix:
node-version: [20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install
run: npm install
- name: Build
run: npm run build
- name: Update sentry sourcemaps
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
continue-on-error: true
run: npm run sentry:sourcemaps
- name: 'Create env file'
run: |
touch .env
echo NODE_ENV=${{ vars.NODE_ENV }} >> .env
echo PORT=${{ vars.PORT }} >> .env
echo MONGODB_CONNECTION_STRING=${{ secrets.MONGODB_CONNECTION_STRING }} >> .env
echo CORS_VALID_ORIGINS=${{ vars.CORS_VALID_ORIGINS }} >> .env
echo JWT_ACCESS_SECRET=${{ vars.JWT_ACCESS_SECRET }} >> .env
echo JWT_ACCESS_EXPIRATION=${{ vars.JWT_ACCESS_EXPIRATION }} >> .env
echo JWT_REFRESH_SECRET=${{ vars.JWT_REFRESH_SECRET }} >> .env
echo JWT_REFRESH_EXPIRATION=${{ vars.JWT_REFRESH_EXPIRATION }} >> .env
echo SMTP_USERNAME=${{ secrets.SMTP_USERNAME }} >> .env
echo SMTP_PASSWORD=${{ secrets.SMTP_PASSWORD }} >> .env
echo SMTP_HOST=${{ vars.SMTP_HOST }} >> .env
echo SMTP_PORT=${{ vars.SMTP_PORT }} >> .env
echo SMTP_FROM_EMAIL=${{ vars.SMTP_FROM_EMAIL }} >> .env
echo SMTP_FROM_NAME=${{ vars.SMTP_FROM_NAME }} >> .env
echo WEB_URL=${{ vars.WEB_URL }} >> .env
echo SERVER_URL=${{ vars.SERVER_URL }} >> .env
echo MOMO_PARTNER_CODE=${{ secrets.MOMO_PARTNER_CODE }} >> .env
echo MOMO_ACCESS_KEY=${{ secrets.MOMO_ACCESS_KEY }} >> .env
echo MOMO_SECRET_KEY=${{ secrets.MOMO_SECRET_KEY }} >> .env
echo MOMO_ENDPOINT=${{ vars.MOMO_ENDPOINT }} >> .env
echo PAYOS_CLIENT_ID=${{ secrets.PAYOS_CLIENT_ID }} >> .env
echo PAYOS_API_KEY=${{ secrets.PAYOS_API_KEY }} >> .env
echo PAYOS_CHECKSUM_KEY=${{ secrets.PAYOS_CHECKSUM_KEY }} >> .env
echo ZALOPAY_APP_ID=${{ secrets.ZALOPAY_APP_ID }} >> .env
echo ZALOPAY_KEY1=${{ secrets.ZALOPAY_KEY1 }} >> .env
echo ZALOPAY_KEY2=${{ secrets.ZALOPAY_KEY2 }} >> .env
echo ZALOPAY_ENDPOINT=${{ vars.ZALOPAY_ENDPOINT }} >> .env
echo SENTRY_DSN=${{ secrets.SENTRY_DSN }} >> .env
echo DISCORD_WEBHOOK_ID=${{ secrets.DISCORD_WEBHOOK_ID }} >> .env
echo DISCORD_WEBHOOK_TOKEN=${{ secrets.DISCORD_WEBHOOK_TOKEN }} >> .env
echo TRIPO_3D_AI_ENDPOINT=${{ vars.TRIPO_3D_AI_ENDPOINT }} >> .env
echo EDEN_AI_ENDPOINT=${{ vars.EDEN_AI_ENDPOINT }} >> .env
- name: Deploy
run: pm2 restart furnique-api

snyk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/node@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
111 changes: 111 additions & 0 deletions .github/workflows/k8s-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: NestJS CI/CD on Kubernetes

on:
push:
branches: [ "develop" ]

jobs:
build:
name: CI/CD on EKS
runs-on: ubuntu-latest
environment: develop
env:
ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }}

steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

- name: Set short git commit SHA
id: commit
uses: prompt/actions-commit-hash@v2

- name: Checkout
uses: actions/checkout@v2

- name: Make .env file
uses: SpicyPizza/[email protected]
with:
envkey_NODE_ENV: ${{ vars.NODE_ENV }}
envkey_PORT: ${{ vars.PORT }}
envkey_MONGODB_CONNECTION_STRING: ${{ secrets.MONGODB_CONNECTION_STRING }}
envkey_CORS_VALID_ORIGINS: ${{ vars.CORS_VALID_ORIGINS }}

envkey_JWT_ACCESS_SECRET: ${{ vars.JWT_ACCESS_SECRET }}
envkey_JWT_ACCESS_EXPIRATION: ${{ vars.JWT_ACCESS_EXPIRATION }}
envkey_JWT_REFRESH_SECRET: ${{ vars.JWT_REFRESH_SECRET }}
envkey_JWT_REFRESH_EXPIRATION: ${{ vars.JWT_REFRESH_EXPIRATION }}

envkey_SMTP_USERNAME: ${{ secrets.SMTP_USERNAME }}
envkey_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
envkey_SMTP_HOST: ${{ vars.SMTP_HOST }}
envkey_SMTP_PORT: ${{ vars.SMTP_PORT }}
envkey_SMTP_FROM_EMAIL: ${{ vars.SMTP_FROM_EMAIL }}
envkey_SMTP_FROM_NAME: ${{ vars.SMTP_FROM_NAME }}

envkey_WEB_URL: ${{ vars.WEB_URL }}
envkey_SERVER_URL: ${{ vars.SERVER_URL }}

envkey_MOMO_PARTNER_CODE: ${{ secrets.MOMO_PARTNER_CODE }}
envkey_MOMO_ACCESS_KEY: ${{ secrets.MOMO_ACCESS_KEY }}
envkey_MOMO_SECRET_KEY: ${{ secrets.MOMO_SECRET_KEY }}
envkey_MOMO_ENDPOINT: ${{ vars.MOMO_ENDPOINT }}

envkey_ZALOPAY_APP_ID: ${{ secrets.ZALOPAY_APP_ID }}
envkey_ZALOPAY_KEY1: ${{ secrets.ZALOPAY_KEY1 }}
envkey_ZALOPAY_KEY2: ${{ secrets.ZALOPAY_KEY2 }}
envkey_ZALOPAY_ENDPOINT: ${{ vars.ZALOPAY_ENDPOINT }}
- 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: ${{ vars.AWS_REGION }}

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

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master

- name: Docker cache layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-single-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-single-buildx
- name: Build & Push Image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ steps.commit.outputs.short }}

run: |
docker buildx create --use
docker buildx build \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache-new \
--tag ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} \
--push \
.
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Update kube config
run: aws eks update-kubeconfig --name ${{ vars.EKS_CLUSTER_NAME }} --region ${{ vars.AWS_REGION }}

- name: Deploy to EKS
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ steps.commit.outputs.short }}
run: |
sed -i.bak "s|DOCKER_IMAGE|${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}|g" k8s/deployment.yaml && \
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/ingress.yaml
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ lerna-debug.log*
!.vscode/extensions.json

# Env file
.env
.env
# Sentry Config File
.sentryclirc
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/dist
11 changes: 9 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"arrowParens": "always",
"semi": false,
"trailingComma": "none",
"tabWidth": 2,
"endOfLine": "auto",
"useTabs": false,
"singleQuote": true,
"trailingComma": "all"
}
"printWidth": 120,
"jsxSingleQuote": true
}
56 changes: 32 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
## Build image
FROM node:20-alpine
WORKDIR /src
###################
# BUILD FOR LOCAL DEVELOPMENT
###################
FROM node:20-alpine AS development

COPY package*.json ./
COPY .npmrc ./
RUN npm install
RUN rm -rf .npmrc
WORKDIR /app

COPY . .
RUN npm run build
COPY --chown=node:node package*.json ./

RUN npm ci

COPY --chown=node:node . .

USER node

## Target image
FROM node:20-alpine

WORKDIR /home/nonroot
###################
# BUILD FOR PRODUCTION
###################
FROM node:20-alpine AS build
WORKDIR /app

COPY --chown=node:node package*.json ./

COPY package*.json ./
COPY .npmrc ./
RUN npm install
RUN rm -rf .npmrc
COPY --chown=node:node --from=development /app/node_modules ./node_modules

COPY --chown=node:node . .

RUN npm run build

COPY --from=0 /src/dist ./dist
RUN npm ci --only=production && npm cache clean --force

ENV PORT=5000
EXPOSE ${PORT}
USER node

RUN addgroup nonroot
RUN adduser --disabled-password --gecos "" --ingroup nonroot nonroot
RUN chown -R nonroot:nonroot /home/nonroot
###################
# RUN PRODUCTION
###################
FROM node:20-alpine AS production

USER nonroot
COPY --chown=node:node --from=build /app/node_modules ./node_modules
COPY --chown=node:node --from=build /app/dist ./dist
COPY --chown=node:node --from=build /app/.env ./.env

CMD ["npm", "run", "start:prod"]
CMD ["node", "dist/main.js"]
22 changes: 22 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
services:
mongo1:
image: mongo:7.0
command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27018"]
ports:
- 27018:27018
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27018 --quiet
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
volumes:
- "mongo1_data:/data/db"
- "mongo1_config:/data/configdb"

volumes:
mongo1_data:
mongo1_config:
41 changes: 40 additions & 1 deletion example.env
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,43 @@ JWT_ACCESS_EXPIRATION=864000
JWT_REFRESH_SECRET=SWVG1ACUJwVfIyeBe8iGPugAIPq2dNshecqazIVqvK0zb6xJFGGGpoB8naJuOCatH4q+lE57L093HIBm9iZVCd8GfTGsXULaij0k4IU4SSQ/9yyp5qiTWJKnjsmfJc2/FX8xr6XL7chCX8tHgSye5clffIQIY0LlVCwUbC4CukZY8ScSs980EXqnwk63b6R4z+ULYdjPxMk5GQB/qHgJnpa3oFIdCirFtUQUaQY8JpLU6qArDN2LelAcg3g1Eilo4fDNMvDtjNtsRxWYt4zL8Gmf4Mt2lfrrfrKxShd8ITD/4z+zy0GS5Uxg3rD2iVj4E3kjrQv5CD8zhOOg5xA1NA==
JWT_REFRESH_EXPIRATION=90

CORS_VALID_ORIGINS=localhost,ngrok-free
# GOOGLE
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

#FURNIQUE
CORS_VALID_ORIGINS=localhost,ngrok-free,furnique.tech
WEB_URL=https://www.furnique.tech
SERVER_URL=https://api.furnique.tech

#Discord webhook
DISCORD_WEBHOOK_ID=
DISCORD_WEBHOOK_TOKEN=

#Tripo 3D AI API
TRIPO_3D_AI_ENDPOINT=https://api.tripo3d.ai

#Eden AI
EDEN_AI_ENDPOINT=https://api.edenai.run


## PAYMENT
#MOMO
MOMO_PARTNER_CODE=
MOMO_ACCESS_KEY=
MOMO_SECRET_KEY=
MOMO_ENDPOINT=https://test-payment.momo.vn

#ZALOPAY
ZALOPAY_APP_ID=
ZALOPAY_KEY1=
ZALOPAY_KEY2=
ZALOPAY_ENDPOINT=https://sb-openapi.zalopay.vn

#PAYOS
PAYOS_CLIENT_ID=
PAYOS_API_KEY=
PAYOS_CHECKSUM_KEY=

# SENTRY
SENTRY_DSN=
Loading

0 comments on commit 9b399d1

Please sign in to comment.