From f0efdbf4165cfe17f2bd4c35053c47b9f5a1790c Mon Sep 17 00:00:00 2001 From: geekyharsh05 Date: Wed, 2 Oct 2024 01:02:40 +0530 Subject: [PATCH 1/2] feat: add Docker & Docker Compose For Dev-Mode. --- .dockerignore | 5 ++ .env.docker | 12 +++++ .gitignore | 1 - Dockerfile | 17 ------ Dockerfile.dev | 27 ++++++++++ Dockerfile.prod | 32 +++++++++++ docker-compose.yml | 51 ++++++++++-------- package.json | 8 ++- pnpm-lock.yaml | 129 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 .dockerignore create mode 100644 .env.docker delete mode 100644 Dockerfile create mode 100644 Dockerfile.dev create mode 100644 Dockerfile.prod diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b92f7e4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +/node_modules +.env.example +dist/ +ignore/ +node_modules/* \ No newline at end of file diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000..ac29266 --- /dev/null +++ b/.env.docker @@ -0,0 +1,12 @@ +# For Docker +# Paste all this in your .env file and run it with docker-compose up -d + +DATABASE_URL="postgresql://postgres:postgres@postgres:5432/postgres" +JWT_SECRET="secretjwt" +API_PORT=3000 +POSTGRES_PORT=5432 +POSTGRES_PATH=postgres-data +POSTGRES_HOST=postgres +POSTGRES_USERNAME=postgres +POSTGRES_PASSWORD=postgres +STRIPE_SK_KEY= \ No newline at end of file diff --git a/.gitignore b/.gitignore index e971859..76a8cb9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ dist/ ignore/ prisma/data .env -.env.* ! .env.example .vscode node_modules diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index dfe7db8..0000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# THIS IS BROKEN RN - -FROM node:21.7.1 -RUN mkdir -p /opt/app -WORKDIR /opt/app -COPY package.json pnpm-lock.yaml ./ - -# install pnpm -RUN npm install -g pnpm - -# install dependencies -RUN pnpm install - -COPY . . - -EXPOSE 3000 -CMD [ "pnpm", "run", "start"] \ No newline at end of file diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..8ea72d0 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,27 @@ +# Stage 1: Installer Stage +FROM node:22-alpine3.20 AS installer + +WORKDIR /usr/src/app + +RUN corepack enable && corepack prepare pnpm@9.5.0 --activate +COPY package.json pnpm-lock.yaml ./ +COPY prisma ./prisma + +RUN apk add --no-cache make gcc g++ python3 && \ + if [ -f pnpm-lock.yaml ]; then \ + pnpm install --frozen-lockfile --ignore-scripts; \ + else \ + echo "pnpm-lock.yaml not found" && exit 1; \ + fi && \ + npm rebuild bcrypt --build-from-source && \ + apk del make gcc g++ python3 + +COPY . . + +# Stage 2: Development Stage +FROM node:22-alpine3.20 AS development + +WORKDIR /usr/src/app +RUN corepack enable && corepack prepare pnpm@9.5.0 --activate +COPY --from=installer /usr/src/app/ ./ +CMD ["pnpm", "run", "dev:docker"] diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 0000000..95b7183 --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,32 @@ +# Stage 1: Builder Stage +FROM node:22-alpine3.20 AS builder +WORKDIR /usr/src/app + +RUN corepack enable && corepack prepare pnpm@9.5.0 --activate + +COPY package.json pnpm-lock.yaml ./ +COPY prisma ./prisma + +RUN apk add --no-cache make gcc g++ python3 && \ + if [ -f pnpm-lock.yaml ]; then \ + pnpm install --frozen-lockfile --ignore-scripts; \ + else \ + echo "pnpm-lock.yaml not found" && exit 1; \ + fi && \ + npm rebuild bcrypt --build-from-source && \ + apk del make gcc g++ python3 + +COPY . . + +RUN DATABASE_URL=$DATABASE_URL pnpm run build + +# Stage 2: Production Stage +FROM node:22-alpine3.20 AS production +WORKDIR /usr/src/app + +COPY --from=builder /usr/src/app/dist ./dist +COPY --from=builder /usr/src/app/node_modules/ ./node_modules + +EXPOSE 3000 + +CMD [ "node", "dist/index.js" ] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 2690516..ea8dd97 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,31 +1,36 @@ -# docker-compose.yml - -# THIS IS BROKEN RN - -version: "3.9" services: - postgres: - image: postgres:latest - environment: - POSTGRES_USER: jasper - POSTGRES_PASSWORD: jasper - ports: - - '5432:5432' - volumes: - - db:/var/lib/postgresql/data - api: + container_name: api-docker build: context: . - environment: - DB_SCHEMA: postgres - DB_USER: postgres - DB_PASSWORD: postgres - DB_HOST: postgres + dockerfile: Dockerfile.prod + env_file: + - .env + ports: + - ${API_PORT}:3000 depends_on: - - postgres + postgres: + condition: service_healthy + volumes: + - ./:/usr/src/app + - /usr/src/app/node_modules + + postgres: + container_name: prisma-postgres + image: postgres:alpine + restart: always + env_file: + - .env ports: - - '3000:3000' + - ${POSTGRES_PORT}:5432 + volumes: + - ${POSTGRES_PATH}:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 volumes: - db: + postgres-data: + external: false \ No newline at end of file diff --git a/package.json b/package.json index f4a67bd..75c02f3 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ ], "packageManager": "pnpm@9.5.0", "scripts": { + "preinstall": "npx only-allow pnpm", "start": "node dist/index.js", "postinstall": "npx prisma generate && tsc", "watch-node": "nodemon dist/index.js", @@ -22,7 +23,9 @@ "heroku-prebuild": "echo This runs before Heroku installs dependencies.", "heroku-postbuild": "echo This runs after Heroku installs dependencies, but before Heroku prunes and caches dependencies.", "heroku-cleanup": "echo This runs after Heroku prunes and caches dependencies.", - "prepare": "husky" + "prepare": "husky", + "prisma:docker": "npx prisma generate && npx prisma migrate dev", + "dev:docker": "pnpm prisma:docker && pnpm dev" }, "keywords": [], "author": "Jasper Mayone ", @@ -42,7 +45,8 @@ "puppeteer": "^22.15.0", "request-ip": "^3.3.0", "response-time": "^2.3.2", - "stripe": "^16.8.0" + "stripe": "^16.8.0", + "ts-node": "^10.9.2" }, "devDependencies": { "@types/bcrypt": "^5.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6589aa8..2a771f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: stripe: specifier: ^16.8.0 version: 16.8.0 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.16.0)(typescript@5.5.4) devDependencies: '@types/bcrypt': specifier: ^5.0.2 @@ -105,6 +108,20 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@mapbox/node-pre-gyp@1.0.11': resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true @@ -141,6 +158,18 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@types/bcrypt@5.0.2': resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==} @@ -199,6 +228,15 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -231,6 +269,9 @@ packages: engines: {node: '>=10'} deprecated: This package is no longer supported. + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -395,6 +436,9 @@ packages: typescript: optional: true + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + data-uri-to-buffer@6.0.2: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} @@ -450,6 +494,10 @@ packages: devtools-protocol@0.0.1312386: resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -785,6 +833,9 @@ packages: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -1160,6 +1211,20 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} @@ -1199,6 +1264,9 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -1249,6 +1317,10 @@ packages: yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} @@ -1268,6 +1340,19 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.0.1 + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@mapbox/node-pre-gyp@1.0.11': dependencies: detect-libc: 2.0.3 @@ -1323,6 +1408,14 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + '@types/bcrypt@5.0.2': dependencies: '@types/node': 20.16.0 @@ -1402,6 +1495,12 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + acorn-walk@8.3.4: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + agent-base@6.0.2: dependencies: debug: 4.3.6(supports-color@5.5.0) @@ -1436,6 +1535,8 @@ snapshots: delegates: 1.0.0 readable-stream: 3.6.2 + arg@4.1.3: {} + argparse@2.0.1: {} array-flatten@1.1.1: {} @@ -1623,6 +1724,8 @@ snapshots: optionalDependencies: typescript: 5.5.4 + create-require@1.1.1: {} + data-uri-to-buffer@6.0.2: {} debug@2.6.9: @@ -1661,6 +1764,8 @@ snapshots: devtools-protocol@0.0.1312386: {} + diff@4.0.2: {} + doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -2033,6 +2138,8 @@ snapshots: dependencies: semver: 6.3.1 + make-error@1.3.6: {} + media-typer@0.3.0: {} merge-descriptors@1.0.1: {} @@ -2434,6 +2541,24 @@ snapshots: tr46@0.0.3: {} + ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.16.0 + acorn: 8.12.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tslib@2.6.3: {} type-is@1.6.18: @@ -2462,6 +2587,8 @@ snapshots: utils-merge@1.0.1: {} + v8-compile-cache-lib@3.0.1: {} + vary@1.1.2: {} webidl-conversions@3.0.1: {} @@ -2506,4 +2633,6 @@ snapshots: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 + yn@3.1.1: {} + zod@3.23.8: {} From 0fa612b9e68f37e3b1976e093166c4a04f4292be Mon Sep 17 00:00:00 2001 From: geekyharsh05 Date: Wed, 2 Oct 2024 04:57:52 +0530 Subject: [PATCH 2/2] refactor: Update Dockerfile.dev reference in docker-compose.yml --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index ea8dd97..b6f167f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: container_name: api-docker build: context: . - dockerfile: Dockerfile.prod + dockerfile: Dockerfile.dev env_file: - .env ports: