From a856ea0a513f9ad8f01978ef5eb206c61447a34a Mon Sep 17 00:00:00 2001 From: Archisman Mridha Date: Sat, 10 Feb 2024 01:12:37 +0530 Subject: [PATCH] Containerizing the `frontend` | Adding build step for the frontend in the CI | Adding manifests to run the frontend in Kubernetes --- .dockerignore | 6 +- .github/workflows/main.yaml | 7 + compose.yaml | 369 +++++++++--------- frontend/Dockerfile | 33 ++ frontend/app/providers.component.tsx | 2 +- frontend/next.config.js | 16 + frontend/package.json | 1 + frontend/pnpm-lock.yaml | 253 ++++++++++++ frontend/todos.md | 1 + .../microservices/feeds/pod-monitor.yaml | 4 +- .../followships/pod-monitor.yaml | 4 +- .../microservices/frontend/application.yaml | 21 + .../microservices/frontend/pod-monitor.yaml | 22 ++ .../microservices/frontend/sealed-secret.yaml | 20 + .../microservices/gateway/pod-monitor.yaml | 4 +- .../microservices/kustomization.yaml | 4 + .../microservices/posts/pod-monitor.yaml | 4 +- .../microservices/profiles/pod-monitor.yaml | 4 +- .../microservices/users/pod-monitor.yaml | 4 +- 19 files changed, 587 insertions(+), 192 deletions(-) create mode 100644 frontend/Dockerfile create mode 100644 kubernetes/manifests/microservices/frontend/application.yaml create mode 100644 kubernetes/manifests/microservices/frontend/pod-monitor.yaml create mode 100644 kubernetes/manifests/microservices/frontend/sealed-secret.yaml diff --git a/.dockerignore b/.dockerignore index f87ad2d..b0fc1d3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,4 +4,8 @@ sample.application.yaml Dockerfile -hack \ No newline at end of file +hack + +frontend/.next +frontend/node_modules +frontend/.env.local diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 7b56a46..0401dc7 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -127,6 +127,13 @@ jobs: - backend/gateway/** - go.work.sum + - name: frontend + path: frontend + manifest: kubernetes/manifests/microservices/frontend/application.yaml + path_filters: | + changed: + - frontend/** + - name: application-controller path: kubernetes/operators/application manifest: kubernetes/manifests/application-controller/deployment.yaml diff --git a/compose.yaml b/compose.yaml index a8c8287..b7ababf 100644 --- a/compose.yaml +++ b/compose.yaml @@ -319,186 +319,199 @@ services: # --- MICROSERVICES --- - # users-microservice: - # container_name: users-microservice - # build: - # context: . - # dockerfile: ./backend/microservices/users/Dockerfile - # environment: - # - JWT_SECRET=secret - # # gRPC - # - GRPC_SERVER_PORT=4001 - # # PostgreSQL - # - POSTGRES_HOST=postgres - # - POSTGRES_PORT=5432 - # - POSTGRES_USER=default - # - POSTGRES_PASSWORD=pass - # - POSTGRES_CONNECTION_POOL_SIZE=300 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=http://jaeger:4317 - # depends_on: - # - postgres-migrate - # - fluentd - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: users-microservice + users-microservice: + container_name: users-microservice + build: + context: . + dockerfile: ./backend/microservices/users/Dockerfile + environment: + - JWT_SECRET=secret + # gRPC + - GRPC_SERVER_PORT=4001 + # PostgreSQL + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=default + - POSTGRES_PASSWORD=pass + - POSTGRES_CONNECTION_POOL_SIZE=300 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=http://jaeger:4317 + depends_on: + - postgres-migrate + - fluentd + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: users-microservice - # profiles-microservice: - # container_name: profiles-microservice - # build: - # context: . - # dockerfile: ./backend/microservices/profiles/Dockerfile - # environment: - # # gRPC - # - GRPC_SERVER_PORT=4002 - # # Elasticsearch - # - ELASTICSEARCH_URL=http://elasticsearch:9200 - # - ELASTICSEARCH_USERNAME=kibana_system - # - ELASTICSEARCH_PASSWORD=pass - # # Apache Kafka - # - KAFKA_HOSTS=kafka:9092 - # # PostgreSQL - # - POSTGRES_HOST=postgres - # - POSTGRES_PORT=5432 - # - POSTGRES_USER=default - # - POSTGRES_PASSWORD=pass - # - POSTGRES_CONNECTION_POOL_SIZE=300 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=http://jaeger:4317 - # depends_on: - # - postgres-migrate - # - kafka-migrate - # - elasticsearch - # - fluentd - # restart: on-failure - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: profiles-microservice + profiles-microservice: + container_name: profiles-microservice + build: + context: . + dockerfile: ./backend/microservices/profiles/Dockerfile + environment: + # gRPC + - GRPC_SERVER_PORT=4002 + # Elasticsearch + - ELASTICSEARCH_URL=http://elasticsearch:9200 + - ELASTICSEARCH_USERNAME=kibana_system + - ELASTICSEARCH_PASSWORD=pass + # Apache Kafka + - KAFKA_HOSTS=kafka:9092 + # PostgreSQL + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=default + - POSTGRES_PASSWORD=pass + - POSTGRES_CONNECTION_POOL_SIZE=300 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=http://jaeger:4317 + depends_on: + - postgres-migrate + - kafka-migrate + - elasticsearch + - fluentd + restart: on-failure + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: profiles-microservice - # followships-microservice: - # container_name: followships-microservice - # build: - # context: . - # dockerfile: ./backend/microservices/followships/Dockerfile - # environment: - # # gRPC - # - GRPC_SERVER_PORT=4003 - # # PostgreSQL - # - POSTGRES_HOST=postgres - # - POSTGRES_PORT=5432 - # - POSTGRES_USER=default - # - POSTGRES_PASSWORD=pass - # - POSTGRES_CONNECTION_POOL_SIZE=300 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=http://jaeger:4317 - # depends_on: - # - postgres-migrate - # - fluentd - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: followships-microservice + followships-microservice: + container_name: followships-microservice + build: + context: . + dockerfile: ./backend/microservices/followships/Dockerfile + environment: + # gRPC + - GRPC_SERVER_PORT=4003 + # PostgreSQL + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=default + - POSTGRES_PASSWORD=pass + - POSTGRES_CONNECTION_POOL_SIZE=300 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=http://jaeger:4317 + depends_on: + - postgres-migrate + - fluentd + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: followships-microservice - # posts-microservice: - # container_name: posts-microservice - # build: - # context: . - # dockerfile: ./backend/microservices/posts/Dockerfile - # environment: - # # gRPC - # - GRPC_SERVER_PORT=4004 - # # PostgreSQL - # - POSTGRES_HOST=postgres - # - POSTGRES_PORT=5432 - # - POSTGRES_USER=default - # - POSTGRES_PASSWORD=pass - # - POSTGRES_CONNECTION_POOL_SIZE=300 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=http://jaeger:4317 - # depends_on: - # - postgres-migrate - # - fluentd - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: posts-microservice + posts-microservice: + container_name: posts-microservice + build: + context: . + dockerfile: ./backend/microservices/posts/Dockerfile + environment: + # gRPC + - GRPC_SERVER_PORT=4004 + # PostgreSQL + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=default + - POSTGRES_PASSWORD=pass + - POSTGRES_CONNECTION_POOL_SIZE=300 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=http://jaeger:4317 + depends_on: + - postgres-migrate + - fluentd + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: posts-microservice - # feeds-microservice: - # container_name: feeds-microservice - # build: - # context: . - # dockerfile: ./backend/microservices/feeds/Dockerfile - # environment: - # # gRPC - # - GRPC_SERVER_PORT=4005 - # # PostgreSQL - # - POSTGRES_HOST=postgres - # - POSTGRES_PORT=5432 - # - POSTGRES_USER=default - # - POSTGRES_PASSWORD=pass - # - POSTGRES_CONNECTION_POOL_SIZE=300 - # # Apache Kafka - # - KAFKA_HOSTS=kafka:9092 - # # Redis - # - REDIS_URL=redis://:pass@redis:6379 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=http://jaeger:4317 - # depends_on: - # - postgres-migrate - # - kafka-migrate - # - redis - # - fluentd - # restart: on-failure - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: feeds-microservice + feeds-microservice: + container_name: feeds-microservice + build: + context: . + dockerfile: ./backend/microservices/feeds/Dockerfile + environment: + # gRPC + - GRPC_SERVER_PORT=4005 + # PostgreSQL + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=default + - POSTGRES_PASSWORD=pass + - POSTGRES_CONNECTION_POOL_SIZE=300 + # Apache Kafka + - KAFKA_HOSTS=kafka:9092 + # Redis + - REDIS_URL=redis://:pass@redis:6379 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=http://jaeger:4317 + depends_on: + - postgres-migrate + - kafka-migrate + - redis + - fluentd + restart: on-failure + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: feeds-microservice - # gateway: - # container_name: gateway - # build: - # context: . - # dockerfile: ./backend/gateway/Dockerfile - # environment: - # - GRAPHQL_SERVER_PORT=4000 - # # Microservices - # - USERS_MICROSERVICE_URL=users-microservice:4001 - # - PROFILES_MICROSERVICE_URL=profiles-microservice:4002 - # - FOLLOWSHIPS_MICROSERVICE_URL=followships-microservice:4003 - # - POSTS_MICROSERVICE_URL=posts-microservice:4004 - # - FEEDS_MICROSERVICE_URL=feeds-microservice:4005 - # # Prometheus - # - METRICS_SERVER_PORT=5000 - # # Jaeger - # - JAEGER_COLLECTOR_URL=jaeger:4317 - # depends_on: - # - users-microservice - # - profiles-microservice - # - followships-microservice - # - posts-microservice - # - feeds-microservice - # ports: - # - 4000:4000 - # restart: on-failure - # logging: - # driver: fluentd - # options: - # fluentd-address: localhost:24224 - # tag: gateway + gateway: + container_name: gateway + build: + context: . + dockerfile: ./backend/gateway/Dockerfile + environment: + - GRAPHQL_SERVER_PORT=4000 + # Microservices + - USERS_MICROSERVICE_URL=users-microservice:4001 + - PROFILES_MICROSERVICE_URL=profiles-microservice:4002 + - FOLLOWSHIPS_MICROSERVICE_URL=followships-microservice:4003 + - POSTS_MICROSERVICE_URL=posts-microservice:4004 + - FEEDS_MICROSERVICE_URL=feeds-microservice:4005 + # Prometheus + - METRICS_SERVER_PORT=5000 + # Jaeger + - JAEGER_COLLECTOR_URL=jaeger:4317 + depends_on: + - users-microservice + - profiles-microservice + - followships-microservice + - posts-microservice + - feeds-microservice + ports: + - 4000:4000 + restart: on-failure + # logging: + # driver: fluentd + # options: + # fluentd-address: localhost:24224 + # tag: gateway + + frontend: + container_name: frontend + build: + context: . + dockerfile: ./frontend/Dockerfile + environment: + - BACKEND_URL=http://gateway:4000/graphql + depends_on: + - gateway + ports: + - 3000:3000 + restart: on-failure diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..79404df --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,33 @@ +# syntax=docker/dockerfile:1 + +# --- STAGE 1 - Building the application --- # + +FROM node:20-alpine AS build +WORKDIR /src + +# Install pnpm +RUN npm install -g pnpm + +COPY ./frontend/package.json ./package.json +COPY ./frontend/pnpm-lock.yaml ./pnpm-lock.yaml +COPY ./frontend/.npmrc ./npmrc + +# Download dependencies as a separate step to take advantage of Docker's caching. +RUN CI=true pnpm install --frozen-lockfile + +COPY ./frontend . + +# Build the application. +RUN pnpm build && \ + cp -r ./.next/static ./.next/standalone/.next && \ + mv ./.next/standalone /build + +# --- STAGE 2 - Running the application --- # + +FROM node:20-alpine AS final + +# Copy the .next/standalone folder from the "build" stage. +COPY --from=build /build /app + +# What the container should run when it is started. +ENTRYPOINT [ "node", "/app/server.js" ] \ No newline at end of file diff --git a/frontend/app/providers.component.tsx b/frontend/app/providers.component.tsx index c7fd200..c6d5335 100644 --- a/frontend/app/providers.component.tsx +++ b/frontend/app/providers.component.tsx @@ -7,7 +7,7 @@ import { Poppins } from "next/font/google" import { Toaster } from "react-hot-toast" const poppins = Poppins({ - weight: ["400", "500", "600", "700", "800", "900"], + weight: ["400", "500", "600", "700"], subsets: ["latin"] }) diff --git a/frontend/next.config.js b/frontend/next.config.js index 87a391e..d5b75da 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -9,6 +9,22 @@ const nextConfig = { header (or X-Forwarded-Host). If these don't match, the request will be aborted. In other words, Server Actions can only be invoked on the same host as the page that hosts it. */ + + /* + During a build, Next.js will automatically trace each page and its dependencies to determine all + of the files that are needed for deploying a production version of your application. + + During next build, Next.js will use @vercel/nft to statically analyze import, require, and fs + usage to determine all files that a page might load. + + This will create a folder at .next/standalone which can then be deployed on its own without + installing node_modules. Additionally, a minimal server.js file is also output which can be used + instead of next start. This minimal server does not copy the public or .next/static folders by + default as these should ideally be handled by a CDN instead, although these folders can be + copied to the standalone/public and standalone/.next/static folders manually, after which + server.js file will serve these automatically. + */ + output: "standalone" } module.exports = nextConfig diff --git a/frontend/package.json b/frontend/package.json index d9f93dd..74cf1ed 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "react-hook-form": "^7.49.2", "react-hot-toast": "^2.4.1", "react-infinite-scroll-component": "^6.1.0", + "sharp": "^0.33.2", "validator": "^13.11.0", "zod": "^3.22.4", "zustand": "^4.5.0" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 9c69e4a..06008b9 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -41,6 +41,9 @@ dependencies: react-infinite-scroll-component: specifier: ^6.1.0 version: 6.1.0(react@18.2.0) + sharp: + specifier: ^0.33.2 + version: 0.33.2 validator: specifier: ^13.11.0 version: 13.11.0 @@ -753,6 +756,14 @@ packages: statuses: 2.0.1 dev: true + /@emnapi/runtime@0.45.0: + resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==} + requiresBuild: true + dependencies: + tslib: 2.6.2 + dev: false + optional: true + /@emotion/is-prop-valid@0.8.8: resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} requiresBuild: true @@ -1458,6 +1469,194 @@ packages: react-hook-form: 7.49.2(react@18.2.0) dev: false + /@img/sharp-darwin-arm64@0.33.2: + resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.1 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.2: + resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.1 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.1: + resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==} + engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.1: + resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==} + engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.1: + resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.1: + resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.1: + resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.1: + resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.1: + resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.1: + resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-linux-arm64@0.33.2: + resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.1 + dev: false + optional: true + + /@img/sharp-linux-arm@0.33.2: + resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.1 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.33.2: + resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.1 + dev: false + optional: true + + /@img/sharp-linux-x64@0.33.2: + resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.1 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.33.2: + resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.33.2: + resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.1 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.2: + resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 0.45.0 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.2: + resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.2: + resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@internationalized/date@3.5.1: resolution: {integrity: sha512-LUQIfwU9e+Fmutc/DpRTGXSdgYZLBegi4wygCWDSVmUdLTaMHsQyASDiJtREwanwKuQLq0hY76fCJ9J/9I2xOQ==} dependencies: @@ -4630,6 +4829,11 @@ packages: engines: {node: '>=8'} dev: true + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + dev: false + /detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} dev: false @@ -5423,6 +5627,13 @@ packages: dependencies: yallist: 3.1.1 + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: false + /map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} @@ -6186,6 +6397,14 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + /sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} dependencies: @@ -6216,6 +6435,36 @@ packages: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true + /sharp@0.33.2: + resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==} + engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.2 + semver: 7.6.0 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.2 + '@img/sharp-darwin-x64': 0.33.2 + '@img/sharp-libvips-darwin-arm64': 1.0.1 + '@img/sharp-libvips-darwin-x64': 1.0.1 + '@img/sharp-libvips-linux-arm': 1.0.1 + '@img/sharp-libvips-linux-arm64': 1.0.1 + '@img/sharp-libvips-linux-s390x': 1.0.1 + '@img/sharp-libvips-linux-x64': 1.0.1 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 + '@img/sharp-libvips-linuxmusl-x64': 1.0.1 + '@img/sharp-linux-arm': 0.33.2 + '@img/sharp-linux-arm64': 0.33.2 + '@img/sharp-linux-s390x': 0.33.2 + '@img/sharp-linux-x64': 0.33.2 + '@img/sharp-linuxmusl-arm64': 0.33.2 + '@img/sharp-linuxmusl-x64': 0.33.2 + '@img/sharp-wasm32': 0.33.2 + '@img/sharp-win32-ia32': 0.33.2 + '@img/sharp-win32-x64': 0.33.2 + dev: false + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -6785,6 +7034,10 @@ packages: /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: false + /yaml-ast-parser@0.0.43: resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} dev: true diff --git a/frontend/todos.md b/frontend/todos.md index 682a6ac..bd72560 100644 --- a/frontend/todos.md +++ b/frontend/todos.md @@ -1,3 +1,4 @@ # Todos - [ ] If JWT is expired, then remove it from the cookie. +- [ ] Manage Apollo client caching. diff --git a/kubernetes/manifests/microservices/feeds/pod-monitor.yaml b/kubernetes/manifests/microservices/feeds/pod-monitor.yaml index 239a4f5..23fccb5 100644 --- a/kubernetes/manifests/microservices/feeds/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/feeds/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: feeds-microservice + app: feeds-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: diff --git a/kubernetes/manifests/microservices/followships/pod-monitor.yaml b/kubernetes/manifests/microservices/followships/pod-monitor.yaml index 9c2d9a8..5569005 100644 --- a/kubernetes/manifests/microservices/followships/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/followships/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: followships-microservice + app: followships-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: diff --git a/kubernetes/manifests/microservices/frontend/application.yaml b/kubernetes/manifests/microservices/frontend/application.yaml new file mode 100644 index 0000000..21eaa2a --- /dev/null +++ b/kubernetes/manifests/microservices/frontend/application.yaml @@ -0,0 +1,21 @@ +apiVersion: instagramclone.io/v1alpha1 +kind: Application +metadata: + name: frontend-microservice + namespace: microservices + labels: + app: frontend-microservice + app.kubernetes.io/instance: frontend-microservice + +spec: + image: ghcr.io/archisman-mridha/instagram-clone-frontend-microservice:89d47a5a4cffbab586f2609fbc8d4e3f07152f3c + replicas: + min: 1 + max: 3 + resources: + cpu: 200m + memory: 200Mi + secretName: frontend-microservice + ports: + - name: web + containerPort: 3000 diff --git a/kubernetes/manifests/microservices/frontend/pod-monitor.yaml b/kubernetes/manifests/microservices/frontend/pod-monitor.yaml new file mode 100644 index 0000000..9744613 --- /dev/null +++ b/kubernetes/manifests/microservices/frontend/pod-monitor.yaml @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: frontend-microservice-metrics + namespace: prometheus + +spec: + namespaceSelector: + matchNames: + - microservices + selector: + matchLabels: + app: frontend-microservice + + # Defines the labels which are transferred from the associated Kubernetes Pod object onto the + # ingested metrics. + podTargetLabels: + - app + + # List of endpoints part of this PodMonitor. + podMetricsEndpoints: + - port: metrics diff --git a/kubernetes/manifests/microservices/frontend/sealed-secret.yaml b/kubernetes/manifests/microservices/frontend/sealed-secret.yaml new file mode 100644 index 0000000..2bd7c16 --- /dev/null +++ b/kubernetes/manifests/microservices/frontend/sealed-secret.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + annotations: + sealedsecrets.bitnami.com/cluster-wide: "true" + creationTimestamp: null + name: frontend-microservice + namespace: microservices +spec: + encryptedData: + BACKEND_URL: AgAz20rS4WQsqTeD9NSQvtmE4yVjP4nhXOnQz3A5gBj4KRdqw/qf1/GaDEJ3FXj+a/Y+q27DM0gR+6bSj5ufYVzBszUjzNFxxAX4pwiuT4h0mbe8h/lJ8ogqsnYQbDizAG5bHgznVD7eR0g9bm8ux5pgCIn9xFJjMMDeSY3D7l59+hd7R7WwwPI1TMdqRbEV41bs5E4Mf4a8cbUGr2LfpY4ft4qhjnlrLjtpRr09gr2hMdrpc3GoLuYUPDeaBlT3lmn/gPYtbkyC5RrerA9B2Nb8VS/hR3eZzTGMxFnlsotMSTzt5Jz9TJXkiMQSQuF3492hLbzhfj1eo4DZvXaXgbWimRKUQ7SJZItSWBFpEpy+wI8xWMGGAtVHjikTQWfzMD9ueCHLK1l/gW9OwHQ/oBQ16QOueG888zw9P5XDSBnXxRcH0DgnOQ/m913XigaUua+EmlV9XoSktwRsF92t12vBDtakyqNpR3BO88AcSYcDqFYKBZ6c/cQNtVYXulPPJB9nnKUZZiKa/otqymRD5jUyEtVslFxSxkdGmFfkyK12IPGcIkqNhhJ5zJnC/hBJ5s9MpZQ5/KRFZcOltDvbr63OqAK0Il7xMVtXk6BdwUFcUcNpmH9WZdG4uqa+khrnVbnbneWsaInHzz17gyTiWjAp1SJqFg+7nMMtiNKdJ0P5MuB2xduw6VegXGuy6tylOL1SiV/zCrk/P5bTWvxKI8ynX9ttvZ/AFd7ZViNK8rvix7wI0yTTlWJ9 + template: + metadata: + annotations: + sealedsecrets.bitnami.com/cluster-wide: "true" + creationTimestamp: null + name: frontend-microservice + namespace: microservices + type: Opaque diff --git a/kubernetes/manifests/microservices/gateway/pod-monitor.yaml b/kubernetes/manifests/microservices/gateway/pod-monitor.yaml index 3457bd2..ecca7b4 100644 --- a/kubernetes/manifests/microservices/gateway/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/gateway/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: gateway-microservice + app: gateway-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: diff --git a/kubernetes/manifests/microservices/kustomization.yaml b/kubernetes/manifests/microservices/kustomization.yaml index 65a766f..267a3c6 100644 --- a/kubernetes/manifests/microservices/kustomization.yaml +++ b/kubernetes/manifests/microservices/kustomization.yaml @@ -24,3 +24,7 @@ resources: - gateway/application.yaml - gateway/sealed-secret.yaml - gateway/pod-monitor.yaml + + - frontend/application.yaml + - frontend/sealed-secret.yaml + - frontend/pod-monitor.yaml diff --git a/kubernetes/manifests/microservices/posts/pod-monitor.yaml b/kubernetes/manifests/microservices/posts/pod-monitor.yaml index dcc9ebc..7510b46 100644 --- a/kubernetes/manifests/microservices/posts/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/posts/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: posts-microservice + app: posts-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: diff --git a/kubernetes/manifests/microservices/profiles/pod-monitor.yaml b/kubernetes/manifests/microservices/profiles/pod-monitor.yaml index 7793991..07f31c4 100644 --- a/kubernetes/manifests/microservices/profiles/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/profiles/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: profiles-microservice + app: profiles-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: diff --git a/kubernetes/manifests/microservices/users/pod-monitor.yaml b/kubernetes/manifests/microservices/users/pod-monitor.yaml index b9a7162..25858b5 100644 --- a/kubernetes/manifests/microservices/users/pod-monitor.yaml +++ b/kubernetes/manifests/microservices/users/pod-monitor.yaml @@ -10,12 +10,12 @@ spec: - microservices selector: matchLabels: - microservice: users-microservice + app: users-microservice # Defines the labels which are transferred from the associated Kubernetes Pod object onto the # ingested metrics. podTargetLabels: - - microservice + - app # List of endpoints part of this PodMonitor. podMetricsEndpoints: