Your First Cumulus Virtual Personal Server
What is Cumulus?
Cumulus is Linnaeus University's cloud computing platform that provides students with virtual personal servers (VPS) for course-related projects and exercises. Each student receives:
- A personal Ubuntu Linux server running in the cloud
- Root-level access to install software and configure services
- Public internet connectivity with a unique DNS name (e.g.,
cuXXXX.camp.lnu.se) - SSH access through the university's VPN network
What you can do with your Cumulus server:
- Deploy web applications and APIs
- Learn Linux system administration
- Practice server configuration and security
- Host course projects accessible from anywhere on the internet
- Experiment with different technologies without affecting your personal computer
Important limitations:
- Access requires connection to the university VPN
- The server is for course-related activities only - not personal projects
- Your server and data may be reset between courses
- Resource usage is monitored and limited
Think of Cumulus as your personal sandbox server where you can safely learn and experiment with real-world server technologies in a controlled environment.
Step 1: Verify SSH Availability
Before you can connect to your Cumulus server, make sure that the ssh command
is available in your terminal.
Windows Instructions
If you're using Windows 10 or later, the built-in PowerShell or Command Prompt usually includes SSH, but we recommend using Git Bash as your terminal (this guide assumes you're using a Bash terminal).
Check if SSH is installed:
Open Git Bash (or your preferred terminal) and run:
If you see a version number (e.g., OpenSSH_9.9p1, OpenSSL 3.2.3 3 Sep 2024),
you're good to go and can proceed to Step 2.
If SSH is not available, you have several options:
- Install OpenSSH Client via Windows Features (Settings → Apps → Optional Features)
- Use Windows Terminal with PowerShell or Command Prompt
- Install Windows Subsystem for Linux (WSL) - provides a complete Linux environment with native SSH support
- Alternatively, install PuTTY, though this guide assumes OpenSSH command-line tools
macOS Instructions
SSH is pre-installed on macOS. You can verify it's available by opening Terminal and running:
If you see a version number, you're ready to proceed to Step 2.
Linux Instructions
SSH is typically pre-installed on most Linux distributions. You can verify it's available by opening your terminal and running:
If you see a version number, you're ready to proceed to Step 2.
If SSH is not installed, you can install it using your distribution's package manager:
Ubuntu/Debian:
Fedora:
Arch Linux:
Step 2: Download Your Identity File from GitLab
To access your personal server in the Cumulus cloud via SSH, you need an identity file (private key). This file is provided through a GitLab project.
Locate and download the identity file:
- Go to the Secrets project in GitLab
- In this project, you will find:
- Your private key file (named something like
id_cumulus_xxx) - The IP address of your server
- The DNS name assigned to your server
- Your private key file (named something like
- Download the private key file (
id_cumulus_xxx) to a known location on your computer
Keep this file safe - you'll need it in the next step.
Step 3: Create the .ssh Directory
The .ssh directory is a standard location for storing SSH keys and configuration
files. If it doesn't already exist, you need to create it.
Windows (Git Bash) Instructions
Open Git Bash and run:
This creates the .ssh directory in your home folder if it doesn't already exist.
The -p flag ensures no error occurs if the directory is already there.
macOS Instructions
Open Terminal and run:
This creates the .ssh directory in your home folder if it doesn't already exist.
The -p flag ensures no error occurs if the directory is already there.
Linux Instructions
Open your terminal and run:
This creates the .ssh directory in your home folder if it doesn't already exist.
The -p flag ensures no error occurs if the directory is already there.
Step 4: Move the Identity File to .ssh Directory
Now you need to move the downloaded identity file to the .ssh directory.
Windows (Git Bash) Instructions
In Git Bash, navigate to where you downloaded the file (e.g., Downloads folder)
and move it to .ssh:
Replace id_cumulus_xxx with the actual filename of your private key.
If your file is in a different location, adjust the path accordingly:
macOS Instructions
In Terminal, move the file from your Downloads folder to .ssh:
Replace id_cumulus_xxx with the actual filename of your private key.
If your file is in a different location, adjust the path accordingly.
Linux Instructions
In your terminal, move the file from your Downloads folder to .ssh:
Replace id_cumulus_xxx with the actual filename of your private key.
If your file is in a different location, adjust the path accordingly.
Step 5: Set Correct Permissions on the Identity File
Setting the correct permissions ensures that your private key is only readable by you. SSH will refuse to use the key if it's accessible by others, as this would pose a security risk.
Windows (Git Bash) Instructions
In Git Bash, run:
Replace id_cumulus_xxx with the actual filename of your private key.
Note: When using Git Bash, chmod 600 works as expected and ensures your
key is accepted by SSH, even though Windows handles file permissions differently
under the hood.
macOS Instructions
In Terminal, run:
Replace id_cumulus_xxx with the actual filename of your private key.
This command sets the file permissions so that only you (the owner) can read and write the file, while removing all permissions for group and others.
Linux Instructions
In your terminal, run:
Replace id_cumulus_xxx with the actual filename of your private key.
This command sets the file permissions so that only you (the owner) can read and write the file, while removing all permissions for group and others.
Once your identity file is in place and has the correct permissions, you can connect to your virtual personal server in the Cumulus cloud using SSH.
Use the DNS name (or IP address)
In the GitLab Secrets project, you will find either:
- The DNS name of your virtual personal server (recommended), e.g. cuXXXX.camp.lnu.se
- Or the IP address, e.g. 172.27.XXX.XXX
Connect using SSH
Open your terminal (Git Bash on Windows) and run:
Replace:
id_cumulus_xxxwith the actual filename of your private keycuXXXX.camp.lnu.sewith your server’s DNS name (or IP address)
📌 Example
If this is your first time connecting, you may be asked to confirm the host's fingerprint. Type yes to continue.
🔧 Troubleshooting: Remove a Previously Registered Key
If you’ve connected to your server before and the host key has changed (for example, due to a reinstallation), SSH may refuse to connect and show a warning about a mismatched key.
To fix this, remove the old key from your known hosts file:
Replace
cuXXXX.camp.lnu.sewith your servers’s actual DNS name or IP address. This command deletes the outdated entry from~/.ssh/known_hosts, allowing you to reconnect without errors.What Happens When You Successfully Connect
If the SSH connection is successful, you’ll see a welcome message from the Ubuntu operating system, along with system information such as memory usage, IP address, and login history.
You will land in your home directory, typically
/home/ubuntu, and the prompt will look something like:From here, you can start working on your virtual personal server — installing packages, running applications, or setting up web services
Step 4: Update Package Lists
Before installing any software on your Cumulus virtual personal server, it's good practice to update the package lists. This ensures that you get the latest available versions of packages from the Ubuntu repositories.
You are logged in as a regular user (ubuntu), so administrative commands like
apt update require sudo.
Run the following command:
This command fetches the most recent information about available packages and updates, which is necessary before installing tools like Node.js, npm, and nginx.
You only need to run this once before installing multiple packages. There's no need to repeat it before each installation unless a significant amount of time has passed or you've added new repositories.
Step 5: Install Node.js and npm
To run JavaScript applications on your Cumulus server, you need to install Node.js and its package manager npm.
Add the NodeSource Repository
Start by adding the official NodeSource repository for Node.js version 22:
This command downloads and runs a setup script that configures your system to use the NodeSource repository.
Install Node.js
Once the repository is added, install Node.js and npm:
The
-yflag automatically confirms the installation.Verify the Installation
After installation, check that both Node.js and npm are available:
You should see version numbers printed in the terminal, confirming that the installation was successful.
Step 6: Install and Start nginx
To serve web content from your Cumulus server, you need to install a web server. We use nginx, a lightweight and high-performance HTTP server.
Install nginx
Run the following command to install nginx:
This installs the nginx package and its dependencies.
Start the nginx Service
Once installed, start the nginx service:
This launches the web server.
Enable nginx to Start on Boot
To make sure nginx starts automatically when the server boots:
Check nginx Status
You can verify that nginx is running with:
You should see output indicating that the service is active (running).
Step 7: Verify nginx in Your Browser
Once nginx is installed and running, you can verify that it works by accessing your server in a web browser using HTTP.
Use the DNS Name
Open a browser and enter your server’s DNS name in the address bar, using http:
Replace cuXXXX.camp.lnu.se with your actual DNS name.
Expected Result
You should see the default Welcome to nginx! page. This confirms that:
- nginx is installed correctly
- the service is running
- your server is reachable over the network
If you don’t see the page, double-check that:
- VPN is connected
- nginx is running (
systemctl status nginx) - You used the correct DNS name
What Happens If You Use HTTPS?
At this stage, your nginx server is only configured to serve content over HTTP. If you try to access your server using HTTPS, like:
…you will likely see a browser warning or error such as:
- "Your connection is not private"
- "This site can’t provide a secure connection"
- "ERR_SSL_PROTOCOL_ERROR"
This is expected, because no SSL/TLS certificate has been installed yet.
You will configure HTTPS and install certificates in the next step.
Step 8: Request and Install a TLS Certificate from LNU FTK Campus CA
To enable HTTPS on your virtual server in the Cumulus network, you can request a certificate using Certbot and the LNU FTK Campus CA.
Prerequisites
- Your server has a floating IP address in the Cumulus campus network.
- You have sudo privileges.
- Nginx is installed and running.
Install the LNU FTK Campus Root CA Certificate
Download and install the root certificate so that Certbot can validate the CA:
Verify that the certificate is installed:
You should see that the system has created a hash-based symlink pointing to a
.pemfile, and another symlink namedLNU_FTK_Campus_Root_CA_2025.pempointing to the original.crtfile. This confirms that the certificate has been added to the system trust store and is available for use by Certbot and other tools.Install Certbot
Install Certbot using Snap and make it available via /usr/bin/certbot:
This ensures that Certbot is available system-wide and can be used with plugins like Nginx.
Request and Install the Certificate
Use Certbot to request a certificate from the LNU FTK Campus CA using the Nginx plugin and the custom ACME endpoint. The command below automatically derives the correct FQDN from the server's floating IP:
This command:
- Uses the LNU FTK Campus ACME endpoint.
- Automatically converts your floating IP to the correct FQDN.
- Requests and installs the certificate via the Nginx plugin.
Test and Restart nginx Configuration
After Certbot has modified your nginx configuration, always test that the configuration is valid before proceeding:
You should see:
If the test is successful, restart nginx to apply the changes:
Step 9: Configuring Automatic Certificate Renewal
Certificates issued by the LNU FTK Campus Certificate Authority are short-lived (6–7 days). Therefore, automatic renewal is mandatory to avoid service interruptions.
When Certbot is installed via snap, automatic renewal is handled by a systemd timer. However, because an internal ACME CA is used, additional configuration is required.
How Automatic Renewal Works
- Certbot is executed automatically by the systemd timer
snap.certbot.renew.timer - The timer runs several times per day
- Renewal occurs automatically when the certificate is close to expiration
- No cron jobs or manual scripts are required
1. Configure Certbot for the Campus CA (One-time setup)
Certbot must be provided with:
- the campus Root CA bundle
- the internal ACME server URL
This is done using a systemd drop-in configuration.
1. Create a drop-in directory
2. Create the drop-in configuration file
Explanation:
REQUESTS_CA_BUNDLEEnsures Certbot trusts the LNU FTK Campus Root CACERTBOT_SERVERPoints Certbot to the campus ACME endpoint instead of Let’s Encrypt
2. Reload systemd and test renewal
This runs the same renewal logic that the timer uses.
3. Verify automatic renewal is scheduled
Check that the systemd timer is active:
You should see output similar to:
This confirms that automatic renewal is enabled.
4. Verify renewal results
To check certificate status at any time:
To verify that a renewal actually occurred:
If the certificate is not close to expiration, Certbot will only perform a check. This is expected behavior.
✅ Automatic renewal is now fully configured.
No further action is required. The certificate will be renewed automatically before it expires.
Step 10: Trust the CA in Your Browser
Before you can verify HTTPS access without security warnings, you need to install the Root CA certificate in your browser's trust store.
1. Download the Root CA
- Download LNU_FTK_Campus_Root_CA_2025.crt
- Remember the download location (e.g., Downloads folder)
2. Import the Certificate
Choose your operating system and browser:
💻 macOS
Google Chrome / Safari (uses macOS Keychain)
- Locate the downloaded
LNU_FTK_Campus_Root_CA_2025.crtfile - Double-click it → opens in Keychain Access
- Select System keychain when prompted
- Find LNU FTK Campus Root CA 2025 in the list
- Double-click it → expand Trust section
- Set When using this certificate → Always Trust
- Close the window (enter admin password if prompted)
Note: Both Chrome and Safari now trust this CA.
Mozilla Firefox (separate certificate store)
- Open Firefox
- Go to Settings (⚙️)
- Navigate to Privacy & Security → Certificates → View Certificates
- Select the Authorities tab
- Click Import
- Select the downloaded Root CA file
- Check "Trust this CA to identify websites"
- Click OK
Note: Firefox uses its own certificate store, independent of macOS Keychain.
💻 Windows
Google Chrome
- Open Chrome
- Navigate to:
chrome://certificate-manager/localcerts/usercerts - Select the Local certificates tab
- Under Installed by you, click Import (Trusted Certificates)
- Browse to the downloaded Root CA file
- Click Open → Confirm the import
Mozilla Firefox
- Open Firefox
- Go to Settings → Privacy & Security → View Certificates
- Select the Authorities tab
- Click Import
- Choose the downloaded Root CA file
- Check "Trust this CA to identify websites"
- Click OK
💻 Linux
Google Chrome
- Open Chrome
- Navigate to:
chrome://certificate-manager/localcerts/usercerts - Select the Local certificates tab
- Under Installed by you, click Import (Trusted Certificates)
- Browse to the downloaded Root CA file
- Click Open → Confirm the import
Mozilla Firefox
- Open Firefox
- Go to Settings → Privacy & Security → View Certificates
- Select the Authorities tab
- Click Import
- Choose the downloaded Root CA file
- Check "Trust this CA to identify websites"
- Click OK
3. Restart Your Browser
Important: Completely close and restart your browser for the changes to take effect.
✅ Your browser now trusts the LNU FTK Campus CA and you're ready to verify HTTPS access without security warnings.
Step 11: Verify HTTPS in Your Browser
After installing the TLS certificate, you should verify that HTTPS is working correctly on your nginx server.
Test HTTPS Access
Open a browser and enter your server's DNS name using HTTPS:
Replace cuXXXX.camp.lnu.se with your actual DNS name.
Expected Result
You should see:
- The same Welcome to nginx! page as before
- A secure connection indicator (lock icon) in your browser's address bar
- No security warnings or certificate errors
This confirms that:
- The TLS certificate is installed correctly
- HTTPS is properly configured
- Your connection is encrypted and secure
Troubleshooting HTTPS Issues
If you encounter problems:
Certificate errors: Verify the certificate installation with:
Nginx configuration: Check that nginx is using the certificate:
Browser cache: Try a hard refresh (Ctrl+F5) or test in an incognito/private window
HTTP vs HTTPS Behavior
Now that HTTPS is configured:
- HTTP requests
http://cuXXXX.camp.lnu.seshould automatically redirect to HTTPS - HTTPS requests
https://cuXXXX.camp.lnu.seshould work directly with a secure connection
This automatic redirection is configured by Certbot when it updates your nginx configuration.
- HTTP requests
Step 12: Secure nginx Configuration
Now that HTTPS is working, it's time to enhance the security of your nginx server by modifying the configuration and removing unnecessary information disclosure.
Edit the nginx Configuration
Open the main nginx configuration file:
Hide Server Version Information
Find the
httpblock in the configuration file. Look for the commented line:Uncomment this line by removing the
#at the beginning:This prevents potential attackers from knowing which specific version of nginx you're running.
Save and Exit
In nano:
- Press
Ctrl + Oto save - Press
Enterto confirm - Press
Ctrl + Xto exit
- Press
Test the Configuration
Before restarting nginx, always test that your configuration is valid:
You should see:
Restart nginx
Apply the changes by restarting the nginx service:
Verify the Security Enhancement
Test that the version information is now hidden by checking the HTTP headers:
Replace
cuXXXX.camp.lnu.sewith your actual DNS name.Before the change, you would see:
After the change, you should only see:
This simple security enhancement reduces information leakage that could be useful to potential attackers.
Step 13: Create Your Own Static Website
Instead of using the default nginx page, let's create your own custom website with a dedicated directory structure.
Create a New Directory for Your Website
Create a dedicated directory for your hello-world website:
Set Proper Ownership
Change ownership to the ubuntu user so you can edit files without sudo:
Create Your Custom index.html
Create your hello-world homepage:
Add the following content:
Create a New nginx Site Configuration
Create a dedicated configuration file for your domain:
Add the following configuration:
Important: Replace
cuXXXX.camp.lnu.sewith your actual DNS name in both theserver_nameand SSL certificate paths.Configuration Breakdown:
- First server block (HTTP): Redirects all HTTP traffic to HTTPS for security
- Second server block (HTTPS): Handles encrypted connections on port 443
- http2: Enables HTTP/2 protocol for faster page loading and better performance
- SSL certificates: Points to the certificates installed by Certbot
- root /var/www/hello-world: Sets the directory for static files
- location /: Serves static files, returns 404 if not found
- include locations/*.conf: Loads configurations for dynamic applications
HTTP/2 Benefits:
HTTP/2 is automatically enabled in your nginx configuration and provides:
- Multiplexing - Multiple requests over a single connection
- Header compression - Reduced overhead for HTTP headers
- Server push - Proactive resource delivery (if configured)
- Binary protocol - More efficient than HTTP/1.1 text-based protocol
Create Directory for Application Configurations
Create a dedicated directory structure for modular nginx configurations. This allows you to manage each application separately:
This directory will store individual
.conffiles for each application you deploy, making it easy to add, remove, or modify applications without touching the main site configuration.Disable the Default Site and Enable Your Hello-World Site
Remove the default nginx site and enable your custom hello-world site:
Test and Restart nginx Configuration
Always test the configuration before applying changes:
If the test is successful, restart nginx:
Visit Your Custom Hello-World Website
Open your browser and navigate to:
Replace
cuXXXX.camp.lnu.sewith your actual DNS name.You should now see your custom hello-world website instead of the default nginx page!
Verify HTTP/2 is Working
You can confirm that HTTP/2 is properly configured using either of these methods:
Browser Developer Tools: Open Developer Tools (F12) → Network tab → Refresh the page → Check the "Protocol" column (should show "h2")
Command line: Test with curl from your terminal:
Note: Your curl must support HTTP/2. Check with:
- Look for "Features: ... HTTP2 ..."
- If
--http2is not recognized, you can try to update curl (Linux: apt install curl, Windows: winget install curl or download from https://curl.se/windows/.
Look for
HTTP/2 200in the response headers.
Step 14: Create and Deploy an Express Application
Now let's create a dynamic web application using Node.js with Express and deploy it alongside your static website.
📁 What you'll build:
🌐 URL structure:
https://cuXXXX.camp.lnu.se/→ Static websitehttps://cuXXXX.camp.lnu.se/hello-world-express/→ Express application
Option A: Clone from GitLab (Recommended)
If you have access to the course GitLab repository with the Express Hello World project:
Set Up GitLab SSH Access on Your Cumulus Server (First Time Only)
To clone repositories from GitLab directly on your Cumulus server, you need to configure SSH access. This creates a separate key pair specifically for your Cumulus server to access GitLab repositories.
⚠️ Important: These commands are run on your Cumulus server (via SSH), not on your local computer.
Generate a new SSH key pair for GitLab on your Cumulus server:
When prompted:
- Press Enter to save in the default location (
/home/ubuntu/.ssh/id_gitlab) - Enter a passphrase (optional but recommended)
Display the public key from your Cumulus server:
Add the public key to your GitLab account:
Copy the entire output from the command above and add it to your GitLab account:
- Go to GitLab → User Settings → SSH Keys
- Paste the public key content
- Give it a descriptive title (e.g., "Cumulus Server cuXXXX")
- Click "Add key"
Configure SSH on your Cumulus server to use the GitLab key:
Add the following configuration:
Test the connection from your Cumulus server:
You should see: "Welcome to GitLab, @yourusername!"
What you've created:
- A separate SSH key pair on your Cumulus server for GitLab access
- SSH configuration that uses this key automatically for GitLab
- Secure connection between your Cumulus server and GitLab repositories
- Press Enter to save in the default location (
Navigate to your home directory
Clone the Express Hello World Project
You'll use a two-step process: clone in home directory, then move to the web directory:
💡 Why you don't clone directly to
/var/www/:- ❌
sudo git clone→ SSH uses root's keys (which don't exist) - ❌ Direct clone to
/var/www/→ Permission denied (directory owned by root) - ✅ Clone to home → move → fix ownership = Clean and simple solution
- ❌
Install Dependencies
Test the Application
You should see:
🚀 Server is running on http://localhost:3000Test locally:
curl http://localhost:3000Stop the server with
Ctrl + Cbefore proceeding to nginx configuration.
Option B: Create from Scratch (Fallback)
If you don't have access to the GitLab repository, create the application manually:
Create Project Directory
Create package.json
Add the following content:
Create Source Directory and Server File
Add the following Express application code:
Install Dependencies
Test the Application
Configure nginx as Reverse Proxy
Regardless of which option you used above, now configure nginx to serve your Express app using the modular configuration approach:
Create Express App Location Configuration
Instead of modifying the main nginx file, create a separate configuration for the Express app:
Add the following configuration:
Test and Restart nginx Configuration
Test the configuration and restart nginx:
No need to modify symlinks since we're using the include directive from Step 11.
Start Your Express Application
Test Your Setup
Now you can access:
- Static website:
https://cuXXXX.camp.lnu.se/ - Express app:
https://cuXXXX.camp.lnu.se/hello-world-express/ - Test error handling:
https://cuXXXX.camp.lnu.se/hello-world-express/test/throw-error - Test crash (dangerous!):
https://cuXXXX.camp.lnu.se/hello-world-express/test/crash
Important: Replace
cuXXXX.camp.lnu.sewith your actual DNS name.- Static website:
What You've Accomplished:
- Deployed an Express application with ES6 modules
- Configured nginx as a reverse proxy
- Set up both static and dynamic content on the same domain
- Added test routes with intentional errors and crashes
Critical Discovery:
Notice that when you close your terminal or visit /hello-world-express/test/crash,
your Express application stops working completely! This demonstrates a fundamental
problem with running Node.js applications directly - they don't survive crashes
or disconnections.
This is why we need a process manager in the next step!
Step 15: Install and Configure PM2 Process Manager
As you discovered in the previous step, Node.js applications stop running when you close your terminal or when they crash. PM2 (Process Manager 2) solves this problem by keeping your applications running in the background, automatically restarting them on crashes, and providing process monitoring.
Instead of managing each application separately, we'll use a YAML configuration file to define all our applications in one place.
Install PM2 using npm
Install PM2 globally so it's available system-wide:
This installs PM2 as a global package, making the
pm2command available from anywhere on your system.Create the Ecosystem Configuration File
Navigate to your web directory and create a PM2 ecosystem file:
Configure Your Applications
Edit the ecosystem configuration file:
Add the following YAML configuration:
Configuration notes:
script: "src/server.js"- Direct path to the Node.js application filecwd- Working directory for the applicationexec_mode: "fork"- Runs a single Node.js process (vs "cluster" for multiple processes)instances: 1- Number of processes to runenv- Environment variables for production mode
Start All Applications with PM2 Using the Ecosystem File
Use PM2 to start all applications defined in your ecosystem file:
PM2 will read the configuration and start your Express application.
Verify Applications are Running
Check the status of your PM2-managed applications:
You should see output similar to:
Test Your Express Application
Visit your Express application in a browser:
The application should be working normally.
Test Crash Recovery
Try the crash test route to see PM2's auto-restart feature:
What happens:
- The application crashes (as intended)
- PM2 automatically detects the crash
- PM2 immediately restarts the application
- Your application is available again within seconds
Check PM2 status after the crash:
You should see the restart count has increased, showing that PM2 successfully restarted your application.
Configure PM2 to Start on Server Boot
⚠️ Critical for Production: Without this configuration, your applications will NOT restart automatically when the server reboots, leading to downtime.
For a production server, it's essential that your applications start automatically when the server reboots. PM2 provides a simple way to configure this.
Generate the startup script:
This command will analyze your system and output a custom command that you need to execute. The output will look similar to this:
📋 Important Steps:
- Copy the command that PM2 outputs in YOUR terminal (not the example above)
- Paste and execute that specific command with sudo
- Each server generates a unique command - yours will be different from the example
Example of what to do:
⚠️ Warning: The exact command will be different on your system. Always use the command that PM2 generates for YOUR specific server configuration.
Save your current PM2 configuration:
This saves the current list of running applications so they're restored on boot.
Test the boot persistence:
You can test this by rebooting your server:
After the server comes back online, reconnect via SSH and check:
Your applications should be running automatically without any manual intervention.
Monitor Your Applications
View real-time logs from all applications:
View logs for a specific application:
Monitor processes in real-time:
(Press q to exit the monitor)
✅ What You've Accomplished
- Installed PM2 process manager
- Created a YAML ecosystem configuration file for managing multiple applications
- Configured centralized logging for your applications
- Set up automatic crash recovery and restart functionality
- Enabled applications to start automatically on server boot
- Learned essential PM2 monitoring and management commands
🗝️ Key Benefits of Using PM2
- Process persistence - Applications survive terminal disconnections
- Automatic restart - Crashed applications are immediately restarted
- Centralized logging - All application logs in one place
- Easy scaling - Can run multiple instances of applications
- Boot persistence - Applications start automatically when server boots
- Process monitoring - Real-time monitoring of CPU, memory, and performance
Your Express application is now running as a production-ready service that can handle crashes, server reboots, and provides comprehensive monitoring capabilities!
What's Next?
Now that you have a fully functional web server with HTTPS, static content, dynamic Express applications, and process management, you can:
- Deploy more applications - Add new location blocks for additional services
- Learn database integration - Connect your Express apps to MongoDB or PostgreSQL
- Implement monitoring - Set up log analysis and performance monitoring
- Scale your applications - Use PM2's cluster mode for better performance
- Add CI/CD - Automate deployments from your GitLab repositories
Your Cumulus virtual personal server is now a production-ready web server platform!
Summary: Your Server Stack
You've successfully built a complete web server stack:
Technologies mastered:
- ✅ Linux system administration
- ✅ SSH key management
- ✅ nginx web server configuration
- ✅ SSL/TLS certificate management
- ✅ Node.js and Express development
- ✅ Process management with PM2
- ✅ Modular nginx configuration
Common Issues and Solutions
SSH Connection Problems
- "Permission denied": Check key permissions with
ls -l ~/.ssh/id_cumulus_* - "Host key verification failed": Run
ssh-keygen -R cuXXXX.camp.lnu.se - "Connection refused": Verify VPN connection and DNS name
nginx Issues
- 502 Bad Gateway: Check if your Node.js app is running with
pm2 status - 403 Forbidden: Check file permissions in
/var/www/ - 404 Not Found: Verify file paths and nginx configuration syntax
PM2 Problems
- App not starting: Check logs with
pm2 logs - Port conflicts: Verify ports in ecosystem.config.yml
- Apps not restarting after reboot: Run
pm2 startupandpm2 save
SSL Certificate Issues
- Certificate expired: Run
sudo certbot renew - Certificate errors: Verify with
sudo certbot certificates - Browser warnings: Clear cache or test in incognito mode