How to Install Ubuntu 16.04 LTS on a VPS – Step by Step

13 min read 2,590 words
How to Install Ubuntu 16.04 LTS on a VPS from Scratch featured image

Setting Up a VPS with Ubuntu 16.04 LTS from Scratch

Provisioning a virtual private server with Ubuntu 16.04 LTS from scratch means starting with a base installation image and building out the server environment yourself. This approach gives you full control over every component, from the operating system to the web server stack. This guide walks through the complete initial setup: creating user accounts, configuring SSH access, setting up a firewall, and installing the LAMP stack.

One important note before proceeding: Ubuntu 16.04 reached end of standard support in April 2021. If you are setting up a new server, Ubuntu 22.04 LTS is the current recommended choice. This guide remains useful if you are maintaining an existing Ubuntu 16.04 deployment, or if your hosting provider still offers it as an option and you need to work with what is available.

Accessing Your VPS for the First Time

After your VPS is provisioned, your hosting provider will typically give you root access through their control panel's VNC console or a similar remote console feature. This is your starting point. You log in as root, set up the basics, and then lock root access down.

The first thing to do after logging in as root is change the root password to something strong and unique. Then take a moment to note your server's IP address, as you will need it for SSH configuration later. Most providers display this in their dashboard alongside your server details.

Creating a Non-Root User with Sudo Privileges

Working as root for everyday tasks is a security risk. A single mistake can cause serious damage to the system. Create a regular user account and give it sudo privileges for administrative tasks.

adduser deploy
usermod -aG sudo deploy

This creates a user called deploy and adds them to the sudo group. You can use any username you prefer. The usermod command with the -aG flags appends the user to the specified group without removing them from any other groups.

To allow this user to restart specific services without needing a password, which is useful for automated deployment scripts, create a sudoers file for that user:

visudo /etc/sudoers.d/90-deploy

Add these lines:

deploy ALL=(ALL) PASSWD: ALL
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart apache2, /usr/bin/systemctl restart mysql

The first line requires a password for sudo commands. The second line allows passwordless restarts of Apache and MySQL, which is useful for deployment scripts without compromising general sudo access.

Configuring SSH for Secure Remote Access

SSH is how you will manage your server day-to-day. The default configuration works, but it is designed for convenience rather than security. A few changes make it significantly harder for automated attacks to succeed.

First, set up SSH key authentication for the deploy user. On your local machine, generate an SSH key pair if you do not already have one:

ssh-keygen -t ed25519 -C "your_email@example.com"

Copy the public key to your server:

ssh-copy-id deploy@your-server-ip

You will be asked for the deploy user's password. After this, you can log in without a password using your private key.

Now edit the SSH daemon configuration to lock down access:

sudo nano /etc/ssh/sshd_config

Make these changes:

  • PermitRootLogin no: Prevents direct root login over SSH. You can still use sudo from your regular user account.
  • PasswordAuthentication no: Disables password-based login. Only SSH keys are accepted. Make sure your key is working before enabling this.
  • AllowUsers deploy@your-desktop-ip: Restricts SSH access to the deploy user, and only from your specific IP address. Replace your-desktop-ip with your actual IP.

After saving the configuration, reload the SSH daemon:

sudo systemctl reload sshd

Test the new login in a separate terminal before closing your current session. This is critical. If the configuration has an error, you want to catch it while you still have access through the VNC console.

Warning: Never disable password authentication or root login until you have confirmed that SSH key authentication works. A misconfigured sshd_config file can lock you out of your server.

Installing the LAMP Stack on Ubuntu 16.04

The LAMP stack is a common web server configuration: Linux, Apache, MySQL, and PHP. It handles serving web pages, managing databases, and processing dynamic content. Installing it on Ubuntu 16.04 involves updating the package index and then installing each component.

Update the package lists first:

sudo apt update && sudo apt upgrade -y

Then install Apache, MySQL, and PHP along with commonly needed extensions:

sudo apt install -y apache2 mysql-server php7.0 php7.0-mysql php7.0-cli
php7.0-mbstring php7.0-xml php7.0-curl

After installation completes, Apache should be running. You can verify this:

sudo systemctl status apache2

For a complete guide to LAMP stack installation and configuration on Ubuntu 16.04, see the LAMP stack setup guide. That guide covers virtual host configuration, permissions, and Apache module management in more detail than this article.

Securing MySQL

MySQL comes with a script that helps you set up basic security for your database server. Run it:

sudo mysql_secure_installation

The script prompts you through several steps. Set a strong root password, remove anonymous users, disable remote root login, and remove the test database. These steps remove common attack vectors that are enabled by default.

For your applications, create a dedicated database and user rather than using the root account. Log into MySQL:

sudo mysql

Then run:

CREATE DATABASE webapp;
CREATE USER 'webapp_user'@'localhost' IDENTIFIED BY 'strong-password-here';
GRANT ALL PRIVILEGES ON webapp.* TO 'webapp_user'@'localhost';
FLUSH PRIVILEGES;

Replace webapp, webapp_user, and strong-password-here with values appropriate for your project. Using separate database users for each application limits the damage if one application is compromised.

Configuring Apache Virtual Hosts

Virtual hosts let you run multiple websites on a single server. Each domain can have its own document root, configuration, and log files. On Ubuntu 16.04, Apache sites are configured in /etc/apache2/sites-available/.

Create a configuration file for your domain:

sudo nano /etc/apache2/sites-available/yourdomain.com.conf

Add a basic virtual host configuration:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/yourdomain.com/public_html

    <Directory /var/www/yourdomain.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/yourdomain.com-error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain.com-access.log combined
</VirtualHost>

Enable the site and the rewrite module:

sudo a2ensite yourdomain.com.conf
sudo a2enmod rewrite
sudo a2dissite 000-default.conf
sudo systemctl restart apache2

Set up the document root with correct ownership and permissions:

sudo mkdir -p /var/www/yourdomain.com/public_html
sudo chown -R www-data:www-data /var/www/yourdomain.com
sudo chmod -R 755 /var/www

Setting Up UFW Firewall on Ubuntu 16.04

UFW (Uncomplicated Firewall) comes pre-installed on Ubuntu 16.04. It provides a straightforward interface for managing iptables rules. A firewall should be one of the first things you configure after setting up SSH access.

The basic approach is to deny all incoming connections by default, then explicitly allow only the traffic you need. Configure UFW before enabling it:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh from your-desktop-ip/32
sudo ufw allow 'Apache Full'
sudo ufw enable

The ufw allow 'Apache Full' command opens both port 80 (HTTP) and port 443 (HTTPS). It also includes rules for WebSocket support, which is useful if you later add real-time features to your sites.

Test the firewall from an external IP that is not in your allowed list. The connection should be refused. If you lock yourself out of SSH, you can access the server through the provider's console and adjust the rules.

Warning: If you enable UFW without first allowing SSH from your IP, you will lock yourself out of the server. Always add the SSH rule before enabling the firewall.

Hardening Your Ubuntu 16.04 Server

With the LAMP stack installed and connectivity confirmed, the next step is hardening. This means reducing the server's attack surface by disabling unnecessary features and adding protective layers. The Apache security configuration guide covers additional hardening steps that complement the measures described here.

Disable Unused Apache Modules

Apache ships with several modules that are not needed for most deployments. These modules can leak information about your server configuration. Disable them:

sudo a2dismod status autoindex cgi

The mod_status, mod_info, and autoindex modules expose server information that is useful to attackers profiling your system.

Suppress Server Signature Information

By default, Apache includes version information in HTTP response headers. Edit /etc/apache2/conf-enabled/security.conf:

ServerTokens Prod
ServerSignature Off

These settings tell Apache to show only that it is Apache (not the version number) and to suppress the server signature on error pages.

Install and Configure Fail2Ban

Fail2Ban monitors log files for failed login attempts and automatically bans IP addresses that show malicious behaviour. It is particularly useful for protecting SSH. Install it:

sudo apt install fail2ban -y

The default SSH protection in Fail2Ban is reasonable, but you can tune it for production servers. Edit /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = ssh
bantime = 3600
maxretry = 3

This bans an IP for one hour after three failed login attempts. For servers exposed to the public internet, this significantly reduces the effectiveness of brute-force attacks.

Enable Automatic Security Updates

Security patches need to be applied promptly, but manually checking for updates on a server is easy to forget. Enable automatic security updates:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

This installs security updates automatically without requiring manual intervention. It does not replace regular maintenance checks, but it closes the window between a security patch being released and it being applied.

Set Up a Basic Web Application Firewall

For additional protection against common web attacks, enable mod_security (an open-source WAF module for Apache) and mod_evasive (which helps mitigate simple denial-of-service attempts):

sudo apt install libapache2-mod-security2 mod-evasive
sudo a2enmod security2 evasive

After installation, configure mod_security with the OWASP Core Rule Set or a similar ruleset for meaningful protection. The default configuration blocks some attacks but is not comprehensive on its own.

Monitoring Your VPS After Setup

Once the server is running, you need ways to monitor its health. Basic monitoring includes checking disk space, memory usage, and service status.

Check disk space:

df -h

Check which directories consume the most space:

du -sh /var/www/*

Set up logrotate for Apache and MySQL logs to prevent the /var/log partition from filling up over time. Ubuntu configures this by default, but verify that it is working and adjust retention periods if your logs are large.

Set up a simple uptime check. You can use a free service like UptimeRobot to monitor whether your server responds on ports 80 and 443. This catches situations where Apache crashes and stays down until you notice.

When to Consider Upgrading to a Newer Ubuntu Version

If you are running Ubuntu 16.04, plan a migration to a supported LTS release. Ubuntu 22.04 LTS is the current recommended version for new servers. The upgrade process involves backing up your data, spinning up a new server with the newer OS, transferring configurations and data, and testing before switching DNS.

Ubuntu 16.04 continues to receive extended security maintenance (ESM) through Ubuntu Advantage, but this requires a paid subscription. For personal projects or small business servers, the cost may not be justified when a supported LTS version is available at no extra cost.

If you need to install WordPress on your new server after upgrading, the WordPress installation guide walks through the full process with LAMP.

Moving Forward with Your VPS Setup

Setting up a VPS from scratch gives you a clean, controlled environment that you understand completely. The steps in this guide create a functional web server with reasonable security defaults. From here, the next steps depend on what you are building.

If you are deploying a PHP application, configure your virtual host properly, set up Composer for dependency management, and test the application in a staging environment before pointing live traffic at it. If you are serving static content, make sure your caching headers are correct and consider a CDN for assets that benefit from edge caching.

Regular maintenance matters. Check your logs periodically, apply updates when they are released, and monitor disk space. A server that is set up well and maintained consistently is more reliable than one that is forgotten after the initial setup.

If you are working through this guide and run into a specific issue, or if you need help planning a migration from Ubuntu 16.04 to a newer release, you can get in touch with details of your setup and what you are trying to achieve.

Frequently Asked Questions

What should I do if I get locked out of my server after changing SSH settings?
If you can access your server through the hosting provider's VNC console or similar out-of-band method, log in as root and check /etc/ssh/sshd_config for typos. Common mistakes include a misspelled directive name or an incorrect IP address in the AllowUsers line. After fixing the configuration, reload the SSH daemon with systemctl reload sshd. Test from a separate terminal before closing the console session.
How do I monitor disk space on a minimal VPS?
Run df -h to see partition usage at a glance. To identify what is consuming space, use du -sh /var/www/* for website directories or du -sh /var/log/* for log files. Set up logrotate to automatically archive and remove old log files before they fill your disk. Running apt clean periodically also removes downloaded package files that are no longer needed.
Can I run multiple PHP versions on the same server?
Yes. The standard approach is to use PHP-FPM with separate pools per site. Each pool runs as a different system user and can point to a different PHP version. This is the method used by most shared hosting providers. It requires more configuration than a single PHP version but gives you flexibility when different projects have different requirements.
How do I know if my server needs a restart after updates?
Kernel updates on Ubuntu require a reboot to take effect. Ubuntu 16.04 does not have a built-in mechanism to automatically reboot after a kernel update, so you need to schedule this manually or use a tool like unattended-upgrades with the automatic-reboot option enabled. Check if a reboot is needed by comparing the running kernel version with the installed one using uname -r and dpkg -l linux-image-*.
Is it safe to leave root login disabled permanently?
Yes. With a non-root user account that has sudo privileges and SSH key authentication configured, there is no practical need for direct root login over SSH. Using sudo provides an audit trail of which commands were run with elevated privileges. If you need to perform administrative tasks that require root, you can use sudo from your regular user account. Keep the root password stored somewhere secure in case you ever need it for recovery through a console session.
What basic services should run on a new web server?
For a basic web server, the essential services are sshd (for remote management), apache2 (or nginx), mysql (or mariadb), and ufw (for firewall management). On a production server, you may also want fail2ban (for SSH protection), unattended-upgrades (for automatic security patches), and a monitoring agent if you use a service like UptimeRobot or Datadog.