Pontos-chave
- O Express.js é um framework persistente que requer um conjunto de ligações sempre ativo, o que o torna pouco adequado para alojamento sem servidor, especialmente com uma base de dados como o PostgreSQL.
- A hospedagem VPS bare-metal exige a configuração manual do Nginx, do PM2 e do SSL, enquanto as plataformas sem servidor criam novas instâncias a cada pedido e podem esgotar os limites de ligação do Postgres.
- Um ambiente Node.js gerido e persistente, como o Cloudways Velocity, mantém o processo do Express ativo e o conjunto de ligações à base de dados aberto, sem necessidade de administração manual do servidor.
- Este guia explica passo a passo como criar uma API local do Express e do PostgreSQL Task Manager, enviá-la para o GitHub e implementá-la em produção no Cloudways Velocity.
O localhost é fácil. É sempre assim. Ligas a tua base de dados, defines alguns endpoints REST, executas o teu script Node e tudo parece incrivelmente rápido.
Depois, quando tentas mesmo colocar esse backend do Express na Internet, de repente tens de tomar uma decisão sobre a infraestrutura, e as opções padrão costumam deixar-te frustrado.
Ou alugas um servidor Linux vazio e passas o fim de semana a fazer de administrador de sistemas sem receber nada, ou colocas o código numa plataforma edge sem servidor que põe a tua API em modo de suspensão assim que as pessoas deixarem de a usar.
Se estiveres a ligar uma base de dados relacional como o PostgreSQL, a hospedagem sem servidor efémera vai dar-te uma enorme dor de cabeça. Precisas de um backend persistente.
Vou explicar passo a passo como criar uma API rápida do Gestor de Tarefas com o Express e implementá-la diretamente num servidor Node.js (Velocity) gerido pela Cloudways com armazenamento persistente. Sem configurações do Nginx para depurar. Sem arranques a frio em ambientes serverless. Apenas uma hospedagem fiável do Express.js.
VPS «bare-metal» vs. alojamento «serverless» para o Express
Vamos dar uma olhadela nos dois extremos da hospedagem Node e perceber porque é que nenhum deles é perfeito para uma API padrão.
De um lado, tens o VPS «bare-metal» puro. Recebes um endereço IP, acesso root e zero ajuda. Para pôr uma aplicação Express a funcionar aqui, tens de instalar o Node manualmente. Tens de te debater com os bloqueios do proxy reverso do Nginx só para expor a porta 3000 à web. Tens de configurar o PM2 para gerir os processos em segundo plano e és totalmente responsável pelos teus próprios certificados SSL. É uma enorme perda de tempo.
Por isso, toda a gente acaba por migrar para plataformas sem servidor. Basta carregares o repositório e o fornecedor de serviços na nuvem trata do resto.
Mas aqui está o senão. O Express é, na essência, um framework persistente. Ele quer ficar ativo. Quer manter um conjunto de ligações à base de dados aberto na RAM para não ter de estabelecer ligação constantemente com a tua base de dados.
As plataformas sem servidor encerram a tua aplicação quando o tráfego web diminui. Quando um novo utilizador acede ao ponto final, a nuvem cria uma nova instância do zero. Essa nova instância tem de estabelecer uma ligação totalmente nova à tua base de dados Postgres.
O Postgres tem um limite rígido para o número de ligações simultâneas. Se a tua API receber 150 pedidos ao mesmo tempo, uma plataforma sem servidor vai ativar 150 instâncias separadas. Todas elas tentam ligar-se à base de dados ao mesmo tempo. O Postgres entra em pânico, atinge o seu limite de ligações e o teu backend fica completamente fora de serviço.
Por que é que um servidor Node.js persistente é a melhor opção
Este estrangulamento na ligação à base de dados é exatamente a razão pela qual precisas de um ambiente Node persistente.
Um servidor dedicado nunca coloca o teu processo Express em modo de espera. Ele mantém-se ativo. Como o processo nunca se desliga, consegue manter aberto indefinidamente um único conjunto de ligações à base de dados, altamente eficiente. Quando chega uma consulta, não há atrasos na inicialização. Os dados são transferidos instantaneamente.
Usar um ambiente gerido como o Cloudways Velocity dá-te essa potência constante sem o pesadelo do DevOps. A plataforma trata do encaminhamento por proxy, da gestão de processos e das atualizações de segurança automaticamente. Basta enviares o código para o teu repositório e o servidor mantém tudo a funcionar.
Cria um ambiente Node.js persistente em poucos minutos
O Cloudways Velocity mantém o teu processo Express ativo, para que as tuas ligações à base de dados nunca sejam reiniciadas.
Miniprojeto: Criar uma API de gerenciamento de tarefas
Vou construir uma API minimalista para gerenciamento de tarefas. Vou escrever um backend personalizado em Express que lida com operações CRUD básicas e se conecta a um banco de dados PostgreSQL.
Configurar o projeto local
A primeira coisa que vou fazer é configurar o meu espaço de trabalho local.
Estou a usar o meu portátil do trabalho para esta demonstração, que tem restrições de TI, por isso não consigo executar o instalador padrão do Node. Em vez disso, vou descarregar a versão binária autónoma do Node.js num ficheiro .zip para o meu computador.
Depois de descompactar a pasta do Node, vou indicar ao Prompt de Comandos onde ela está na minha máquina. Para isso, vou executar este comando com o caminho exato:
set PATH=%PATH%;C:\Users\abdulrehman\Downloads\node-v24.18.0-win-x64\node-v24.18.0-win-x64
Ótimo, agora já posso executar os comandos do Node e do npm.
A seguir, vou criar uma pasta de projeto no meu ambiente de trabalho.
cd C:\Users\abdulrehman\Desktop mkdir cloudways-express-api

cd cloudways-express-api npm init -y

A seguir, vou instalar as dependências. Preciso do Express para o encaminhamento. Preciso do CORS para pedidos entre origens. Também preciso do dotenv para as variáveis de ambiente locais e do pg para me ligar ao PostgreSQL.
npm install express cors dotenv pg

Também preciso de uma base de dados local para testar o miniprojeto. Mas, mais uma vez, como estou a usar o portátil do escritório, vou descarregar e descompactar a versão .zip autónoma na minha pasta de downloads.
E, tal como da última vez, vou indicar ao CMD onde estão as ferramentas do Postgres no meu computador:
set PATH=%PATH%;C:\Users\abdulrehman\Downloads\postgresql-18.4-2-windows-x64-binaries\pgsql\bin
![]()
Agora, já posso inicializar o cluster da base de dados local. Execuo isto para criar uma nova pasta de dados dentro desse diretório extraído:
initdb.exe -D "C:\Users\abdulrehman\Downloads\postgresql-18.4-2-windows-x64-binaries\pgsql\data" -U postgres -W
Depois de executar o comando, o PostgreSQL pede-me para definir uma palavra-passe de superutilizador. Vou guardá-la algures, pois vou precisar dela mais tarde.

Aquela opção -W no final é super importante. Obriga o terminal a fazer uma pausa e a pedir uma nova palavra-passe de superutilizador. Digitei apenas uma palavra-passe simples para usar nos meus testes locais.
A seguir, preciso de ligar o servidor de bases de dados para que funcione silenciosamente em segundo plano:
pg_ctl.exe -D "C:\Users\abdulrehman\Downloads\postgresql-18.4-2-windows-x64-binaries\pgsql\data" -l logfile start

O servidor já está a funcionar, mas está completamente vazio. A minha aplicação Express precisa de uma base de dados específica para se ligar, por isso vou criar uma chamada task_api_db:
createdb.exe -U postgres task_api_db

E pronto. A minha base de dados local já está totalmente operacional nesta fase.
A criar o servidor Express
Para testar a persistência em condições reais, manter um conjunto de ligações ao PostgreSQL ativo é o teste de carga perfeito. Vou abrir o meu editor e criar um ficheiro server.js. Vou colar aqui o meu script personalizado:
// server.js
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const { Pool } = require('pg');
const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.use(express.json());
// Initialize PostgreSQL Connection Pool
// This relies on the environment variable we will set in Cloudways
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
// If the URL contains 'localhost', turn SSL off. Otherwise, turn it on for Cloudways.
ssl: process.env.DATABASE_URL.includes('localhost') ? false : { rejectUnauthorized: false }
});
// Initialize the database table on startup
const initDB = async () => {
const createTableQuery = `
CREATE TABLE IF NOT EXISTS tasks (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
completed BOOLEAN DEFAULT FALSE
);
`;
try {
await pool.query(createTableQuery);
console.log("Database table initialized successfully.");
} catch (err) {
console.error("Error creating table:", err);
}
};
initDB();
// API Route: Get all tasks
app.get('/api/tasks', async (req, res) => {
try {
const result = await pool.query('SELECT * FROM tasks ORDER BY id DESC');
res.json(result.rows);
} catch (err) {
res.status(500).json({ error: 'Failed to fetch tasks' });
}
});
// API Route: Create a new task
app.post('/api/tasks', async (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({ error: 'Title is required' });
}
try {
const result = await pool.query(
'INSERT INTO tasks (title) VALUES ($1) RETURNING *',
[title]
);
res.status(201).json(result.rows[0]);
} catch (err) {
res.status(500).json({ error: 'Failed to create task' });
}
});
// Start the persistent server
app.listen(port, () => {
console.log(`Express API listening on port ${port}`);
});

A lógica aqui é extremamente importante. Dá uma olhadela com atenção à configuração da ligação ao PostgreSQL . Ao usar o `process.env.DATABASE_URL`, estou a dizer explicitamente ao Express para usar uma variável de ambiente para a base de dados.
Se eu fosse hospedar isto numa plataforma «serverless» normal, desativar e recriar este conjunto de ligações a cada pedido criaria imediatamente um estrangulamento na base de dados. É absolutamente necessário um processo Node.js ativo e persistente para manter o conjunto de ligações ativo.
Para testar o que criei localmente, vou criar um novo ficheiro chamado .env dentro da pasta do meu projeto, colar lá a minha cadeia de ligação local ao Postgres e executar o comando `node server.js`.
DATABASE_URL=postgres://postgres:your_password_here@localhost:5432/task_api_db


Depois de executares o comando `node server.js`, o terminal mostra uma confirmação de que a tabela da base de dados foi inicializada.
Para ver a API a funcionar, abro o meu navegador e vou até http://localhost:3000/api/tasks.
A página carrega um par de parênteses vazio: [].

Era exatamente isto que eu esperava ver. Significa que o Express fez a consulta à base de dados Postgres com sucesso e que a base de dados respondeu corretamente que a tabela está vazia.
Para verificar se a base de dados consegue guardar dados, abro uma segunda janela do Prompt de Comandos e envio um pedido POST rápido usando o cURL:
curl -X POST http://localhost:3000/api/tasks -H "Content-Type: application/json" -d "{\"title\":\"Finish the Cloudways deployment!\"}"

Quando volto ao meu navegador e atualizo a página, os parênteses vazios já não aparecem. Em vez disso, agora consigo ver {“id”:1,”title”:”Concluir a implementação no Cloudways!”,”completed”:false}.
Isto significa que o meu servidor Express local recebeu com sucesso o pedido POST, analisou a carga JSON, executou a consulta de inserção SQL e guardou a tarefa na minha base de dados PostgreSQL local.
O mini-projeto está totalmente operacional na minha máquina local. Agora posso enviar este código para o Git e implementá-lo no Cloudways Velocity.
Enviar o projeto para o GitHub
Antes de enviar, vou abrir o meu Arquivo package.json e adiciona manualmente um script de arranque. Deve ficar exatamente assim:
"scripts": {
"start": "node server.js"
}
O meu código atualizado vai ficar assim:
{
"name": "cloudways-express-api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"cors": "^2.8.6",
"dotenv": "^17.4.2",
"express": "^5.2.1",
"pg": "^8.23.0"
}
}

O comando «start» é fundamental. A Cloudways procura exatamente esta palavra-chave ao configurar o servidor de produção.
Vou ao GitHub e, depois, vou criar um novo repositório. Vou chamá-lo de cw-velocity-express-api.

Depois, volto ao meu prompt de comandos e envio o projeto para o meu repositório do GitHub:
git init git add . git commit -m "Initial commit: Express Task API with PostgreSQL" git branch -M main git remote add origin https://github.com/abdulrehman293/cw-velocity-express-api git push -u origin main

Agora que o meu código está bem guardado no sistema de controlo de versões, está na hora de tratar da infraestrutura.
Implementar o Mini Project no Cloudways Velocity
Implementar uma aplicação Node.js personalizada em servidores VPS bare-metal normalmente implica configurar o Nginx como proxy reverso, manter o PM2 a funcionar e tratar dos certificados SSL.
O Cloudways Velocity trata dessas tarefas do lado do servidor sozinho. Oferece um ambiente Node.js gerido, onde a configuração do servidor subjacente é tratada por ti, e também provisiona uma base de dados PostgreSQL como parte da configuração.
De volta à implementação. Vou abrir a consola do Cloudways, selecionar o Velocity e, em seguida, clicar em «Começar».

Para esta implementação, vou escolher o plano Starter, que é mais do que suficiente para esta demonstração.

A seguir, ligo a minha conta do GitHub, seleciono o meu repositório cw-velocity-express-api e clico em «Continuar».


Agora, o Cloudways vai escolher tudo automaticamente por mim. Por exemplo, procura o ficheiro package.json na raiz do projeto. A partir daí, lê as dependências, deteta o Express e seleciona automaticamente a predefinição adequada para o framework Express.
Não preciso de criar comandos de arranque personalizados nem de configurar o PM2 manualmente. A plataforma trata disso tudo como parte da implementação.
Tudo o que preciso de fazer é adicionar uma variável de ambiente para inserir de forma segura as minhas credenciais da base de dados diretamente no processo Node de produção.

Mas, para fazer isso, primeiro tenho de implementar a aplicação. Assim que a implementação estiver concluída, posso aceder aos detalhes da base de dados da minha aplicação e criar a minha cadeia de ligação para adicionar à variável de ambiente, utilizando este formato:
postgres://[Username]:[Password]@localhost:5432/[DB Name]
Por isso, vou clicar em «Deploy Now» por agora e deixar que a implementação termine.


Agora que a aplicação está implementada, vou abrir a minha aplicação no Cloudways e clicar no separador «Database ».

Como usei o PostgreSQL na implementação local, vou ligar o PostgreSQL ao Cloudways.

Depois de ligado, já consigo ver o nome da base de dados, o nome de utilizador e a palavra-passe do PostgreSQL. Vou usar isto para criar a minha cadeia de ligação, de que falei há pouco.

Vou pegar na cadeia de ligação que criei e adicioná-la como variável de ambiente no Cloudways, assim:

Agora que está tudo pronto, vou voltar ao separador «Visão geral» da aplicação e copiar o URL da aplicação. Vou abri-lo no navegador e adicionar /api/tasks ao final do URL para testar a API.

Um array JSON vazio carrega instantaneamente, tal como acontecia no ambiente local.

Para testar o armazenamento de dados reais, abro o Prompt de Comandos e envio um pedido POST para o meu URL ativo do Cloudways:
curl -X POST https://nodejs-1658614-6605116.cloudwaysnodeapps.com/api/tasks -H "Content-Type: application/json" -d "{\"title\":\"Live test on Cloudways Node.js hosting Velocity!\"}"
![]()
Quando atualizo a página agora, consigo ver a tarefa que enviei através da solicitação POST.

E para verificar se foi guardada na base de dados PostgreSQL no Cloudways, vou abrir o gestor de bases de dados.

Aqui consigo ver a tabela de tarefas e também a tarefa guardada com o seu ID na base de dados.

E com isto, estou a experimentar uma instância Express a sério, sempre ativa. Sem tempos de espera na ligação. Sem arranques a frio.
Pronto para implementar a tua própria API Express?
Liga o teu repositório do GitHub e deixa que o Cloudways Velocity trate da configuração do servidor por ti.
Conclusão:
E assim chega ao fim este guia de implementação do Express.js. Expliquei porque é que um ambiente Node.js persistente pode ser a melhor opção para APIs que precisam de um desempenho consistente, especialmente quando a aplicação depende de manter as ligações à base de dados ativas.
Também criei uma API Express que se liga ao PostgreSQL localmente, testei o projeto, enviei-o para o GitHub e, depois, implementei a aplicação final utilizando o serviço de alojamento gerido Node.js da Cloudways (Velocity).
O projeto completo está disponível no meu GitHub, caso queiras usá-lo como ponto de partida para a tua própria aplicação Express.js. Se tiveres algum problema com os passos de configuração ou implementação, não hesites em deixar uma pergunta nos comentários.
P. Para que é que o ExpressJS serve, exatamente?
O Express.js é um framework web minimalista para o Node.js. Os programadores usam-no para criar APIs de backend, processar pedidos HTTP e gerir o encaminhamento. Funciona como o motor de backend para aplicações de página única e serviços web complexos.
P. O ExpressJS é um servidor?
Não. O Express.js é um framework que funciona dentro do ambiente de execução do Node.js. O framework fornece o encaminhamento e a estrutura. É o Node.js que cria e gere fisicamente o processo do servidor HTTP propriamente dito.
P. Por que é que o ExpressJS é tão popular?
É incrivelmente leve e neutro. Não impõe uma estrutura de diretórios rígida. Não exige a utilização de um ORM específico. Essa flexibilidade permite que as equipas criem rapidamente protótipos de back-ends usando qualquer base de dados que escolherem.
P. O Express
.
js é RESTful?
Sim. Os programadores usam muito o Express.js para criar APIs RESTful. A sua arquitetura central encaminha métodos HTTP padrão, como GET, POST, PUT e DELETE, para pontos finais de URL específicos. Isso torna-o ideal para criar interfaces REST simples e sem estado.
Start Growing with Cloudways Today.
Our Clients Love us because we never compromise on these
[email protected]
O Abdul é um profissional de marketing experiente em tecnologia, movido a café e criativo, que adora manter-se a par das últimas actualizações de software e gadgets tecnológicos. É também um escritor técnico competente que consegue explicar conceitos complexos de forma simples para um público alargado. Abdul gosta de partilhar os seus conhecimentos sobre a indústria da nuvem através de manuais de utilizador, documentação e publicações em blogues.