Um projeto monorepo que permite pesquisar vagas de emprego no LinkedIn de forma automatizada, com backend em NestJS para scraping e frontend em Next.js para interface web.
linkedin-job-searcher/
│
├─ package.json # Configuração do monorepo e workspaces
├─ pnpm-workspace.yaml # Configuração do pnpm workspaces
├─ apps/
│ ├─ backend/ # Backend NestJS
│ │ ├─ src/
│ │ │ ├─ jobs/ # Módulo de scraping de vagas
│ │ │ ├─ app.module.ts
│ │ │ └─ main.ts
│ │ └─ package.json
│ └─ frontend/ # Frontend Next.js
│ ├─ src/
│ └─ package.json
└─ packages/ # Bibliotecas compartilhadas (opcional)
└─ common/
- Node.js (>= 20)
- pnpm (para gerenciar workspaces):
npm install -g pnpm- Instalar dependências do monorepo:
pnpm install- Gerar módulos, controllers e services (já feito para o módulo
jobs):
pnpm dlx @nestjs/cli g mo jobs
pnpm dlx @nestjs/cli g s jobs
pnpm dlx @nestjs/cli g co jobsPara rodar backend e frontend simultaneamente com auto-refresh:
- Instalar
concurrentlyna raiz (para rodar os dois apps juntos):
pnpm add -D concurrently -w- Adicionar scripts no
package.jsonda raiz:
"scripts": {
"dev:backend": "pnpm --filter backend dev",
"dev:frontend": "pnpm --filter frontend dev",
"dev": "concurrently \"pnpm dev:backend\" \"pnpm dev:frontend\""
}- Rodar:
pnpm dev- Backend: NestJS (
http://localhost:3000) - Frontend: Next.js (
http://localhost:3001ou3000)
Cada app tem seu próprio package.json.
- Backend:
cd apps/backend
pnpm add axios cheerio- Frontend:
cd apps/frontend
pnpm add axios tailwindcssO pnpm workspace gerencia separadamente cada app.
No package.json da raiz:
"scripts": {
"build:backend": "pnpm --filter backend build",
"build:frontend": "pnpm --filter frontend build",
"build": "pnpm build:backend && pnpm build:frontend"
}build:backend→ criadist/build:frontend→ cria.next/
"scripts": {
"start:backend": "pnpm --filter backend start:prod",
"start:frontend": "pnpm --filter frontend start",
"start:prod": "concurrently \"pnpm start:backend\" \"pnpm start:frontend\""
}jobs/→ Módulo responsável por buscar vagas no LinkedIn via scrapingjobs.service.ts→ Lógica do scraping usandoaxios+cheeriojobs.controller.ts→ EndpointGET /jobs/searchque recebe parâmetros comokeywords,locationetimeFilter(r3600,r1800, etc.)search-jobs.dto.ts→ DTO com parâmetros de busca
Exemplo de endpoint:
GET /jobs/search?keywords=Node.js&location=Natal, RN&timeFilter=3600
Retorna JSON com as vagas mais recentes.
- Landing page
/→ Apresenta o projeto - Página de pesquisa
/jobs→ Exibe vagas com filtros e cards, inspirada no LinkedIn Jobs - Estilização com Tailwind CSS
- Componentes organizados em
src/components/
O projeto utiliza GitHub Actions para automação de CI/CD. O workflow está configurado em .github/workflows/ci-cd.yml e inclui:
- Checkout do código
- Setup do Node.js v20
- Instalação do pnpm v10.15.0
- Cache de dependências para builds mais rápidas
- Instalação de dependências
- Linting do backend e frontend
- Testes do backend
- Build de ambas as aplicações
- Testes Docker que verificam se os containers Docker funcionam corretamente:
- Construção das imagens Docker
- Inicialização dos containers
- Verificação de acessibilidade dos serviços backend e frontend
- Encerramento dos containers
O pipeline é executado automaticamente em:
- Push para as branches
mainoumaster - Pull requests para as branches
mainoumaster
O deploy em produção é otimizado para VPS com recursos limitados:
- Build das imagens Docker no CI: As imagens Docker são construídas no ambiente do GitHub Actions, não na VPS
- Exportação das imagens: As imagens são exportadas para arquivos .tar
- Transferência via SSH: Os arquivos são transferidos para a VPS via SSH
- Carregamento das imagens: Na VPS, as imagens são carregadas do arquivo .tar
- Inicialização dos containers: Os containers são iniciados usando docker-compose
Esta abordagem evita o consumo excessivo de recursos na VPS durante o processo de build das imagens Docker.
O projeto está configurado para ser executado em containers Docker, facilitando a implantação e garantindo consistência entre ambientes.
apps/backend/Dockerfile- Configuração para construir a imagem do backend NestJSapps/frontend/Dockerfile- Configuração para construir a imagem do frontend Next.jsdocker-compose.yml- Orquestração dos serviços backend e frontend.dockerignore- Exclui arquivos e diretórios desnecessários do contexto de build (como node_modules)
- Construir e iniciar os containers:
docker-compose up -d --buildPara ambientes de produção com recursos limitados, as imagens são pré-construídas pelo CI/CD:
- As imagens são construídas no ambiente CI
- As imagens são transferidas para a VPS
- Iniciar os containers (sem build):
docker-compose up -dApós iniciar os containers (tanto em desenvolvimento quanto em produção):
- Backend:
http://localhost:3000 - Frontend:
http://localhost:3001
Para parar os containers:
docker-compose downO arquivo docker-compose.yml já configura as variáveis de ambiente necessárias:
-
Backend:
NODE_ENV=production- Define o ambiente de execução
-
Frontend:
NODE_ENV=production- Define o ambiente de execuçãoNEXT_PUBLIC_API_URL=http://backend:3000- URL da API do backend
Para adicionar mais variáveis de ambiente, edite o arquivo docker-compose.yml ou crie arquivos .env nas pastas dos respectivos serviços.
- O arquivo
.dockerignoreé essencial para excluir o diretórionode_modulesdo contexto de build do Docker, evitando problemas com permissões de arquivos e modos de arquivo desconhecidos durante o processo de build.
- Mantenha o monorepo organizado: cada app dentro de
apps/e libs compartilhadas empackages/. - Sempre usar pnpm install na raiz do monorepo.
- Para adicionar novas bibliotecas a um app específico, vá para a pasta do app e use
pnpm add <package>. - Use o endpoint do backend para popular a página de pesquisa do frontend.