How to Create Your First Safe Server That‘s Ready for Production

Launching a new web application or website is an exciting milestone for any developer. But before you release your project to the world, it‘s crucial that you have a production-ready server to host it on. After all, the performance, security and reliability of your app is only as good as the infrastructure it runs on.

In this in-depth guide, we‘ll walk through all the key steps to create your first safe and robust server that‘s fully equipped to handle real-world production traffic. Whether you‘re a solo developer or part of a larger team, the practices covered here will put you on the path to success. Let‘s jump in!

Choose a Web Host and Server

The first decision you‘ll need to make is where to host your server and what type of server to use. There are many web hosting providers to choose from, including Amazon Web Services (AWS), DigitalOcean, Linode, Vultr, Google Cloud, Microsoft Azure, and more.

For most applications, a cloud virtual private server (VPS) will provide a good balance of performance, scalability, and cost. With a cloud VPS, you can easily scale up your server resources as your traffic grows.

Some key factors to consider when choosing a host:

  • Server locations – Choose a data center close to your target users to minimize latency
  • Pricing – VPS plans can range from $5 to hundreds per month depending on resources
  • Ease of use – Some hosts have a more polished UI and knowledgebase than others
  • Customer support – Consider what level of technical support you may need

For this guide, we‘ll use DigitalOcean for our example setup, but the same steps can be adapted for other cloud hosts as well. Once you‘ve signed up for a DigitalOcean account, create a new VPS droplet and choose the following options:

  • Distribution: Ubuntu 20.04 LTS x64
  • Plan: Basic, regular Intel with SSD, $5/month
  • Datacenter region: Choose one closest to your target audience
  • Authentication: SSH keys, which we‘ll set up in a later step

Set Up the Server OS

With your new server provisioned, the first step is getting the operating system properly set up and secured. We‘ll use Ubuntu Linux for this guide, which is one of the most popular server distros thanks to its stability and well-maintained package repositories.

To connect to your VPS, you‘ll need an SSH client. On macOS or Linux, you can simply use the built-in terminal. On Windows, you can use the free PuTTY client.

Open your terminal and connect to the server using:

ssh root@SERVER_IP_ADDRESS

Once logged in, update the system to pull in the latest security patches:

apt update && apt upgrade

Next, we‘ll create a new user account that we‘ll use for day-to-day tasks, as it‘s poor practice to regularly use the root account:

adduser johndoe
usermod -aG sudo johndoe

This creates a new user "johndoe" and adds it to the sudo group for admin privileges.

Harden Server Security

Now we‘ll take some steps to lock down our server and reduce the risk of intrusion.

First, disable password-based SSH authentication, as passwords can be brute-forced. Instead we‘ll rely solely on cryptographic SSH keys, which are far more secure.

On your local machine, generate a new SSH key pair if you don‘t already have one:

ssh-keygen -t ed25519 

Then print out the public key:

cat ~/.ssh/id_ed25519.pub

Select and copy the printed key. Back on the server, switch to your new user account:

su - johndoe

Open the authorized_keys file:

nano ~/.ssh/authorized_keys

Paste in the public key you copied, save, and exit.

Now open the SSH daemon config file:

sudo nano /etc/ssh/sshd_config 

Find the line that says PasswordAuthentication and change it to no to disable password logins. Also change the PermitRootLogin to no.

At the bottom, add your SSH port number if you want to change it from the default 22 (e.g. Port 7777).

Save and exit, then restart the SSH daemon:

sudo systemctl restart ssh

Next, configure the uncomplicated firewall (UFW) to restrict access to your server:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

This blocks all incoming ports except for SSH, HTTP (80), and HTTPS (443). If your app uses additional ports, be sure to allow those too.

Configure Web Server

Next we‘ll install a web server to handle HTTP requests. The two most popular open source options are Apache and NGINX. We‘ll use NGINX for this guide.

Install NGINX using apt:

sudo apt install nginx

You can verify it‘s running with:

sudo systemctl status nginx

If you visit your server‘s public IP address in a browser, you should see the default NGINX landing page.

Let‘s also install an SSL certificate to enable HTTPS using the free Let‘s Encrypt service:

sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-nginx
sudo certbot --nginx -d yourdomain.com

The certbot tool will automatically fetch and configure a new SSL certificate for your domain.

By default, NGINX uses a single default server block, which works fine for single-site setups. But if you want to host multiple sites, you‘ll want to create additional site-specific server blocks.

To add a new server block, create a config file ending in .conf in the /etc/nginx/conf.d directory:

sudo nano /etc/nginx/conf.d/mysite.conf

Then add a server block like:

server {
    listen 80;
    server_name mysite.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    } 
}

This tells NGINX to route all requests for mysite.com to a backend server running on port 3000. This assumes you already have your application running, such as through a process manager like PM2.

Test the config and restart NGINX:

sudo nginx -t
sudo systemctl restart nginx

Secure Sensitive Data

Most applications will require storing some type of sensitive data, like API keys, database credentials, and user info. It‘s critical this data is properly secured.

As a general rule, never store sensitive data in your codebase, especially if it‘s version controlled. Instead, use environment variables, which can be accessed from within your app.

For extra security, you can store secrets with encryption using a tool like git-crypt or Blackbox.

When storing user data, be sure to follow OWASP best practices. Hash all passwords using a strong hashing algorithm like bcrypt or Argon2. Use HTTPS everywhere. Protect against common web app vulnerabilities like SQL injection and XSS.

Monitoring and Logging

To keep tabs on your server, it‘s important to set up monitoring and logging.

To check the overall health of your server, you can configure a monitoring tool like:

  • Nagios – Monitors servers, switches, applications
  • Grafana – Monitors server and app metrics, analytics
  • Zabbix – Open source monitoring for networks, servers, cloud

It‘s also good practice to collect and store your server and application logs for troubleshooting and auditing. Some popular logging systems include:

  • ELK Stack – Elasticsearch + Logstash + Kibana for search and analysis
  • Graylog – Centralized log management platform
  • Fluentd – Open source data collector for unified logging

Backups

To avoid catastrophic data loss, you must back up your data and code.

The 3-2-1 rule is a best practice for backups: keep at least 3 copies of your data, on 2 different media, with 1 copy offsite.

For VPS data, you can use a tool like rsync or duplicity to perform automated backups to an external storage system like AWS S3.

For databases, you can write a cron job to dump the database daily and transfer it offsite.

Load Testing

Before launching your app, it‘s wise to perform load testing to see how your server performs under heavy traffic.

Some open source load testing tools include:

  • Apache JMeter – Load test functional behavior and measure performance
  • Artillery – Modern load testing toolkit
  • Locust – Scalable user load testing tool

By simulating heavy traffic, you can identify bottlenecks, optimize performance, and configure autoscaling if supported by your host.

Documentation

Finally, make sure to document your server setup!

At a minimum, write up an outline of:

  • How to SSH into the server
  • How to deploy the app
  • How to perform common maintenance tasks
  • Who to contact for help

Store this in a secure but accessible location, like a company wiki or Google Doc.

Conclusion

Setting up a production-ready server involves many steps, but they‘re all important for building a stable and secure foundation for your application.

By choosing a reliable host, hardening your server‘s security, setting up monitoring and backups, and following other best practices covered in this guide, you‘ll be well on your way to launching a successful app.

Always stay vigilant and continue to iterate on your setup to keep up with the latest technologies and threats. Now go forth and deploy!

Similar Posts