diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml new file mode 100644 index 0000000..b1d709e --- /dev/null +++ b/.github/workflows/build-dev.yml @@ -0,0 +1,82 @@ +name: Build xyzuan-api-v2 Development Build + +on: + push: + branches: + - dev + # pull_request: + # branches: + # - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Settle up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Authenticating to Eden Server realms. + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SERVER_PRIVATE_KEY }} + + - name: Authenticating to GHCR realms + run: echo "${{ secrets.GH_TOKEN }}" | docker login -u "${{ github.actor }}" ghcr.io --password-stdin + + - name: Treaty Build the Docker image + run: | + docker build \ + --build-arg PORT=3121 \ + --build-arg NODE_ENV=dev \ + --build-arg DOMAIN=xyzuan.my.id \ + --build-arg PASSWORD_PEPPER=${{ secrets.PASSWORD_PEPPER }} \ + --build-arg DATABASE_URL=${{ secrets.DATABASE_URL_DEV }} \ + --build-arg GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} \ + --build-arg GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} \ + --build-arg GITHUB_CLIENT_ID=${{ secrets.GH_CLIENT_ID }} \ + --build-arg GITHUB_CLIENT_SECRET=${{ secrets.GH_CLIENT_SECRET }} \ + --build-arg LINKEDIN_CLIENT_ID=${{ secrets.LINKEDIN_CLIENT_ID }} \ + --build-arg LINKEDIN_CLIENT_SECRET=${{ secrets.LINKEDIN_CLIENT_SECRET }} \ + --build-arg TELEGRAM_TOKEN=${{ secrets.TELEGRAM_TOKEN }} \ + --build-arg TELEGRAM_CHAT_ID=${{ secrets.TELEGRAM_CHAT_ID }} \ + --build-arg CLOUDINARY_CLOUD_NAME=${{ secrets.CLOUDINARY_CLOUD_NAME }} \ + --build-arg CLOUDINARY_API_KEY=${{ secrets.CLOUDINARY_API_KEY }} \ + --build-arg CLOUDINARY_API_SECRET=${{ secrets.CLOUDINARY_API_SECRET }} \ + -t ghcr.io/xyzuan/xyzuan_api_v2:dev -f misc/Dockerfile.dev . + + - name: Adding tags to the Images + run: | + IMAGE_NAME=ghcr.io/xyzuan/xyzuan_api_v2 + docker tag $IMAGE_NAME:dev $IMAGE_NAME:$(echo "${{ github.sha }}" | head -c 7) + + - name: Bring the Images to GHCR + run: | + docker push ghcr.io/xyzuan/xyzuan_api_v2:dev + docker push ghcr.io/xyzuan/xyzuan_api_v2:$(echo "${{ github.sha }}" | head -c 7) + + - name: Serving the Images in Eden Server realms. + run: | + ssh-keyscan -t rsa ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts + ssh ${{ github.actor }}@${{ secrets.SERVER_HOST }} << 'EOF' + + echo 'Authenticating to GHCR realms...' + echo "${{ secrets.GH_TOKEN }}" | docker login -u "${{ github.actor }}" ghcr.io --password-stdin + + echo 'Pulling the latest image from GHCR...' + docker pull ghcr.io/xyzuan/xyzuan_api_v2:dev + + echo 'Force Blowing the exist Docker Container...' + docker rm -f xyzuan-api-v2-dev + + echo 'Running the Docker Container...' + docker run -d \ + --name xyzuan-api-v2-dev \ + --restart always \ + --network nginx_default \ + -p 3121:3121 \ + ghcr.io/xyzuan/xyzuan_api_v2:dev + EOF diff --git a/.github/workflows/build-prod.yml b/.github/workflows/build-prod.yml new file mode 100644 index 0000000..0f7ca49 --- /dev/null +++ b/.github/workflows/build-prod.yml @@ -0,0 +1,79 @@ +name: Build xyzuan-api-v2 Production Build + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Settle up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Authenticating to Eden Server realms. + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SERVER_PRIVATE_KEY }} + + - name: Authenticating to GHCR realms + run: echo "${{ secrets.GH_TOKEN }}" | docker login -u "${{ github.actor }}" ghcr.io --password-stdin + + - name: Treaty Build the Docker image + run: | + docker build \ + --build-arg PORT=3131 \ + --build-arg NODE_ENV=production \ + --build-arg DOMAIN=xyzuan.my.id \ + --build-arg PASSWORD_PEPPER=${{ secrets.PASSWORD_PEPPER }} \ + --build-arg DATABASE_URL=${{ secrets.DATABASE_URL }} \ + --build-arg GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} \ + --build-arg GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} \ + --build-arg GITHUB_CLIENT_ID=${{ secrets.GH_CLIENT_ID }} \ + --build-arg GITHUB_CLIENT_SECRET=${{ secrets.GH_CLIENT_SECRET }} \ + --build-arg LINKEDIN_CLIENT_ID=${{ secrets.LINKEDIN_CLIENT_ID }} \ + --build-arg LINKEDIN_CLIENT_SECRET=${{ secrets.LINKEDIN_CLIENT_SECRET }} \ + --build-arg TELEGRAM_TOKEN=${{ secrets.TELEGRAM_TOKEN }} \ + --build-arg TELEGRAM_CHAT_ID=${{ secrets.TELEGRAM_CHAT_ID }} \ + --build-arg CLOUDINARY_CLOUD_NAME=${{ secrets.CLOUDINARY_CLOUD_NAME }} \ + --build-arg CLOUDINARY_API_KEY=${{ secrets.CLOUDINARY_API_KEY }} \ + --build-arg CLOUDINARY_API_SECRET=${{ secrets.CLOUDINARY_API_SECRET }} \ + -t ghcr.io/xyzuan/xyzuan_api_v2:{{ github.ref }} -f misc/Dockerfile.prod . + + - name: Adding tags to the Images + run: | + IMAGE_NAME=ghcr.io/xyzuan/xyzuan_api_v2 + docker tag $IMAGE_NAME:{{ github.ref }} $IMAGE_NAME:$(echo "${{ github.sha }}" | head -c 7) + + - name: Bring the Images to GHCR + run: | + docker push ghcr.io/xyzuan/xyzuan_api_v2:{{ github.ref }} + docker push ghcr.io/xyzuan/xyzuan_api_v2:$(echo "${{ github.sha }}" | head -c 7) + + - name: Serving the Images in Eden Server realms. + run: | + ssh-keyscan -t rsa ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts + ssh ${{ github.actor }}@${{ secrets.SERVER_HOST }} << 'EOF' + + echo 'Authenticating to GHCR realms...' + echo "${{ secrets.GH_TOKEN }}" | docker login -u "${{ github.actor }}" ghcr.io --password-stdin + + echo 'Pulling the latest image from GHCR...' + docker pull ghcr.io/xyzuan/xyzuan_api_v2:{{ github.ref }} + + echo 'Force Blowing the exist Docker Container...' + docker rm -f xyzuan-api-v2-{{ github.ref }} + + echo 'Running the Docker Container...' + docker run -d \ + --name xyzuan-api-v2-{{ github.ref }} \ + --restart always \ + --network nginx_default \ + -p 3131:3131 \ + ghcr.io/xyzuan/xyzuan_api_v2:{{ github.ref }} + EOF diff --git a/.gitignore b/.gitignore index 996fc0e..4d780f9 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,6 @@ yarn-error.log* **/*.tgz **/*.log package-lock.json -**/*.bun \ No newline at end of file +**/*.bun + +misc/Dockerfile.local \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index d747d22..920e108 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/misc/Dockerfile.dev b/misc/Dockerfile.dev new file mode 100644 index 0000000..e368db4 --- /dev/null +++ b/misc/Dockerfile.dev @@ -0,0 +1,73 @@ +FROM oven/bun AS build + +WORKDIR /app + +COPY package.json bun.lockb tsconfig.json ./ +RUN \ + if [ -f bun.lockb ]; then bun install --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +COPY ./src ./src +COPY ./prisma ./prisma + +RUN bun install +RUN bunx prisma generate +RUN bun build \ + --compile \ + --minify-whitespace \ + --minify-syntax \ + --target bun \ + --outfile server \ + ./src/index.ts + +FROM gcr.io/distroless/cc + +WORKDIR /app + +COPY --from=build /app/server server +COPY --from=build /app/node_modules/.prisma /app/node_modules/.prisma +COPY --from=build /app/node_modules/@prisma /app/node_modules/@prisma + +ARG PORT +ARG NODE_ENV +ARG DOMAIN +ARG PASSWORD_PEPPER +ARG DATABASE_URL + +ARG GOOGLE_CLIENT_ID +ARG GOOGLE_CLIENT_SECRET +ARG GITHUB_CLIENT_ID +ARG GITHUB_CLIENT_SECRET +ARG LINKEDIN_CLIENT_ID +ARG LINKEDIN_CLIENT_SECRET +ARG TELEGRAM_TOKEN +ARG TELEGRAM_CHAT_ID + +ARG CLOUDINARY_CLOUD_NAME +ARG CLOUDINARY_API_KEY +ARG CLOUDINARY_API_SECRET + +ENV PORT=$PORT +ENV NODE_ENV=$NODE_ENV +ENV DOMAIN=$DOMAIN +ENV PASSWORD_PEPPER=$PASSWORD_PEPPER +ENV DATABASE_URL=$DATABASE_URL + +ENV GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID +ENV GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET +ENV GITHUB_CLIENT_ID=$GITHUB_CLIENT_ID +ENV GITHUB_CLIENT_SECRET=$GITHUB_CLIENT_SECRET +ENV LINKEDIN_CLIENT_ID=$LINKEDIN_CLIENT_ID +ENV LINKEDIN_CLIENT_SECRET=$LINKEDIN_CLIENT_SECRET +ENV TELEGRAM_TOKEN=$TELEGRAM_TOKEN +ENV TELEGRAM_CHAT_ID=$TELEGRAM_CHAT_ID + +ENV CLOUDINARY_CLOUD_NAME=$CLOUDINARY_CLOUD_NAME +ENV CLOUDINARY_API_KEY=$CLOUDINARY_API_KEY +ENV CLOUDINARY_API_SECRET=$CLOUDINARY_API_SECRET + +EXPOSE 3131 + +CMD ["./server"] + diff --git a/misc/Dockerfile.prod b/misc/Dockerfile.prod new file mode 100644 index 0000000..e368db4 --- /dev/null +++ b/misc/Dockerfile.prod @@ -0,0 +1,73 @@ +FROM oven/bun AS build + +WORKDIR /app + +COPY package.json bun.lockb tsconfig.json ./ +RUN \ + if [ -f bun.lockb ]; then bun install --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +COPY ./src ./src +COPY ./prisma ./prisma + +RUN bun install +RUN bunx prisma generate +RUN bun build \ + --compile \ + --minify-whitespace \ + --minify-syntax \ + --target bun \ + --outfile server \ + ./src/index.ts + +FROM gcr.io/distroless/cc + +WORKDIR /app + +COPY --from=build /app/server server +COPY --from=build /app/node_modules/.prisma /app/node_modules/.prisma +COPY --from=build /app/node_modules/@prisma /app/node_modules/@prisma + +ARG PORT +ARG NODE_ENV +ARG DOMAIN +ARG PASSWORD_PEPPER +ARG DATABASE_URL + +ARG GOOGLE_CLIENT_ID +ARG GOOGLE_CLIENT_SECRET +ARG GITHUB_CLIENT_ID +ARG GITHUB_CLIENT_SECRET +ARG LINKEDIN_CLIENT_ID +ARG LINKEDIN_CLIENT_SECRET +ARG TELEGRAM_TOKEN +ARG TELEGRAM_CHAT_ID + +ARG CLOUDINARY_CLOUD_NAME +ARG CLOUDINARY_API_KEY +ARG CLOUDINARY_API_SECRET + +ENV PORT=$PORT +ENV NODE_ENV=$NODE_ENV +ENV DOMAIN=$DOMAIN +ENV PASSWORD_PEPPER=$PASSWORD_PEPPER +ENV DATABASE_URL=$DATABASE_URL + +ENV GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID +ENV GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET +ENV GITHUB_CLIENT_ID=$GITHUB_CLIENT_ID +ENV GITHUB_CLIENT_SECRET=$GITHUB_CLIENT_SECRET +ENV LINKEDIN_CLIENT_ID=$LINKEDIN_CLIENT_ID +ENV LINKEDIN_CLIENT_SECRET=$LINKEDIN_CLIENT_SECRET +ENV TELEGRAM_TOKEN=$TELEGRAM_TOKEN +ENV TELEGRAM_CHAT_ID=$TELEGRAM_CHAT_ID + +ENV CLOUDINARY_CLOUD_NAME=$CLOUDINARY_CLOUD_NAME +ENV CLOUDINARY_API_KEY=$CLOUDINARY_API_KEY +ENV CLOUDINARY_API_SECRET=$CLOUDINARY_API_SECRET + +EXPOSE 3131 + +CMD ["./server"] + diff --git a/package.json b/package.json index e168c34..d8a5c88 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@types/node-telegram-bot-api": "^0.64.7", "bun-types": "latest", - "prisma": "^5.19.0" + "prisma": "5.19.1" }, "module": "src/index.js" } diff --git a/prisma/schema.prisma b/prisma/schema.prisma index fe5ddeb..21cec97 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -6,6 +6,8 @@ generator client { provider = "prisma-client-js" + engineType = "binary" + binaryTargets = ["debian-openssl-3.0.x"] } datasource db {