The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
The dependable way to install the MEAN stack on a Linux VPS is to use a supported Ubuntu LTS image, pin compatible Node.js, Angular CLI and MongoDB versions, run Express privately, serve the Angular build through NGINX on ports 80 and 443, and keep the API alive with PM2. You can self-host MongoDB or use MongoDB Atlas; in either case, keep the connection string in MONGODB_URI, not in source code.
What the MEAN stack contains
MEAN is a JavaScript and TypeScript web stack with four layers:
Recommended Free Tools
| Component | Layer | Role in a VPS deployment |
|---|---|---|
| MongoDB | Data | Stores application documents and serves queries to the API. |
| Express.js | Server and application | Defines HTTP routes, validates requests, applies middleware and talks to MongoDB. |
| Angular | Presentation | Compiles the browser application into static HTML, CSS and JavaScript files. |
| Node.js | Runtime | Runs Express and the build tooling on the server. |
In production, the browser normally reaches NGINX first. NGINX returns Angular’s compiled files and forwards an API prefix such as /api to Express on an internal loopback port. MongoDB should not be exposed to the public internet.
Decide versions and topology before installing
Write down the Ubuntu release, Node.js LTS release, Angular CLI version, MongoDB major version and Express port before creating the application. MEAN.JS documentation warns that unsupported preinstalled versions can break a project, and Angular, Node.js and MongoDB compatibility changes over time. Use one version policy for development and production rather than accepting whatever a package manager happens to provide.
#1 Best Overall
Supported operating-system image
Choose an Ubuntu LTS image that is still supported by your VPS provider and by the MongoDB release you intend to install. A provider’s one-click image may use a different Ubuntu release or filesystem layout than a fresh VPS, so inspect its manifest before copying commands from a tutorial.
Node.js and Angular compatibility
Install the current Node.js LTS (or the exact version required by the application) and record the result of node --version and npm --version. MongoDB’s current framework quick start asks for Node.js and recommends the Latest LTS or Latest Release for that guide. Treat that recommendation as a starting point, not permission to mix arbitrary versions with an older Angular project.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsChoose the database location
You have two supported patterns:
- MongoDB on the VPS: you control the service, disk, upgrades, backups and authentication.
- MongoDB Atlas: the database is managed for you; you copy its URI, restrict network access to the VPS, and store the URI as
MONGODB_URI.
Do not run both merely because both are easy to install. Select one connection target and test it from the VPS before putting the API behind NGINX.
Prepare the Linux VPS securely
Use a non-root deployment account for application work. Keep root access for system administration only, and use SSH keys rather than a password wherever the provider supports it.
- Connect as the initial administrator. Use the provider’s SSH details, then update the package index and installed packages:
sudo apt update && sudo apt upgrade -y - Create a deploy user. Replace
deploywith your chosen account name:sudo adduser deploy
sudo usermod -aG sudo deploy - Install the deploy user’s SSH key. Copy the public key into
/home/deploy/.ssh/authorized_keys, set ownership todeploy:deploy, and use mode700on the directory and600on the key file. Open a second SSH session as this user before changing the administrator’s access. - Allow only required firewall ports. A typical web VPS needs SSH, HTTP and HTTPS:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Do not open MongoDB’s default port to the internet. If you use Atlas, allow the VPS’s outbound connection and add only the VPS address to the Atlas network-access list. - Set a hostname and time zone. A stable hostname makes logs and TLS administration easier. Confirm the system clock is synchronized before issuing certificates.
The documented UFW pattern for a provider MEAN image allows 22, 80 and 443. Your provider may add rules, so inspect sudo ufw status numbered instead of assuming the image is hardened.
Install Node.js and npm
Use the installation method recommended for your selected Ubuntu release: the distribution package, a provider-supported Node repository, or a version manager approved by your operations policy. Avoid installing one Node version for the shell and a different one for PM2’s startup service.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- Install Node.js and npm using the chosen method.
- Confirm the binaries resolve for the deploy user:
node --version
npm --version - Record both versions in your deployment notes and in the project’s documentation.
- Log out and back in if the installer changed the user’s
PATH.
One provider MEAN image lists Node.js 22.22.3 on a page crawled in 2026. That is an image-specific figure, not a universal requirement; a different image or application may require another LTS release.
Install MongoDB or connect to Atlas
Self-hosted MongoDB
Follow MongoDB’s repository instructions for the exact Ubuntu release and MongoDB major version. The repository entry, package names and signing-key steps differ by release, so do not substitute an installation command intended for another Ubuntu version.
- Add the repository and signing key specified for your Ubuntu release.
- Install the MongoDB server package.
- Enable and start the service with the service name used by that package.
- Check its status and recent logs before creating application users.
- Enable authorization, create a least-privilege user for the MEAN application, and bind MongoDB to loopback or a private interface unless a documented private-network design requires otherwise.
- Plan backups and test restoring one. A running database is not a backup.
Keep the database port private in both UFW and any provider-level firewall. Store the database username, password and database name in environment configuration rather than in a committed file.
MongoDB Atlas
Atlas is a fully managed MongoDB service. Create a cluster, create a database user, restrict network access to the VPS address or private network, and copy the generated connection URI. Save it securely as MONGODB_URI; MongoDB’s quick start specifically demonstrates this environment-variable pattern and warns users to protect the connection string.
Free tools Windows power users keep installed
One-click scans. No signup required.
Test the URI from the VPS, not only from your laptop. A local workstation allowlist entry can make development appear successful while the production VPS remains blocked.
Environment file layout
Create an environment file outside the public Angular directory, for example /var/www/mean/server/.env:
MONGODB_URI=mongodb+srv://app_user:replace-with-a-secret@cluster.example.mongodb.net/appdb
PORT=5050
NODE_ENV=production
Replace the example URI with the real value, restrict the file to the deploy user, and ensure .env is listed in .gitignore. Never place this value in Angular source: anything compiled into dist can be downloaded by a browser.
Create the Express API
Keep the backend in a separate directory from the Angular project so that NGINX can expose only the compiled frontend.
- Create the application directories and switch to the server directory:
sudo mkdir -p /var/www/mean
sudo chown -R deploy:deploy /var/www/mean
cd /var/www/mean
mkdir server
cd server - Initialize the package and install the dependencies used by MongoDB’s official example:
npm init -y
npm install mongodb express cors dotenv
npm install -D typescript @types/node @types/cors @types/express tsx - Create
server.js(or use your TypeScript entry point) and load the environment before opening the database connection.
A minimal Express entry point can follow this shape:
import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import { MongoClient } from 'mongodb';
const app = express();
const port = Number(process.env.PORT || 5050);
const client = new MongoClient(process.env.MONGODB_URI);
app.use(cors());
app.use(express.json());
app.get('/api/health', (_req, res) => {
res.json({ ok: true });
});
app.listen(port, '127.0.0.1', () => {
console.log(`API listening on ${port}`);
});
The example uses port 5050, matching MongoDB’s current Angular/Node framework guide. Connect to MongoDB during application startup in your real code, handle connection failures, and mount your routes below the same prefix that NGINX will proxy. Do not copy sample restaurant data or routes unless they belong to your application.
If your project uses CommonJS, use its existing module style rather than mixing import and require. Add a production script to package.json, for example "start":"node server.js", or use the command appropriate to your compiled TypeScript output.
Create and build the Angular frontend
- Install the Angular CLI version compatible with your project:
sudo npm install -g @angular/cli
For a project that pins a CLI locally, prefernpx ngafter installing its declared dependencies. - Create a new project or clone the existing repository into a directory separate from
server, such as/var/www/mean/client. - Install its dependencies:
cd /var/www/mean/client
npm ci
Usenpm installonly when you intentionally need to resolve or update the lockfile. - Set the production API base URL to the reverse-proxied path, such as
/api, rather thanhttp://127.0.0.1:5050. A browser interprets loopback as the user’s own computer, not the VPS. - Build for production:
npx ng build --configuration production
Angular writes the compiled files beneath dist; the exact nested project directory depends on the Angular workspace. Find the directory containing index.html and use that directory as NGINX’s root. Keep source maps and development files out of a public directory unless you deliberately need them.
Configure NGINX as the public entry point
Install NGINX from the Ubuntu package repository, then create a server block for your domain. The public listener uses ports 80 and 443; Express remains on its internal port.
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/mean
Use a configuration like this, changing the domain and Angular path:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/mean/client/dist/client;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:5050/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
try_files $uri $uri/ /index.html;
}
}
The trailing slash behavior in proxy_pass matters. With the example above, NGINX removes the matching /api/ prefix before forwarding. If your Express routes include /api themselves, adjust the location and proxy target deliberately and test the resulting path.
Rank #4
- Enable the site:
sudo ln -s /etc/nginx/sites-available/mean /etc/nginx/sites-enabled/mean - Disable the default site if it conflicts:
sudo rm -f /etc/nginx/sites-enabled/default - Check syntax:
sudo nginx -t - Reload only after a successful test:
sudo systemctl reload nginx
The try_files fallback is required for Angular’s single-page routing. Without it, loading a bookmarked route such as /orders/42 directly can return a 404 even though navigation from the home page works.
Issue HTTPS certificates
Point DNS at the VPS, confirm that port 80 reaches NGINX, then use the Certbot workflow supported by your Ubuntu image and provider. Configure the certificate for the same server block, redirect HTTP to HTTPS, and renew it automatically. Verify renewal with the provider’s documented dry-run command. Do not close port 80 if your chosen ACME validation method needs it.
Run Express with PM2
Closing SSH should not stop the API. PM2 daemonizes the Node process, records its state and can generate a system-startup unit.
- Install PM2 globally:
sudo npm install pm2@latest -g - Start the API from the directory containing its entry point:
cd /var/www/mean/server
pm2 start server.js --name mean-api - Save the current process list:
pm2 save - Generate the startup command:
pm2 startup - Run the exact command printed by
pm2 startupwith the required privileges. It binds PM2’s saved process list to the system’s boot process. - Check the result:
pm2 ls
pm2 logs mean-api
When the application is updated, install dependencies, rebuild if needed, then restart the named process and save the list again:
cd /var/www/mean/server
npm ci
pm2 restart mean-api --update-env
pm2 save
Use a PM2 ecosystem file when you need several processes, a working directory, environment sets or a non-default interpreter. Keep secrets in the environment or a protected file rather than committing them to that file.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Verify the complete deployment
Perform checks from both the VPS and an external network. A green PM2 status alone does not prove that DNS, TLS, NGINX routing and MongoDB authentication work together.
- API locally: run
curl http://127.0.0.1:5050/api/healthand confirm the expected JSON response. - Angular through NGINX: request the domain and confirm that the returned document is the production Angular shell, not the NGINX welcome page.
- API through NGINX: request
https://example.com/api/healthand confirm that the request reaches Express. - Browser calls: open developer tools and confirm that Angular uses the relative
/apipath and that responses do not fail because of an incorrect CORS origin. - Database authentication: exercise a read and a write using the application account, then check that a bad credential fails.
- Firewall: from another network, confirm only SSH, HTTP and HTTPS are reachable; MongoDB must not be publicly exposed.
- Process recovery: run
pm2 restart mean-api, then reboot the VPS and verify that PM2 restores the process. - TLS and DNS: test the hostname over HTTPS from outside the VPS and confirm the certificate covers the hostname users enter.
These are deployment acceptance checks, not a claim that any particular VPS image has already passed them. Provider images and package defaults change, so repeat them after rebuilding a server.
Best Value
Manual installation versus a one-click MEAN image
| Decision point | Manual installation | One-click image |
|---|---|---|
| Control | You choose the Ubuntu image, package versions, ports and directory layout. | The provider chooses image defaults, bundled versions and file locations. |
| Time to first page | Longer because each layer is installed and configured. | Usually faster because the provider bundles the stack and bootstrap scripts. |
| Maintenance | You own updates, hardening, backups and compatibility testing. | Bootstrap is simpler, but you still own application updates and must inspect the defaults. |
| Port assumptions | You define the Express port and NGINX proxy path. | Provider examples commonly use Express on 5000 and NGINX on public ports 80 and 443. |
| Migration | Documented packages and paths are easier to reproduce on another VPS. | Image-specific scripts and paths may require changes during migration. |
Choose a one-click image when speed matters and you are willing to audit its users, firewall rules, service files, Node.js version and database exposure. Choose manual installation when you need repeatable infrastructure, a specific Ubuntu release, a private database network or a controlled upgrade schedule.
Common failures and precise fixes
Angular loads, but every API call fails
Check the compiled environment value first. If it contains 127.0.0.1:5050, rebuild with a relative /api base URL. Then check the NGINX location prefix, the trailing slash on proxy_pass and the Express route path. Read /var/log/nginx/error.log and pm2 logs mean-api together so you can distinguish a proxy error from an application error.
Direct Angular routes return 404
Add or restore try_files $uri $uri/ /index.html; in the general location block, confirm that NGINX’s root is the directory containing index.html, run nginx -t, and reload NGINX.
PM2 works now but not after reboot
pm2 save alone is not enough. Run pm2 startup, execute the exact generated command, verify the process list with pm2 ls, reboot, and inspect both pm2 ls and the system journal if the process is missing.
MongoDB connections time out
For self-hosting, verify the service is running and bound to the interface Express uses; for Atlas, verify the VPS address is in the network-access list. Check DNS resolution, credentials, TLS requirements and outbound firewall rules. Do not solve a timeout by opening MongoDB to every internet address.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →NGINX reports a bad gateway
Confirm that Express is listening on the same port NGINX proxies to and that it is bound to 127.0.0.1. Use ss -ltnp and a local curl request. A stopped PM2 process, a wrong working directory or an environment file that PM2 cannot read are common causes.
Production maintenance checklist
- Pin Node.js, Angular CLI, MongoDB and application dependencies; review upgrades in a staging environment.
- Patch Ubuntu and NGINX regularly and remove unused packages and services.
- Rotate database credentials and any application secrets without committing them to Git.
- Back up MongoDB on a schedule and perform a restore test.
- Monitor disk space, memory, PM2 restarts, NGINX errors and certificate expiry.
- Keep MongoDB private and expose only the web ports required by the application.
- Document the selected Express port, API prefix, Angular dist path, PM2 process name and recovery commands.
- Recheck provider image manifests, Ubuntu support, Node.js versions, Angular compatibility, MongoDB packages and firewall defaults before rebuilding a server. These details can change within a short release cycle.
Frequently Asked Questions
Can the Angular frontend and Express API use different domains?
Yes, but a separate frontend domain requires an explicit CORS policy and usually additional cookie, CSRF and TLS configuration. Keeping both behind one NGINX hostname with an /api prefix avoids those cross-origin requirements.
Should I expose Express directly on port 5000 or 5050?
No. Those are example internal ports: provider examples use 5000, while MongoDB’s framework example uses 5050. Bind Express to loopback and let NGINX be the public entry point.
Can I install MongoDB and the Node application on the same VPS?
You can on a small deployment if the VPS has enough memory, disk and backup capacity, but the services then share one failure domain. A managed database or separate private database host provides stronger isolation.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Why does an environment variable work in Express but not in Angular?
Express reads environment variables at runtime on the server. Angular values are embedded when the application is built, so changing the VPS environment after ng build does not change the browser bundle; rebuild it and never embed secrets.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

