Deploy an Express App
Understanding the Components
Before we dive into the deployment process, let's briefly discuss the key components we'll be working with:
Express.js: A minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It's known for its speed and simplicity, making it a popular choice among developers.
VPS (Virtual Private Server): A virtual machine sold as a service by an Internet hosting provider. It runs its own copy of an operating system, and customers have superuser-level access to that operating system instance, allowing them to install almost any software that runs on that OS.
Caddy: A powerful, enterprise-ready, open source web server with automatic HTTPS written in Go. It's known for its simplicity and ease of use, making it an excellent choice for reverse proxy and SSL/TLS termination.
Custom Domains: Unique web addresses that you own and can use to direct users to your website or application.
Now that we have a basic understanding of these components, let's proceed with the deployment process.
Setting Up Your VPS
The first step in our journey is to set up a Virtual Private Server. For this guide, we'll assume you're using a Linux-based VPS, specifically Ubuntu 20.04 LTS. Here's how to get started:
Choosing a VPS Provider: There are numerous VPS providers available, such as DigitalOcean, Linode, Vultr, and AWS EC2. Choose one that fits your budget and requirements. For beginners, DigitalOcean or Linode are often good choices due to their simplicity and extensive documentation.
Creating Your VPS Instance: Once you've chosen a provider, create a new VPS instance. Select Ubuntu 20.04 LTS as your operating system, and choose a plan that suits your needs. A basic plan with 1GB RAM and 1 CPU core should be sufficient for most small to medium-sized Express applications.
Accessing Your VPS: After creating your instance, you'll receive login credentials. Use SSH to connect to your VPS. On most systems, you can use the following command:
ssh root@your_server_ip
Replace your_server_ip
with the IP address provided by your VPS provider.
Updating Your System: Once you're logged in, it's crucial to update your system. Run the following commands:
sudo apt update
sudo apt upgrade -y
This ensures that your system has the latest security patches and software versions.
Installing Node.js and npm
Our Express application runs on Node.js, so we need to install it on our VPS. Here's how to do it:
Installing Node.js: We'll use the NodeSource repository to install Node.js. Run the following commands:
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
This installs Node.js 14.x and npm (Node Package Manager).
Verifying the Installation: Check if Node.js and npm are installed correctly by running:
node --version
npm --version
You should see the version numbers displayed for both.
Setting Up Your Express Application
Now that we have Node.js installed, let's set up our Express application on the VPS:
Creating a Directory for Your App: Choose a location for your application. A common choice is the /var/www/
directory. Create a new directory for your app:
sudo mkdir -p /var/www/myexpressapp
sudo chown -R $USER:$USER /var/www/myexpressapp
Transferring Your Application: If you've developed your Express application locally, you'll need to transfer it to your VPS. You can use SCP (Secure Copy) or Git for this purpose. If using SCP, the command would look something like this:
scp -r /path/to/your/local/app/* root@your_server_ip:/var/www/myexpressapp/
If you're using Git, clone your repository into the /var/www/myexpressapp/
directory.
Installing Dependencies: Navigate to your application directory and install the necessary dependencies:
cd /var/www/myexpressapp
npm install
Testing Your Application: Before we proceed with setting up Caddy, let's ensure your Express application runs correctly. Start your application:
node app.js
Replace app.js
with your main application file if it's named differently. Your app should now be running. You can test it by opening a new terminal and using curl:
curl http://localhost:3000
Assuming your app listens on port 3000, you should see the response from your Express app.
Installing and Configuring Caddy
Now that our Express application is up and running, let's set up Caddy as a reverse proxy:
Installing Caddy: Caddy isn't available in the default Ubuntu repositories, so we'll need to add the Caddy repository:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Configuring Caddy: Caddy's main configuration file is located at /etc/caddy/Caddyfile
. Let's edit it to set up our reverse proxy:
sudo nano /etc/caddy/Caddyfile
Replace the contents with the following:
yourdomain.com {
reverse_proxy localhost:3000
}
Replace yourdomain.com
with your actual domain name. This configuration tells Caddy to forward all requests to your Express application running on localhost:3000.
Starting Caddy: Start the Caddy service:
sudo systemctl start caddy
Enable Caddy to start on boot:
sudo systemctl enable caddy
Setting Up Your Custom Domain
To use your custom domain with your VPS and Express application, you'll need to configure your domain's DNS settings:
Updating DNS Records: Log in to your domain registrar's control panel. You'll need to create an A record that points your domain to your VPS's IP address. The exact process varies depending on your registrar, but generally, you'll need to:
- Create an A record
- Set the host to @ (representing your root domain)
- Set the value to your VPS's IP address
If you want to use a subdomain (e.g., app.yourdomain.com), create a CNAME record pointing to your root domain instead.
Propagation Time: DNS changes can take up to 48 hours to propagate globally, although it's often much quicker. During this time, your domain may not work correctly for all users.
Securing Your Application
Security is crucial when deploying web applications. Here are some steps to enhance your application's security:
Firewall Configuration: Ubuntu comes with ufw (Uncomplicated Firewall) pre-installed. Let's configure it:
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
This allows SSH, HTTP, and HTTPS traffic while blocking other incoming connections.
Secure Caddy: Caddy automatically obtains and renews SSL/TLS certificates from Let's Encrypt, providing HTTPS by default. However, you should regularly update Caddy to ensure you have the latest security patches:
sudo apt update
sudo apt upgrade caddy
Keep Your System Updated: Regularly update your system to patch any security vulnerabilities:
sudo apt update
sudo apt upgrade
Use Environment Variables: Store sensitive information like API keys and database credentials in environment variables rather than hardcoding them in your application.
Running Your Express App as a Service
To ensure your Express application starts automatically and runs in the background, we'll set it up as a system service using systemd:
Creating a Service File: Create a new service file:
sudo nano /etc/systemd/system/myexpressapp.service
Add the following content:
[Unit]
Description=My Express App
After=network.target
[Service]
Environment=NODE_ENV=production
Type=simple
User=root
ExecStart=/usr/bin/node /var/www/myexpressapp/app.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
Adjust the ExecStart
path if your main application file is named differently or located elsewhere.
Starting Your Service: Now, let's start our new service:
sudo systemctl start myexpressapp
Enable it to start on boot:
sudo systemctl enable myexpressapp
You can check the status of your service at any time with:
sudo systemctl status myexpressapp
Monitoring and Maintaining Your Deployment
Congratulations! Your Express application is now deployed on a VPS, running behind Caddy with custom domain support. However, the work doesn't stop here. Proper monitoring and maintenance are crucial for keeping your application running smoothly:
Log Monitoring: Regularly check your application logs for errors or unusual activity. You can view your Express app's logs using:
sudo journalctl -u myexpressapp
For Caddy logs:
sudo journalctl -u caddy
Performance Monitoring: Consider setting up a monitoring solution like PM2 or New Relic to keep track of your application's performance and resource usage.
Regular Backups: Implement a backup strategy for your application and any associated databases. Many VPS providers offer snapshot features that can be useful for this purpose.
Scaling: As your application grows, you may need to scale your resources. Keep an eye on your VPS's CPU, memory, and disk usage. If you're consistently hitting high usage levels, it might be time to upgrade to a more powerful VPS or consider horizontal scaling.
Troubleshooting Common Issues
Even with careful setup, you may encounter issues. Here are some common problems and their solutions:
Application Not Starting: Check your application logs for errors. Ensure all dependencies are installed and your Node.js version is compatible with your application.
Caddy Not Proxying Requests: Verify your Caddyfile configuration. Ensure your Express app is running and listening on the correct port.
SSL Certificate Issues: Caddy should handle SSL certificates automatically. If you're having issues, check Caddy's logs for more information.
Domain Not Resolving: Double-check your DNS settings. Remember that DNS changes can take time to propagate.
Conclusion
Deploying an Express application on a VPS with Caddy and custom domain support might seem daunting at first, but it's a powerful and flexible setup that gives you full control over your hosting environment. Don't forget regularly update your system and applications, monitor your logs, and be prepared to troubleshoot issues as they arise. With proper maintenance, your Express application will continue to serve your users reliably and efficiently.