10 Essential Steps to Organize Node.js Projects on Cloudways
When you decide to deploy your Node.js project on a managed cloud hosting platform like Cloudways, you’re already making your life easier. No more provisioning and managing infrastructure from scratch. No more endlessly debugging why Nginx isn’t proxying correctly or why SSL broke after a system update.
But while Cloudways handles the server headaches, the structure of your Node.js project can still make or break your app’s maintainability, scalability, and performance. A poorly structured app will feel like untangling Christmas lights every time you want to make a change.
Why Project Structure Matters on Cloudways
Before we dive into the best practices, let’s quickly understand why this even matters on Cloudways:
- Cloudways gives you pre-configured environments (Node.js, PM2, Nginx, etc.). A well-organized app deploys smoothly without extra fiddling.
- One-click staging and deployment work better when your app has predictable structure.
- Performance monitoring tools on Cloudways become easier to use when logs and resources follow conventions.
- Scaling or handing over your project to a team? A clean structure saves onboarding time and reduces bugs.
1. Use a Modular Folder Structure
A modular structure separates concerns — routes, controllers, services, and configurations — making your app easier to maintain and test. Here’s a solid baseline:
/my-node-app
│
├── /src
│ ├── /config # All configuration files
│ ├── /controllers # Route logic
│ ├── /routes # API endpoint definitions
│ ├── /services # Business logic / DB operations
│ ├── /middlewares # Express middlewares
│ ├── /models # Mongoose/Sequelize models
│ ├── /utils # Utility functions
│ └── app.js # Express app setup
│
├── /public # Static assets (if any)
├── .env # Environment variables
├── server.js # Entry point
├── package.json
└── README.md
Why this structure works well on Cloudways:
- You can SSH into your Cloudways server and instantly find what you need.
- If you need to run a specific script using PM2 or node, you know exactly where the entry point (
server.js
) is. - It’s scalable. Adding features doesn’t mean re-writing your whole app.
2. Environment-Specific Configurations
Cloudways lets you set environment variables via SSH or directly through its UI (via .env
file). But you should also make your code environment-aware.
Best practice:
Use dotenv
and a config loader that switches settings based on process.env.NODE_ENV
.
// src/config/index.js
const dev = require('./dev');
const prod = require('./prod');
const config = process.env.NODE_ENV === 'production' ? prod : dev;
module.exports = config;
Then in your main file:
require('dotenv').config();
const config = require('./src/config');
Cloudways makes it easy to upload .env
files or even manage them via SSH, so keep your app clean by abstracting these configs.
3. Use PM2 with Watch and Logs
Cloudways comes with PM2 pre-installed. Use it.
Why PM2 is awesome on Cloudways:
- Automatically restarts your app if it crashes.
- Logs memory and CPU usage.
- Helps with zero-downtime deployments.
- Let’s you easily run background jobs or workers.
How to start your app with PM2:
pm2 start server.js --name "my-node-app"
To auto-start on reboot:
pm2 startup
pm2 save
And to view logs:
pm2 logs
Add a ecosystem.config.js
file for better management:
module.exports = {
apps: [{
name: "my-node-app",
script: "server.js",
watch: true,
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
};
Upload this file to your app root on Cloudways and you’re good to go.
4. Use a tests/
Directory with Minimal Setup
Even if you’re not TDD-focused, you should have a /tests
directory to hold basic unit/integration tests. Jest, Mocha, or even plain assertions are fine — the goal is organization, not perfection.
/my-node-app
│
├── /tests
│ ├── routes.test.js
│ └── auth.test.js
Cloudways doesn’t run your tests automatically — but having them means:
- You can SSH into your app and run
npm test
before deployments. - You can integrate GitHub Actions or any CI tool that deploys to Cloudways.
5. Keep Your Root Directory Clean
Resist the urge to drop everything in the root. Here’s what should stay in the root:
server.js
.env
package.json
README.md
ecosystem.config.js
(for PM2)
Everything else (models, routes, etc.) should live inside /src
.
This practice ensures that when you deploy via Git, or clone the repo directly into your Cloudways instance, there’s minimal clutter.
6. Use Middleware Efficiently
On Cloudways, performance matters. Middleware should be purposeful.
Good middleware practice:
// src/middlewares/errorHandler.js
function errorHandler(err, req, res, next) {
console.error(err.stack);
res.status(500).send({ message: 'Something broke!' });
}
module.exports = errorHandler;
Then plug it into your app:
const errorHandler = require('./middlewares/errorHandler');
app.use(errorHandler);
Keep all middlewares in /middlewares
. Don’t clutter app.js
with logic. This ensures that performance bottlenecks can be diagnosed faster using Cloudways’ New Relic integration or logs.
7. Database Config: Centralize and Secure
Whether you’re using MongoDB, PostgreSQL, or MySQL (Cloudways supports all via managed services), always keep DB logic out of your routes.
Structure:
/src
└── /database
├── connect.js
└── seed.js
Then you import it cleanly:
const connectDB = require('./database/connect');
connectDB();
Cloudways lets you easily provision managed databases, and they provide internal hostnames, which you can safely store in your .env
:
DB_HOST=localhost
DB_USER=cloudwaysuser
DB_PASS=securepassword
8. Automate Deployment with Git + SSH
Cloudways supports Git-based deployment, but a good structure is key.
Steps:
- Initialize Git repo.
- Add
.gitignore
to excludenode_modules
,logs/
,.env
, etc. - Add your Cloudways SSH key (you get it from the UI).
- Deploy via Git and restart using PM2.
You can even set Git Webhooks so every push to main
auto-deploys. But this works best when your app has a consistent structure and doesn’t rely on manual scripts.
9. Handle Static Files and Proxying Properly
If you’re serving a frontend with your Node.js backend, place your build/
or public/
folder cleanly at the root, and serve like this:
app.use(express.static(path.join(__dirname, 'public')));
If you’re reverse-proxying via Nginx (Cloudways handles this automatically), don’t forget:
- Avoid relative paths in frontend builds.
- Test URLs after deployment.
- Use
res.sendFile()
properly when serving HTML.
10. Integrate Cloudways Tools With Ease
Once your structure is ready, you’ll find it super easy to plug into the powerful stack Cloudways offers:
- New Relic: For performance tracing. Set up an organized codebase first.
- Bot Protection: Helps if you serve static or public APIs.
- Cron Job Manager: Works great with a structured app where background jobs live in
/jobs/
folder. - Cloudflare + SSL: With a well-organized app, switching domains, SSL, or CDN takes <5 minutes.
Final Touch: Adding a Signup Prompt (Naturally)
Now that you’ve seen how streamlined Cloudways makes Node.js deployments — especially when you structure your app right — the next logical step is to try it out yourself.
Cloudways offers a free trial, no credit card required, and it supports all major cloud providers (DigitalOcean, AWS, GCP, etc.). The performance and simplicity are truly game-changing.
If you’re looking to set up your Node.js app on a production-grade server in under 10 minutes, Cloudways is the way to go.
Set up your app now and enjoy worry-free deployment, zero-downtime scaling, and blazing speed.
Wrapping Up
Organizing your Node.js project before deploying on Cloudways isn’t just “good practice” — it’s the foundation for scaling, debugging, and working with teams. Here’s what to remember:
→ Keep a modular structure
→ Use .env
and centralized config
→ Use PM2 for process management
→ Keep your root clean
→ Integrate with Cloudways tools
→ Automate deployments via Git
→ Make the most of Cloudways' staging and scaling options
Take a few hours to reorganize your app today — and you’ll save dozens of hours later.
You may also like:
1. 5 AI Developer Tools to Double Your Coding Speed
2. 7 Best Practices for Sanitizing Input in Node.js
3. How to Deploy a Dockerized Node.js App on Google Cloud Run
4. Top 10 Node.js Middleware for Efficient Coding
5. What is GeoIP Rate-Limiting in Node.js on Cloudways?
6. 6 Common Misconceptions About Node.js Event Loop
7. Yarn vs NPM vs PNPM: Which is Best for Your Project?
8. How Do I Fix Performance Bottlenecks in Node.js?
9. Mastering Microservices: gRPC with Node.js Explained
10. Top 10 Large Companies Using Node.js for Backend
Read more blogs from Here
You can easily reach me with a quick call right from here.
Share your experiences in the comments, and let’s discuss how to tackle them!
Follow me on LinkedIn