build(v3): use pnpm, docker, docker-compose to orchestrate two services (client, server)

This commit is contained in:
Amruth Pillai 2022-03-07 13:43:34 +01:00
parent 9c1380f401
commit 938e2e8e25
No known key found for this signature in database
GPG Key ID: E3C57DF9B80855AD
23 changed files with 9355 additions and 11409 deletions

11
.changeset/config.json Normal file
View File

@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@1.7.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"ignore": [],
"baseBranch": "v3",
"access": "restricted",
"updateInternalDependencies": "patch"
}

View File

@ -1,6 +1,18 @@
# Build Artifacts
dist
.next
Dockerfile
# IDEs
.vscode
# Project Metadata
README.md
CHANGELOG.md
# Project Dependencies
node_modules
# Docker
Dockerfile
.dockerignore
docker-compose.yml
docker-compose.yml

View File

@ -1,8 +1,15 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort", "unused-imports"],
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"plugins": [
"@typescript-eslint/eslint-plugin",
"simple-import-sort",
"unused-imports"
],
"rules": {
// TypeScript ESLint
"@typescript-eslint/no-unused-vars": "off",
@ -10,11 +17,9 @@
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
// Simple Import Sort
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
// Unused Imports
"no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
@ -30,10 +35,12 @@
},
"overrides": [
{
"files": ["*.js"],
"files": [
"*.js"
],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
]
}
}

17
.gitignore vendored
View File

@ -1,16 +1,7 @@
# Package Manager
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Project Dependencies
node_modules
# Environment Variables
.env
.env.*
!.env.example
!.env.example
# Project Dependencies
node_modules

View File

@ -1,7 +1,9 @@
{
"css.validate": false,
"scss.validate": false,
"editor.codeActionsOnSave": { "source.fixAll.eslint": true },
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.wordWrap": "on",
@ -10,5 +12,8 @@
"i18n-ally.localesPaths": ["client/public/locales"],
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.sortKeys": true
"i18n-ally.sortKeys": true,
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +0,0 @@
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.2.0.cjs

View File

@ -43,18 +43,16 @@ git clone https://github.com/AmruthPillai/Reactive-Resume.git
cd Reactive-Resume
```
2. I prefer to use `npm`, but you can use anything to install dependencies (`pnpm`/`yarn`)
2. I prefer to use `pnpm`, but you can use anything to install dependencies (`npm`/`yarn`)
```
npm install
pnpm install
```
3. Copy the .env.example files to .env in multiple locations and fill it with values according to your setup
3. Copy the `.env.example` file to `.env` in the project root and fill it with values according to your setup. Everything except the mail server settings are required.
```
cp .env.example .env
cp apps/client/.env.example apps/client/.env
cp apps/server/.env.example apps/server/.env
```
4. Use Docker Compose to create a PostgreSQL instance and a `reactive_resume` database, or feel free to use your own and modify the variables used in `.env`
@ -66,7 +64,7 @@ docker-compose up -d
5. Run the project and start building!
```
npm start
pnpm dev
```
## Contributing

View File

@ -1,58 +0,0 @@
# Install dependencies only when needed
FROM node:16-alpine AS dependencies
RUN apk add --no-cache libc6-compat
WORKDIR /app
RUN yarn set version berry
RUN yarn plugin import workspace-tools
COPY package.json .yarnrc.yml yarn.lock ./
COPY schema/package.json ./schema/package.json
COPY client/package.json ./client/package.json
RUN yarn install
FROM node:16-alpine AS builder
WORKDIR /app
RUN yarn set version berry
RUN yarn plugin import workspace-tools
COPY --from=dependencies /app/package.json .
COPY --from=dependencies /app/node_modules ./node_modules
COPY ./schema ./schema
COPY ./client ./client
RUN yarn workspace @reactive-resume/schema run build
RUN yarn workspace @reactive-resume/client run build
FROM node:16-alpine AS production
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/client/next.config.js ./
COPY --from=builder /app/client/next-i18next.config.js ./
COPY --from=builder /app/client/public ./public
COPY --from=builder /app/client/package.json ./package.json
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/client/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/client/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]

51
client/Dockerfile Normal file
View File

@ -0,0 +1,51 @@
FROM node:16-alpine as dependencies
RUN apk add --no-cache curl g++ make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /app
COPY package.json pnpm-*.yaml ./
COPY ./schema/package.json ./schema/package.json
COPY ./client/package.json ./client/package.json
RUN pnpm install --frozen-lockfile
FROM node:16-alpine as builder
RUN apk add --no-cache curl g++ make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /app
COPY . .
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=dependencies /app/schema/node_modules ./schema/node_modules
COPY --from=dependencies /app/client/node_modules ./client/node_modules
RUN cp .env ./client/.env
RUN pnpm run build:schema
RUN pnpm run build:client
FROM node:16-alpine as production
WORKDIR /app
RUN apk add --no-cache curl \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
COPY --from=builder /app/pnpm-*.yaml .
COPY --from=builder /app/package.json .
COPY --from=builder /app/client/.next ./client/.next
COPY --from=builder /app/client/public ./client/public
COPY --from=builder /app/client/next.config.js ./client/next.config.js
COPY --from=builder /app/client/next-i18next.config.js ./client/next-i18next.config.js
COPY --from=builder /app/client/package.json ./client/package.json
RUN pnpm install -F client --frozen-lockfile --prod
EXPOSE 3000
CMD [ "pnpm", "run", "start:client" ]

View File

@ -1,6 +1,4 @@
import { createTheme } from '@mui/material';
import { grey } from '@mui/material/colors';
import { teal } from 'tailwindcss/colors';
const theme = createTheme({
typography: {
@ -57,8 +55,8 @@ export const lightTheme = createTheme({
...theme,
palette: {
mode: 'light',
primary: { main: grey[800] },
secondary: { main: teal[600] },
primary: { main: '#404040' }, // neutral[700]
secondary: { main: '#0d9488' }, // teal[600]
},
});
@ -66,7 +64,7 @@ export const darkTheme = createTheme({
...theme,
palette: {
mode: 'dark',
primary: { main: grey[100] },
secondary: { main: teal[400] },
primary: { main: '#f5f5f5' }, // neutral[100]
secondary: { main: '#2dd4bf' }, // teal[400]
},
});

View File

@ -1,3 +1,4 @@
const { version } = require('../package.json');
const { i18n } = require('./next-i18next.config');
/** @type {import('next').NextConfig} */
@ -6,20 +7,15 @@ const nextConfig = {
i18n,
env: {
appVersion: '3.0.0',
appUrl: process.env.APP_URL,
serverUrl: process.env.SERVER_URL,
googleClientId: process.env.GOOGLE_CLIENT_ID,
},
images: {
domains: ['www.gravatar.com'],
},
experimental: {
externalDir: true,
outputStandalone: true,
env: {
appVersion: version,
appUrl: process.env.APP_URL,
serverUrl: process.env.SERVER_URL,
googleClientId: process.env.GOOGLE_CLIENT_ID,
},
// Hack to make Tailwind darkMode 'class' strategy with CSS Modules

View File

@ -39,6 +39,7 @@
"react-hotkeys-hook": "^3.4.4",
"react-icons": "^4.3.1",
"react-markdown": "^8.0.0",
"react-query": "^3.34.16",
"react-redux": "^7.2.6",
"react-zoom-pan-pinch": "^2.1.3",
"redux": "^4.1.2",
@ -51,7 +52,6 @@
},
"devDependencies": {
"@babel/core": "^7.17.5",
"@reactive-resume/schema": "workspace:^",
"@types/downloadjs": "^1.4.3",
"@types/lodash": "^4.14.179",
"@types/node": "17.0.21",
@ -66,9 +66,9 @@
"eslint-config-next": "12.1.0",
"postcss": "^8.4.7",
"prettier": "^2.5.1",
"react-query": "^3.34.16",
"sass": "^1.49.9",
"tailwindcss": "^3.0.23",
"typescript": "<4.6.0"
"typescript": "<4.6.0",
"@reactive-resume/schema": "workspace:*"
}
}

View File

@ -11,5 +11,29 @@ services:
- ./scripts/database/initialize.sql:/docker-entrypoint-initdb.d/initialize.sql
- pgdata:/var/lib/postgresql/data
server:
build:
context: .
dockerfile: server/Dockerfile
container_name: server
env_file: .env
environment:
- POSTGRES_HOST=postgres
ports:
- 3100:3100
depends_on:
- postgres
client:
build:
context: .
dockerfile: client/Dockerfile
container_name: client
env_file: .env
ports:
- 3000:3000
depends_on:
- server
volumes:
pgdata:

View File

@ -2,29 +2,38 @@
"name": "reactive-resume",
"version": "3.0.0",
"private": true,
"packageManager": "yarn@3.2.0",
"workspaces": [
"schema",
"client",
"server"
],
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"scripts": {
"dev:client": "yarn workspace @reactive-resume/client run dev",
"dev:server": "yarn workspace @reactive-resume/server run start:dev",
"dev": "env-cmd concurrently --kill-others \"yarn:dev:*\"",
"build": "yarn workspaces foreach run build",
"lint": "yarn workspaces foreach run lint",
"start:client": "yarn workspace @reactive-resume/client run start",
"start:server": "yarn workspace @reactive-resume/server run start:prod",
"start": "concurrently --kill-others \"yarn:start:*\""
"dev:schema": "pnpm -F schema dev",
"dev:server": "pnpm -F server start:dev",
"dev:client": "pnpm -F client dev",
"dev": "env-cmd concurrently --kill-others \"pnpm run dev:*\"",
"build:schema": "pnpm -F schema build",
"build:server": "pnpm -F server build",
"build:client": "pnpm -F client build",
"build": "env-cmd concurrently \"pnpm run build:*\"",
"start:server": "pnpm -F server start:prod",
"start:client": "pnpm -F client start",
"start": "env-cmd concurrently --kill-others \"pnpm run start:*\""
},
"dependencies": {
"concurrently": "^7.0.0",
"env-cmd": "^10.1.0"
},
"devDependencies": {
"@changesets/cli": "^2.21.1",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.13.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.25.4",
@ -32,6 +41,6 @@
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"prettier": "^2.5.1",
"typescript": "<4.6.0"
"typescript": "^4.5.5"
}
}

9139
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

4
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,4 @@
packages:
- 'schema'
- 'server'
- 'client'

View File

@ -5,6 +5,7 @@
"typings": "./dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc -w",
"lint": "eslint --fix --ext .ts ./src"
},
"devDependencies": {

47
server/Dockerfile Normal file
View File

@ -0,0 +1,47 @@
FROM node:16-alpine as dependencies
RUN apk add --no-cache g++ curl make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /app
COPY package.json pnpm-*.yaml ./
COPY ./schema/package.json ./schema/package.json
COPY ./server/package.json ./server/package.json
RUN pnpm install --frozen-lockfile
FROM node:16-alpine as builder
RUN apk add --no-cache g++ curl make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /app
COPY . .
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=dependencies /app/schema/node_modules ./schema/node_modules
COPY --from=dependencies /app/server/node_modules ./server/node_modules
RUN cp .env ./server/.env
RUN pnpm run build:schema
RUN pnpm run build:server
FROM mcr.microsoft.com/playwright:focal as production
WORKDIR /app
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
COPY --from=builder /app/pnpm-*.yaml .
COPY --from=builder /app/package.json .
COPY --from=builder /app/server/dist ./server/dist
COPY --from=builder /app/server/package.json ./server/package.json
RUN pnpm install -F server --frozen-lockfile --prod
EXPOSE 3100
CMD [ "pnpm", "run", "start:server" ]

View File

@ -52,7 +52,6 @@
"devDependencies": {
"@nestjs/cli": "^8.2.2",
"@nestjs/schematics": "^8.0.7",
"@reactive-resume/schema": "workspace:^",
"@types/express": "^4.17.13",
"@types/multer": "^1.4.7",
"@types/node": "^17.0.21",
@ -63,6 +62,7 @@
"ts-node": "^10.7.0",
"tsconfig-paths": "^3.13.0",
"typescript": "<4.6.0",
"webpack": "^5.70.0"
"webpack": "^5.70.0",
"@reactive-resume/schema": "workspace:*"
}
}

View File

@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config';
import { SchedulerRegistry } from '@nestjs/schedule';
import { mkdir, unlink, writeFile } from 'fs/promises';
import { nanoid } from 'nanoid';
import { join } from 'path';
import { join, resolve } from 'path';
import { PDFDocument } from 'pdf-lib';
import { Browser, chromium } from 'playwright-chromium';
@ -42,7 +42,7 @@ export class PrinterService implements OnModuleInit, OnModuleDestroy {
});
const pdf = await PDFDocument.create();
const directory = join(__dirname, 'assets', 'resumes');
const directory = resolve('dist/assets/resumes');
const filename = `RxResume_PDFExport_${nanoid()}.pdf`;
const publicUrl = `${serverUrl}/resumes/${filename}`;

10469
yarn.lock

File diff suppressed because it is too large Load Diff