Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Preparando uma API NodeJS para produção

Hoje vou mostrar o que deve ser feito para preparar sua aplicação NodeJS para o ambiente de produção. Mas, antes vamos criar um projeto para isso. Iniciando projeto A versão do NodeJS que estarei usando é v22.17.0 e usarei o pnp…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Hoje vou mostrar o que deve ser feito para preparar sua aplicação NodeJS para o ambiente de produção. Mas, antes vamos criar um projeto para isso.






Iniciando projeto



A versão do NodeJS que estarei usando é v22.17.0 e usarei o pnpm na versão v10.18.3 como o gerenciador de pacotes, mas você pode usar o npm ou o yarn se preferir.



Vamos iniciar um projeto com o comando init para gerar o package.json




pnpm init






Vou adicionar a chave "type": "module" para usarmos o ES Modules nos nossos arquivos.




{
"name": "node-prod",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module", // Usando ES Modules
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "[email protected]"
}









Instalando dependências



Vamos criar API REST, então precisamos instalar algumas dependências no projeto. Vamos ter dependências de produção, que ficam em dependencies e dependências de desenvolvimento, que ficam em devDependencies, tudo isso listado no package.json.



Vamos começar instalando as dependências de produção





  • express: criação do servidor HTTP


  • pino: geração de logs


  • @prisma/client: cliente do banco de dados


  • @prisma/adapter-pg: adaptador do postgres para o prisma client


  • pg: driver do banco PostgreSQL


  • dotenv: para acessar as variáveis de ambiente no .env


  • express-rate-limit: middleware contra ataque de força bruta


  • cors: middleware para configurar o CORS


  • helmet: middleware para adicionar cabeçalhos de segurança




pnpm add express pino @prisma/client @prisma/adapter-pg pg dotenv express-rate-limit cors helmet






Essas são as dependências que serão usadas no ambiente de produção. Agora vamos instalar as dependências que serão usadas apenas no ambiente de desenvolvimento.





  • typescript: superset do javascript que adiciona tipagem estática


  • prisma: biblioteca de ORM


  • tsx: para executar código typescript


  • @tsconfig/node22: configuração do typescript para o NodeJS v22


  • pino-pretty: para melhor visualização dos logs em desenvolvimento


  • @types/pg: tipagem do pg


  • @types/node: tipagem do NodeJS


  • @types/express: tipagem do express


  • @types/cors: tipagem do cors




pnpm add -D typescript prisma tsx @tsconfig/node22 @types/pg @types/node @types/express @types/cors pino-pretty






No pnpm há uma particularidade, algumas biblioteca têm um script postinstall que o pnpm bloqueia por segurança. Para desbloquear isso você precisa usar o comando pnpm approve-builds e escolher quais libs você permite rodar o script postinstall e digita y para rodar os scripts de postinstall.





Com isso, um arquivo pnpm-workspace.yaml também será criado listando as bibliotecas que podem executar o postinstall.




onlyBuiltDependencies:
- '@prisma/engines'
- esbuild
- prisma






O package.json ficou assim.




{
"name": "node-prod",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "[email protected]",
"dependencies": {
"@prisma/adapter-pg": "^7.2.0",
"@prisma/client": "^7.2.0",
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"express": "^5.2.1",
"express-rate-limit": "^8.2.1",
"helmet": "^8.1.0",
"pg": "^8.16.3",
"pino": "^10.1.0"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.5",
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/node": "^25.0.3",
"@types/pg": "^8.16.0",
"pino-pretty": "^13.1.3",
"prisma": "^7.2.0",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
}
}









Configurando typescript



Agora vamos configurar o typescript. Use o comando tsc --init para criar o arquivo tsconfig.json. E vamos usar a configuração que instalamos com o @tsconfig/node22, vamos definir o diretório de que irá ser gerado com o código compilado como dist e não vamos permitir a compilação se houver erros. Vamos usar o include para incluir tudo de src na pasta dist quando for gerada, se não seria criada uma pasta src dentro da pasta dist.




pnpm tsc --init






tsconfig.json




{
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"noEmitOnError": true
},
"include": ["src"]
}









Variáveis de ambiente



Agora vamos criar nossos arquivos typescript. Vamos começar com um arquivo src/env.ts para centralizar as variáveis de ambiente que usaremos.




export const env = {
port: Number(process.env.PORT) || 3000,
isProduction: process.env.NODE_ENV === "production",
databaseUrl: process.env.DATABASE_URL,
logLevel: process.env.LOG_LEVEL || "info"
};









Logger da aplicação



Agora vamos criar o logger para a nossa aplicação. Usaremos o pino que instalamos antes para isso. Vamos criar o arquivo src/logger.ts.



Na configuração do logger iremos definir o nível de log, para que mensagem de log que estejam abaixo daquele nível não apareçam. E vamos usar o pino-pretty quando não estivermos em ambiente de produção.




import pino from "pino";
import { env } from "./env.js";

export const logger = pino({
level: env.logLevel,
transport: env.isProduction ? undefined : { target: "pino-pretty" }
});









Banco de dados



Para a comunicação com o banco de dados vamos usar o Prisma como biblioteca de ORM e o PostgreSQL como banco de dados.



Primeiro precisamos configurar o prisma com o comando init do prisma.




pnpm prisma init






Esse comando irá criar o prisma/schema.prisma onde temos os esquemas, .env onde ficará as variáveis de ambiente, .gitignore para impedir que alguns arquivos sejam salvos pelo git e o prisma.config.ts onde terá a configuração da CLI do prisma.



No prisma/schema.prisma vamos criar a tabela de usuários. Usarei o @map para mudar o nome da coluna no banco e @@map para mudar o nome da tabela no banco.




generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}

datasource db {
provider = "postgresql"
}

model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@map("users")
}






Salve o arquivo e defina a URL de conexão com o banco de dados no arquivo .env e após isso gere a migração e os arquivos do prisma




// criando a migração
pnpm prisma migrate dev --name create-table-users


// gerando o PrismaClient
pnpm prisma generate






O prisma generate irá criar o diretório src/generated/prisma onde ficam os tipos definidos no schema.prisma e o PrismaClient que será usado para fazer as query no banco.



O próximo passo é criar o arquivo src/db.ts para criar uma instância do PrismaClient.




import { PrismaPg } from "@prisma/adapter-pg";
import { env } from "./env.js";
import { PrismaClient } from "./generated/prisma/client.js";

const adapter = new PrismaPg({ connectionString: env.databaseUrl! });
export const db = new PrismaClient({ adapter });









Rotas da aplicação



Vamos criar algumas rotas para testarmos a aplicação. Colocaremos logs para saber o que está acontecendo também.




import { Router } from "express";
import { logger } from "./logger.js";
import { db } from "./db.js";
import { PrismaClientKnownRequestError } from "./generated/prisma/internal/prismaNamespace.js";

const router = Router();

router.get("/", (req, res) => {
logger.info({ route: "/" }, "Health check endpoint called");

res.json({ status: "OK" });
});

router.post("/users", async (req, res) => {
const childLogger = logger.child({ route: "/users", method: "POST" });

try {
const { name, email } = req.body;

childLogger.debug({ data: { name, email } }, "Creating new user");

const newUser = await db.user.create({
data: {
name,
email
}
});

childLogger.info({ userId: newUser.id }, "New user created");

res.status(201).json(newUser);
} catch (error) {
childLogger.error({ error, route: "/users" }, "Error creating user");

res.status(500).json({ error: "Internal Server Error" });
}
});

router.get("/users", async (req, res) => {
const childLogger = logger.child({ route: "/users", method: "GET" });

try {
const users = await db.user.findMany();

childLogger.info({ userCount: users.length }, "Fetched users successfully");

res.json(users);

} catch (error) {
childLogger.error({ error }, "Error fetching users");

res.status(500).json({ error: "Internal Server Error" });
}
});

router.delete("/users/:id", async (req, res) => {
const childLogger = logger.child({ route: "/users/:id", method: "DELETE" });

try {
const userId = Number(req.params.id);

childLogger.debug({ userId }, "Deleting user");

await db.user.delete({
where: { id: userId }
});

childLogger.info({ userId }, "User deleted successfully");

res.status(204).send();
} catch (error) {
if (error instanceof PrismaClientKnownRequestError && error.code === "P2025") {
childLogger.warn({ error }, "User not found for deletion");

return res.status(404).json({ error: "User not found" });
}

childLogger.error({ error }, "Error deleting user");

res.status(500).json({ error: "Internal Server Error" });
}
});

export { router };









Servidor



Com tudo isso vamos montar nosso arquivo principal src/server.ts onde iremos criar o servidor e iniciá-lo.




import cors from "cors";
import express, { json } from "express";
import rateLimit from "express-rate-limit";
import helmet from "helmet";
import { env } from "./env.js";
import { logger } from "./logger.js";
import { router } from "./routes.js";

const app = express();

// middleware para parsear JSON
app.use(json());

// middleware de segurança
const oneMinute = 60 * 1000;
app.use(
helmet(),
cors({
origin: "*", // ajuste conforme necessário
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allowedHeaders: ["Content-Type", "Authorization"]
}),
rateLimit({
windowMs: 15 * oneMinute,
max: 100
})
);

// rotas
app.use(router);

app.listen(env.port, () => logger.info(`Server is running on port ${env.port}`));









Scripts



Vamos criar os scripts start, dev e build e vamos definir o arquivo de entrada na chave main do package.json




"main": "dist/server.js",
"scripts": {
"start": "node --env-file-if-exists=.env .",
"dev": "tsx --env-file-if-exists=.env src/server.ts",
"build": "tsc"
}









Testando



Inicie a aplicação em modo de desenvolvimento com o script dev e vamos iniciar com o nível de log como debug para ver todos os logs que foram criados.



.env




DATABASE_URL="postgresql://dev:dev@localhost:5432/node_prod_post"
NODE_ENV="development"
PORT=3000
LOG_LEVEL="debug"









pnpm dev








Irei fazer as requisições para a API usando a extensão do VSCode REST Client usando um arquivo client.http




@baseUrl = http://localhost:3000

GET {{baseUrl}}

###
POST {{baseUrl}}/users
Content-Type: application/json

{
"name": "John Doe",
"email": "[email protected]"
}

###
GET {{baseUrl}}/users

###
DELETE {{baseUrl}}/users/1






Fiz algumas requisições e os logs estão sendo gerados corretamente.








Preparando para produção



O código funciona em ambiente de desenvolvimento. Mas, em produção não teremos código typescript sendo executado ou nenhuma dependência de desenvolvimento instalada.



Primeiro vamos compilar o código para javascript usando o script build. Isso irá gerar uma pasta dist com o código compilado.



Agora vamos definir as variáveis de ambiente que serão usadas em produção que são a URL do banco de produção, o nível de log como "warn" e a NODE_ENV como "production" para ativar otimizações das bibliotecas.




DATABASE_URL="postgresql://dev:dev@localhost:5432/node_prod_post_production"
NODE_ENV="production"
PORT=3000
LOG_LEVEL="warn"






Como eu adicionei uma URL para outro banco de dados, preciso rodar as migrações para gerar as tabelas. Para produção, o prisma tem o comando prisma migrate deploy




pnpm prisma migrate deploy






Por fim, vamos desinstalar as dependências de desenvolvimento.




pnpm i --prod






Agora podemos iniciar o projeto com o script start.




pnpm start






O projeto iniciará silenciosamente no terminal. Como definimos o nível como 'warn', apenas avisos e erros críticos serão exibidos, evitando poluição visual e excesso de uso de disco em produção.





Outra mudança é que os logs são impressos em formato JSON. Embora seja difícil para humanos lerem, esse formato é ideal para ferramentas de monitoramento (como Datadog, CloudWatch ou Elastic Stack) indexarem e processarem as informações.



Um ponto que deve ser levado em conta é que nesse projeto o script start eu usei a flag --env-file-if-exists para usar o arquivo .env para definir as variáveis de ambiente, mas em um ambiente real as variáveis de ambiente não são definidas em um arquivo e sim injetadas diretamente no ambiente.






Conclusão



Com essas configurações, transformamos um simples setup de desenvolvimento em uma aplicação pronta para o mundo real. A diferença entre um projeto amador e um profissional muitas vezes está nesses detalhes: a remoção de dependências desnecessárias, a compilação correta do TypeScript e a estruturação de logs em JSON para ferramentas de observabilidade.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - Preparando uma API NodeJS para produção
id: 5e255333-6067-459d-8185-cd82fd17530d
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-26
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-26"
        description = "YARA Signature for "
    strings:
        $str = "Preparando uma API NodeJS para" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Preparando uma API NodeJS para produo")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Preparando uma API NodeJS para produo*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Preparando uma API NodeJS para produo"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Preparando uma API NodeJS para produção.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Preparando uma API NodeJS para produção

Thematisch verwandte Begriffe: Preparando, NodeJS, para, produção · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100620 | Capgo CLI (npm package @capgo/cli) through 7.98.2 is affected by an ove…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag