How to Sep Up Your VPS for Web Hosting with the LAMP Stack Step By Step
Tags: linux, beginners, tutorial, webdev
Published: 2020-12-05 22:24:54

Server administration is an important skill to have as a web developer, but it is still many times overlooked. Today we'll learn how to install the LAMP (Linux, Apache, MySQL, and PHP) stack on a VPS and let it ready to host our website.

Working with servers is mainly done using the console, what might look a little intimidating when you are not used to it, but don't worry, I'll help you to get comfortable with it by guiding you step by step through the whole process.

This is what we are going to learn:
- [First Steps. Getting a VPS and connecting to it](#vpn)
- [Managing Users in Our VPS](#users)
- [Installing the LAMP stack in our VPS](#lamp)
- [Let's Set Up a Firewall in Our VPS](#firewall)
- [Setting up your Domain](#domain)
- [Let's add a FTP Server](#ftp)
- [Adding a SSL certificate to our VPS](#ftp)

**Prerequisites**: Being familiar with Linux can be helpful but it's not a requirement.


<a name="vpn"></a>

## First Steps. Getting a VPS and connecting to it
There are plenty of VPS providers. Most of the hosting companies offer VPS plans in additions to their shared hosting, and there are also cloud providers, such us AWS or Digital Ocean. In this guide, I would go with Digital Ocean, but the installation and setup of the VPS will be the same for all VPS, regardless of the provider.

With Digital Ocean, a basic VPS cost $5/month at the time of writing this tutorial. If you want to try it, <a href="https://m.do.co/c/d17d65ffd897" target="_blank"> here </a> is a link with a 100$ credit so you can test it without spending any money. 

### Let's create our VPS 

The very first step is going to <a href="https://m.do.co/c/d17d65ffd897" target="_blank"> DigitalOcean </a>, opening an account, and creating a droplet —this is how they call a VPS— by clicking on any of the buttons shown below.

<img src="https://www.soniagarcia.dev/blog-images/vps/01_create_a_doplet_in_digital_ocean.png" class="img-fluid" width=70% height=auto alt="install lamp stack in digital ocean">

Choose the OS to install (I'm going with Ubuntu), a plan ('Basic' should be enough), and the virtual machine, this is the physical resources of your server (the most basic one, which cost $5/month, should be enough).

<img src="https://www.soniagarcia.dev/blog-images/vps/02_setting_a_ubuntu_vps_on_digital_ocean.png" class="img-fluid" width=70% height=auto alt="ubuntu vps in digital ocean">

I'm going with a minimal server here, so, I'm not going to choose any additional feature. Select the data center region (one close to where you are).

<img src="https://www.soniagarcia.dev/blog-images/vps/03_server_region.png" class="img-fluid" width=70% height=auto alt="region">

Last thing you want to set is the authentication method (how do you access to your VPS) I prefer to use a SSH key for a more secure authentication, but you can choose to authenticate with a password if you prefer so.

If you are not familiar with SSH keys, let me explain you what they are.

Secure Shell (or SSH) is a cryptographic network protocol that allows to connect with a remote server in a more secure way than logging with a password. Basically because a password can eventually be cracked with a brute force attack, but not SSH keys.

When you click on the SSH key option in Digital Ocean you will be prompted to enter one.

<img src="https://www.soniagarcia.dev/blog-images/vps/04_setting_a_ssh_key.png" class="img-fluid" width=70% height=auto alt="vps-ssh-key">

You might already have one in your computer. Let's check it:

If you are on Windows, open the terminal and go to the */Users/USERNAME/.ssh* dir (This is the default place to store ssh keys). Type `dir` to see the contents of the directory. If you have a file called *id_rsa.pub*, it is your ssh key.

<img src="https://www.soniagarcia.dev/blog-images/vps/05_check-if-you-have-an-ssh-key.png" class="img-fluid" width=70% height=auto alt="check-if-you-have-an-ssh-key">

If you are on Mac, the directory where you have to check is `cd ~/.ssh`. And type `ls` instead of `dir` to inspect its content.

If you have a key, type `cat id_rsa.pub` to see it.

<img src="https://www.soniagarcia.dev/blog-images/vps/06.inspect-ssh-key.png" class="img-fluid" width=70% height=auto alt="inspect-ssh-key">

Copy it and paste it in the Digital Ocean input field. Give it a name of your choice to identify it.

One note here: If you plan to connect with PuTTY, you need to add the .ppk key instead of the -pub one. If you don't even know what PuTTY is, ignore this paragraph.

<img src="https://www.soniagarcia.dev/blog-images/vps/07.add-ssh-key-to-droplet.png" class="img-fluid" width=70% height=auto alt="add-ssh-key-to-droplet">

If you don't have any ssh key, run `ssh-keygen` to generate one. Leave the file name blank and just press return. The key will be generated and stored in the *.ssh* dir

<img src="https://www.soniagarcia.dev/blog-images/vps/08.generate-ssh-key.png" class="img-fluid" width=70% height=auto alt="generate-ssh-key">

Finally, add a name for your droplet, and tags if you want to (I'm just adding a name), and click *create*.

You can also add the backups functionality, which is something you might want to consider for your production sites. Here, as this is just a test droplet for this article, I'm not adding it.

<img src="https://www.soniagarcia.dev/blog-images/vps/09.create-droplet.png" class="img-fluid" width=70% height=auto alt="create-droplet">

What we are doing here is just creating the VPS with its Operative System (The Ubuntu distribution of Linux in our case). Next we'll learn how to manage it and install everything we need to be able to host our website.

Now Digital Ocean will set up your server, what can take a couple of minutes or less (you will see a progress bar).

Once the server has been provisioned, it will show the server IP address and a menu with many options.

<img src="https://www.soniagarcia.dev/blog-images/vps/10.install-lamp-in-ubuntu.png" class="img-fluid" width=70% height=auto alt="install lamp in ubuntu">

If you selected the password authentication method, you need to receive the root password for the droplet you have created. You will get it emailed to your account in a couple of minutes. If you set the ssh authentication method, you don't need a root password.


### Connecting to our VPS ###

The root password or the ssh key is what we use to authenticate ourselves when trying to connect to our VPS from our computer, but we need a way to connect to the remote server.

You can use the Terminal if your are on Mac. However, if you are on Windows, you cannot use the command prompt. Instead you can use an enhanced terminal like <a href="https://gitforwindows.org/"   target ="_blank"> GitBash </a> or <a href="https://cmder.net/" target="_blank"> Cmdr </a>(I'll use this one), or a special tool to connect to remote computers such as <a href="https://www.putty.org/" target ="_blank" > PuTTY</a>.

To connect using GitBash or Cmdr using SSH, enter the following command:`ssh root@YOUR-DROPLET-IP`

You will find the IP next to your droplet name if you go to 'droplets' in your Digital Ocean account.

<img src="https://www.soniagarcia.dev/blog-images/vps/11.setting-up-vps.png.png" class="img-fluid" width=70% height=auto alt="setting upa vps">

It will prompt you for the password you created when creating the ssh key (if you did so).

<img src="https://www.soniagarcia.dev/blog-images/vps/12_connect_to_vps_ssh.png" class="img-fluid" width=70% height=auto alt="connect to vps ssh">

If you don't use SSH but a password to authenticate, the first time you log in to your VPS, you will be probably asked to change the password.

Now we are in our remote server. 

When you connect to your server, you are taken to the user's home directory. This is what the tilde (~) means. We are in the home director of the root user. If we want to see what is there, we can use the `ls` command. Nor *dir* because now we are in the server not in our machine, and the server OS is Linux.

<img src="https://www.soniagarcia.dev/blog-images/vps/13_ls.png" class="img-fluid" width=50% height=auto alt="ls">

We are not going to see anything because the directory is empty. Let's go one directory up using the `cd ..` command and see what's in there.

<img src="https://www.soniagarcia.dev/blog-images/vps/14_linux_file_system_in_vps.png" class="img-fluid" width=70% height=auto alt="linux file system in vps">

The / directory is called the *root* directory. This root has nothing in common with the root user. It is the most upper directory in your server (or your partition to be more precise) (like *c:\* in Windows).

I'm not going to get into details about Linux file system here, but let me walk you through some of the most important directories.

The *bin* directory contains the essential Linux binaries (programs). In *etc* you will find configuration files. In *home*, the home folder for each user, except for the root user, whose home directory is in *root*. Our *usr* folder will be empty because we don't have any user yet, but it will contain the applications installed for each user, in contrast with the *bin* dir, where there are the programs used by the system.

You can use the `clear command` to delete everything in your terminal.


<a name="users"></a>

## Managing Users in Our VPS

So far we have only the root user in our VPS. Let's create an additional user so that we don't have to connect to our server as the root, which is not a good practice.

On Linux, the root user is equivalent to the administrator user on Windows. It's not advisable to log in to your system as root in order to minimize the risk of breaking something.
So, let's create a user using the `adduser USERNAME` command.

You will be asked to create a password for the recently created user, make sure you choose a strong one. Keep in mind that as you type the passwords you won't see the cursor moving.

<img src="https://www.soniagarcia.dev/blog-images/vps/16_add_user_to_linux_vps.png" class="img-fluid" width=80% height=auto alt="add users to linux vps">

To change the password for one user  `passwd USERNAME`.

To delete a user `userdel USERNAME`.

To list all users, you can use `cat /etc/passwd`.

The *cat* commands list the contents of a file. 
The output shows a lot more users than you expected because it lists the system users too. 

<img src="https://www.soniagarcia.dev/blog-images/vps/17_users_list.png" class="img-fluid" width=80% height=auto alt="add users_list">

Each line represents a user and it has 7 fields, separated by a colon.

<img src="https://www.soniagarcia.dev/blog-images/vps/17_b_cat_command.png" class="img-fluid" width=80% height=auto alt="cat command">

Generally, a system user has a UID smaller than 1000. 

Let's now log out using the `logout` command and login with the new user we have created.

Now, if you try to log in using ssh `ssh USERNAME@IP`, you get a *Permission denied (publickey)* error. This is because you need to change the configuration of your SSH in *sshd_config*.

Let's open the file with Vim (a text editor that comes out of the box with Linux). `sudo vim /etc/ssh/sshd_config`

If you are not used to command line text editors, it might look a little tedious to work with Vim, but with a little patience you'll get used to it.

To edit the file, press I (now you should see *--INSERT* at the bottom of the screen). Look for the following piece of text:

`# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no`
And change *PasswordAuthentication* to *yes*.

<img src="https://www.soniagarcia.dev/blog-images/vps/18_config_ssh.png" class="img-fluid" width=80% height=auto alt="change ssh config">

To save the changes press *scape* and type `:wq`, this is to quite saving the changes. To just quit without saving the changes, use `:q`.

Reload the ssh configuration with the command `service sshd reload`.

Now you will be able to login with the non-root user using the password you assigned to it:

Although this is something you are allowed to do and you should know how to do it, I would not recommend to allow login using a password. For that we'll need to associate a ssh key to the user we have just created so that he/she can log in via SSH.

You can generate a new SSH key or use one that you already have in your computer. I will use an existing one, but remember that to create one you should use `ssh-keygen`.

To associate the key with the new user, logout from the server (by typing `logout`). Now you are in your computer. Execute:

`ssh-copy-id -i  ~/.ssh/id_rsa.pub USERNAME@SERVER-IP` if you are on Linux or Mac.

The first parameter is the path to the key and the second the user and IP in the remote server 

*ssh-copy-id* append the contents of your local public key file to a remote file called authorized_keys.

In windows, this command would not work and, as far as I know,  there is no a similar one. So let's try to replicate that behavior with: 

`cat C:/Users/USER-DIR/.ssh/id_rsa.pub | ssh USERNAME@SERVER-IP "cat >> ~/.ssh/authorized_keys"`

If the *.ssh* dir does not exits in your vps, you will get an error.

<img src="https://www.soniagarcia.dev/blog-images/vps/25_error.png" class="img-fluid" width=80% height=auto alt="error ">

In that case, you need to first create the directory:
`cat C:/Users/USER-DIR/.ssh/id_rsa.pub | ssh USERNAME@SERVER-IP "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys" `

Now if we try to log into the vps, we won't be asked for the user's password anymore.  What we are asked is the key password we added to our ssh key.

<img src="https://www.soniagarcia.dev/blog-images/vps/26_lamp_on_vps.png" class="img-fluid" width=80% height=auto alt="lamp on vps">

So, now that we are able to log as the non-root user using a ssh, let's disallow password authentication.

`vim /etc/ssh/sshd_config`

Set *PasswordAuthentication* to  *no*.

This new user is a regular user, meaning that there are certain tasks she/he would not have permission to perform.

If we want to allow a user to execute superuser tasks, we can elevate the user and give him/her superuser privileges. We can upgrade the non-root user by adding it to the *sudo* user group.

`usermod -a -G sudo USERNAME` Make sure you are executing this command with the root user.

*usermod* calls the program, *-a* adds to a group, *-G* specifies the group.

Now, let's check if the user has sudo privileges by checking the group the user belong to with the command `groups USERNAME`.

<img src="https://www.soniagarcia.dev/blog-images/vps/20_usermod.png" class="img-fluid" width=80% height=auto alt="usermod command">

From now on,  the user sonia (in my case) can execute root commands by prefixing the with *sudo*.

For example, to create a new user: `sudo adduser peter`

If you get a sudo command not found, run `apt-get install sudo`.

You might be asked to enter your password. This will happen if this is the first time you're using *sudo* within the current session.

One thing I would recommend you to do is to do not allow log into the server using the root user. This is a security measure you can take to make it harder for hackers to try to get into your server. The goal of many hackers is to get root access to a site. So, let's try to do all we can to avoid this.

Open the configuration file with the command `vim /etc/ssh/sshd_config` and edit the line *PermitRootLogin yes* by setting it to *no*.

You might need to restart your droplet. To do it: `sudo shutdown -r now` or `sudo reboot`.


<a name="lamp"></a>

## Installing the LAMP stack in our VPS

At this point we have a VPS with only the OS installed. Actually there is something more than the OS because when we installed our Linux Distribution (Ubuntu) some programs where installed along with the Linux OS.

In order to host and serve websites and applications from our VPS we need to install some software. There are multiple options here, but we are going to install what is called the LAMP stack. LAMP stands for Linux, Apache, MySQL, PHP, and it is one of the most popular stacks for hosting and serving websites and web apps written in PHP.

If your website does not use PHP, you should install any other software you need, like Python if your site is build with Python.

There are other popular stacks, like LEMP, which uses Ngnix instead of Apache or MEAN, which uses MongoDB, Express, Angular and Node. Or you can make your own stack using any combination of them.

You can of course setup IIS and MSSQL, but they are not free.

Before we install anything, let's make sure the programs ('packages' is how they are called in Linux) that are already installed in our server are up to date. 
Run `sudo apt update` to update any package that need to be updated.

As you can see I'm prefixing the command with *sudo* because I'm logged in with a non-root user. Remember that it is a good practice to avoid login in with the root user.

Once it is done updating, we are ready to start installing the different pieces of software that are part of the LAMP stack.

### Apache
Let's start with Apache, the web server.

Run `sudo apt install apache2` to install it.

You will be prompted to confirm if you want to proceed with the installation, enter *Y*.

Now, let's run it:
`systemctl start apache2.service`

And check if Apache has been installed correctly by opening your browser and typing *http://your-vps-ip*

You should see a page similar to this one:

<img src="https://www.soniagarcia.dev/blog-images/vps/21_install_apache_in_ubuntu.png" class="img-fluid" width=80% height=auto alt="apache on lubuntu vps">

If you cannot see the apache page, it might be because the server firewall is blocking the traffic.

Ubuntu comes with a firewall installed out of the box, the Uncomplicated FireWall (UFW). By default it should be disabled, but let's check if it has been enabled with the command: `sudo ufw status`

If the status is active, let's disable it for now. We'll come back later and enable and configure it. `sudo ufw disable`

You should be able to navigate to the Apache page now.

Here are some basic commands to start, stop, and, restart Apache.

`
//Start command 
systemctl start apache2.service

//Stop command 
systemctl stop apache2.service

//Restart command
systemctl restart apache2.service
`

Notice that those commands work with Ubuntu(Debian) Linux distributions. For other distributions the commands might be different.

Now we are ready to server webpages, but those web pages might need a database to store data that they will display. So, let's install a database server. As we are installing the LAMP stack, we'll install MySQL.


### MySQL
 
To install MySql, simply run `sudo apt install mysql-server`.

When done, it's advisable to install a script that helps us make our DB secure. `sudo mysql_secure_installation`

You'll be asked during the installation if you want to install the Validate Password Plugin.  This is a tool to make sure when you create a password it is strong by validating it against certain conditions. I won't install it.

Then, you will need to enter the password for the root user (this is not the root user of your Linux OS but the root user for MySQL). Don’t leave it blank and make sure to use a strong password. 

For the rest of the questions you can just enter Yes.

Once the installation is finished, let's verify it by executing `sudo mysql`

This will connect you to the MySQL DB as the root user, and will open the mysql console.


<img src="https://www.soniagarcia.dev/blog-images/vps/22_instal_mysql_in _a_vps.png" class="img-fluid" width=80% height=auto alt="mysql on vps">

Type **exit** to log out of mysql.

Those are the command to start, stop, and restart MySql:

`systemctl start mysql
systemctl stop mysql
systemctl restart mysql`

### Php

The last piece of the LAMPP stack is PHP. Let's install it along with **php-mysql** (a tool to connect php with the DB)  and **libapache2-mod-php,** a required component to allow Apache to handle PHP files. We can install all three at once with the following command:
`sudo apt install php libapache2-mod-php php-mysql`

And that's it. Let's test it by creating a php file and run it.

To do it, create a new file called *info.php* in *var/www/html* and open it with vim.

The */var/www/html* directory is known as the **web root**. This is where by default Apache looks for the file requested in a website URL. 

`sudo vim /var/www/html/info.php`

Type the following code (remember to press *I* to allow inserting text with Vim).

`<?php
phpinfo();
?>`

This piece of code displays information about our current Php installation.

<img src="https://www.soniagarcia.dev/blog-images/vps/23_test_php_in_vps.png" class="img-fluid" width=80% height=auto alt="lamp on vps">

Save it and quit by pressing ESC and typing *:wq*.

In your browser, navigate to *http.//your-vps-ip/info.php* and you should see a page like this:

<img src="https://www.soniagarcia.dev/blog-images/vps/24_install_php_in_ubuntu.png" class="img-fluid" width=80% height=auto alt="php on ubuntu vps">

Leaving this file in our server is not a good idea because it shows information about the server that can help malicious hackers attack it. So, let's remove it by running `sudo rm /var/www/html/info.php`.

We have successfully installed all three pieces of the LAMP stack, so technically we are ready to create and manage MySQL databases and serve web pages and applications written in Php that get dynamic data form a MySQl database. However, there are a couple more things you want to do to have a fully functional server to host and manage your website.


<a name="firewall"></a>

## Let's Set Up a Firewall in Our VPS
We'll use a firewall to add some network security by filtering incoming and outgoing network traffic based on a set of user-defined rules. 

We have different options to set a firewall in out server:
- Using  <a href="https://www.digitalocean.com/docs/networking/firewalls/how-to/configure-rules/" target="_blank"> DigitalOcean Firewall</a>

- Using iptables. Iptables is a standard firewall included in most Linux distributions. 
    I'm not going to cover iptables here. If you are interested, you can learn more <a href="https://help.ubuntu.com/community/IptablesHowTo" target="_blank"> here </a>

- Using UFW (Uncomplicated Firewall):  UFW is an interface to iptables that simplifies its use. This is what I'm going to use.

### How to set up UFW on Ubuntu
UFW should be installed with your Linux distribution, but let's make sure by running `sudo which ufw`

You'll get back something like */usrs/bin/ufw*, the directory where the ufw is installed.

If it does not return the path to ufw, then install UFW with the following command: `sudo apt-get install ufw `

Let's now check the status of the firewall: `ufw status`

It should be disabled at this point.

By default, UFW denies all incoming connections and allows all outgoing connections. This means that anyone trying to reach your server would not be able to connect, while any application within the server would be able to get out. As we want to host our website, our server should be able to respond to incoming request, so we need to modify this configuration. We do it by creating rules.

The first thing we want to allow is ssh connections so that we can connect form our local computer. To set the rule, run `sudo ufw allow ssh`.

This will allow all connections on port 22, which is the port that the SSH daemon listens on by default. 

However, if your ssh daemon is configured to use another port, you should use the same command but specifying the port instead of the service: `sudo ufw allow 2222`

To check which port ssh uses, you can run `sudo grep Port /etc/ssh/sshd_config`

As my VPS ssh connection is configured to use port 22, I can create the rule with any of those two commands:

`sudo ufw allow ssh
sudo ufw allow 22`

<img src="https://www.soniagarcia.dev/blog-images/vps/24b_ufw.png" class="img-fluid" width=70% height=auto alt="set a firewall on vps">

Now we can safely enable the firewall because we have made sure that we can connect via ssh. To do it: `sudo ufw enable`.

You will see a warning that says the command may disrupt existing SSH connections. It's ok. We can connect back.

To disable it we'll use `ufw disable`.

Connect again to the server and check the status of the firewall. This time adding the *verbose* flag to the command: `sudo ufw status verbose`.

If the status is active, the verbose flag will return additional information about the rules being applied.

<img src="https://www.soniagarcia.dev/blog-images/vps/24c_ufw_status.png" class="img-fluid" width=70% height=auto alt="set ufw on vps">

If after enabling the firewall, the status remains inactive, make sure you restart your VPS with `sudo reboot`.

There is one more thing we need to do. It is to allow incoming requests from browsers trying to visit our website. To do so, we need to create a rule to allow http and https connections.

As with ssh, this can be done by specifying the port or the connection type — this last option only if the server uses the default ports: 80 for http and 443 for https

`sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow http
sudo ufw allow https`

<img src="https://www.soniagarcia.dev/blog-images/vps/24d_ufw_http_status.png" class="img-fluid" width=70% height=auto alt="set ufw rules">

Yo can also specify the protocol if you want to limit the connections to only TCP or UDP. If you do not specify the protocol, the connection is allowed for both protocols: `ufw allow 22/tcp`.

In case you are wondering what TCP and UDP are, don't worry. They are network protocols that determine how to send data packets over the Internet. When you send an email or a page request through your browser, you are sending data that is transferred in packets. TCP and UDP protocols define how this data is sent. In most cases, allow both and you will be good.

When you run `sudo ufw status verbose`, you can see the column *From* with the values set to *Anywhere*. This means that we are allowing connections form any computer, which makes sense if we want to publish a public website.

However, if for any reason you want to limit the traffic to an specific computer or computers, you can set the IP that you want to allow to connect. 
`sudo ufw allow from xxx.x.xxx.x`

You can also allow connections to a range of ports. It that case, you must specify the protocol (tcp or udp).

`sudo ufw allow 6000:6007/tcp
sudo ufw allow 6000:6007/udp`

If you want to deny the connections to an specific port, request type or IP, you can also with *deny*.

`ufw deny 22
ufw deny ssh
ufw deny http
sudo ufw deny from xxx.x.xxx.x //IP`

Another important thing to know is how to delete a specific rule.

You can do it in two ways: 
- Specifying the actual rule to delete:
    `sudo ufw delete allow ssh
     sudo ufw delete allow 22`
- Specifying the rule id. Each rule has a numeric identifier. We can get the id by running the status command with the numbered flag: `sudo ufw status numbered`

    <img src="https://www.soniagarcia.dev/blog-images/vps/24e_ufw_http_status.png" class="img-fluid" width=70% height=auto alt="delete rule ufw">

    To delete a specific rule, run the command:
    `sudo ufw delete 2 //rule id`

    And if you want to delete all rules: `ufw reset`.

One more thing done. Let's go for the next one, which is setting virtual hosts.


<a name="domain"></a>

## Setting up your Domain
If you are hosting your website in you VPS you will probably want to use your domain. To do so we have to set a new A record of the domain pointing to the VPS IP or your domain.

You do it where your domain registration is managed. 

First make sure that your DNS is set to the registrar nameservers.

Ex: if your domain is register in GoDaddy, you must have the DNS set to goDaddy. Otherwise, the DNS records will be managed by the hosting provider (and we don't want to use any hosting provider here).

<img src="https://www.soniagarcia.dev/blog-images/vps/dns-vps.png" class="img-fluid" width=70% height=auto alt="point domain to vps">

You will need to set the name @ (@ means the whole domain) to point to the VPS IP.
Then, you want to set the canonical name (CNAME) www to the same IP than @. And also the ftp.

<img src="https://www.soniagarcia.dev/blog-images/vps/dns-records.png" class="img-fluid" width=70% height=auto alt="point domain to vps">

And that's it. You only need to wait for the changes to propagate, what can take a couple of hours.
Once it is propagated, if you browse to your domain, you will see your VPS.

But, what if you want to host multiple domains in your VPS? No problem. I'll show you how to set up multiple virtual hosts.


### Setting Up Multiple Virtual Hosts to Host Multiple Domains in our VPS
If you want to install multiple domains in the same VPS, you need to create multiple virtual hosts.

The web server(Apache) will determine which site's files to serve out based on the the hostname portion of the specified URL (the domain name).

Even if you only need to host a single website for now, I recommend that you set it up as a virtual host, which will make it easier to add more sites later.

Apache by default is configured to serve documents from *var/www/html*. Do you remember that we placed here our info.php file when testing our Php installation?

To serve files for different domains, we'll create a directory for each site we want to host within the /var/www folder.

Create a html dir and a log dir, for each domain
`mkdir -p /var/www/domain1.com/html
mkdir -p /var/www/domain1.com/log
mkdir -p /var/www/domain2.com/html
mkdir -p /var/www/domain2.com/log`

Actually you can create those folders wherever you want, but is good practice to follow conventions. 

I have created the folders for soniagm.com. 

<img src="https://www.soniagarcia.dev/blog-images/vps/30-vhost.png" class="img-fluid" width=70% height=auto alt="virtual hosts">

We need to make sure that the directories we have just created have the 755 permission (read and execute access for everyone and also write access for the owner of the file).
`chmod -R 755 /var/www`

If we check the permissions for the domain directory, we can see that its owner is the root user and the root group. As my user belongs to the root group, it will have permission to write into that dir.

<img src="https://www.soniagarcia.dev/blog-images/vps/34-vps-permissions.png" class="img-fluid" width=70% height=auto alt="virtual hosts">

Let's now create a test file (index.html, for example) in the html folder.

Navigate to the the your-domain/html folder and run `sudo vim index.html`.

This will open the empty file in vim. Paste the following code: (Remember to press I to start editing the file)

`<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
</head>
<body>
    <h1> Home of the domain </h1>
</body>
</html>`

When done, press ESC and type `:wq` to save and quit

Our file structure is ready. Let's create the virtual hosts.

To create the virtual hosts, we have to create an Apache virtual host configuration file to serve each one of your websites.

`sudo vim /etc/apache2/sites-available/domain1.com.conf
sudo vim /etc/apache2/sites-available/domain2.com.conf`

Add the following code to each file
`<VirtualHost *:80>
ServerAdmin admin@soniagm.com
ServerName soniagm.com
DocumentRoot /var/www/soniagm.com/html
DirectoryIndex index.html
ErrorLog ${APACHE_LOG_DIR}/soniagm.com_error.log
CustomLog ${APACHE_LOG_DIR}/soniagm.com_access.log combined
</VirtualHost>`

Quit with `:wq`.

The VPS by default is set to read the default 000-default.conf file.  We will need to disable the default file and enable the configuration files we have created.

`sudo a2dissite 000-default.conf
sudo a2ensite domain1.com.conf
sudo a2ensite domain2.com.conf`

You will have to restart Apache for those changes to take effect: `sudo systemctl restart apache2.service`.

Visit http://your-domain/ and you should see the index.html page you created


<a name="ftp"></a>

## Let's Add a FTP Server
You will need to be able to upload files from your computer to your VPS. We can use FTP to do it. Probably, you already have a FTP client such as FileZilla installed in your local machine, what we need to do now is to install a FTP server in out VPS.

I'm going to install <a href="https://security.appspot.com/vsftpd.html" target="_blank"> Vsftpd </a>

`sudo apt install vsftpd`

Start the service manually: `sudo systemctl start vsftpd`

And enable it to start when the server starts: `systemctl enable vsftpd`

As with any other service, you can check it status with `service vsftpd status`.

Next, in order to allow access to FTP services from our (and others) computer, we have to open port 20 and 21:

`sudo ufw allow 21/tcp
 sudo ufw allow 20/tcp`

Now let's setup and secure our FTP server.
Before we modify the vsftpd config file, let's make a backup: `sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig`

<img src="https://www.soniagarcia.dev/blog-images/vps/35_ftp.png" class="img-fluid" width=80% height=auto alt="install ftp in vps">

Let's now open the config file with vim and make sure those config options are set up:

`listen=NO   			# prevent vsftpd from running in standalone mode
listen_ipv6=YES		        # enable vsftpd to listen on an IPv6 socket i
anonymous_enable=NO             # disable  anonymous login
local_enable=YES		# allows local logins
write_enable=YES		# enable FTP commands which change the filesystem
dirmessage_enable=YES	        # enable showing of messages when users first enter a new directory
xferlog_enable=YES		# maintain a log file detailing uploads and downloads
connect_from_port_20=YES        # use port 20 (ftp-data) on the server machine for PORT 
local_umask=022		        # value of umask for file creation for local users
xferlog_std_format=YES          # keep standard log file format
pam_service_name=vsftpd         # name of the PAM service vsftpd will use`

After modifying the conf file, restart the ftp service: `systemctl restart vsftpd`.

Now you should be able to connect to your server via ftp using any of the users.
Open a new terminal window where you won't be connected to your VPS and run `ftp VPS_IP`.

<img src="https://www.soniagarcia.dev/blog-images/vps/36_connect_ftp.png" class="img-fluid" width=70% height=auto alt="ftp in vps">

To disconnect, enter 'bye'.

<img src="https://www.soniagarcia.dev/blog-images/vps/37_bye_ftp.png" class="img-fluid" width=70% height=auto alt="bye ftp in vps">

You might prefer to use FileZilla or another client with a graphical interface to work with FTP. Now that we have made sure that we can connect to our server, you can configure your client as usual.

Here you can see how I have connected to my Digital Ocean Droplet using FileZilla.

<img src="https://www.soniagarcia.dev/blog-images/vps/38_filezilla.png" class="img-fluid" width=70% height=auto alt="filezilla to vps">


<a name="ssl"></a>

## Adding a SSL certificate to our VPS
SSL stands for Secure Socket Layer, and it is a way to encrypt the sensitive information sent over the Internet. Sensitive information like usernames, passwords and credit card info can be sent safely, out of the reach of malicious hackers, making your site more secure. This is why when users visit a site that doesn't have an SSL certificate, their browsers warn them: "This connection is not secure."

So, its highly advisable to install a SSL certificate even if your site is not sending sensitive information, because you don't want this unfriendly message to be shown when a user try to browse your website, right?

You have two options: add a free certificate or buy a paid one and upload it to your VPS. In most of the cases, a free one would be enough and it's what I'm going to do here. I'm going to install a free SSL certificate from Let's Script.

In order to be able to add the free Let's Script certificate to out Digital Ocean droplet, we must have the DNS of our domain pointing to Digital Ocean DNS. 
<img src="https://www.soniagarcia.dev/blog-images/vps/38-digital-ocean-nameservers.png" class="img-fluid" width=80% height=auto alt="digital ocean nameservers">

If you don't know how to do it, you can check  <a href="https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars" target="_blank"> this guide </a>

Do you remember that in order to [associate our domain with our VPS](#domain) we added some DNS records? Well, since now we have changed the nameservers, we'll need to do it again. This time from Digital Ocean control panel.

First of all, we need to associate a domain to our droplet. Click 'Create' in the top right, and select Domains/DNS.
<img src="https://www.soniagarcia.dev/blog-images/vps/38-digital-ocean-add-domain.png" class="img-fluid" width=80% height=auto alt="digital ocean domain name">

Now, enter the domain name in the Enter Domain field and click 'Add Domain'.

<img src="https://www.soniagarcia.dev/blog-images/vps/40-digital-ocean-vps.png" class="img-fluid" width=70% height=auto alt="digital ocean vps">

This will take us to the screen where we can add DNS records to our domain. Those are the records you have to add:

<img src="https://www.soniagarcia.dev/blog-images/vps/41-digital-ocean-set-dns-records.png" class="img-fluid" width=70% height=auto alt="digital ocean vps">

Remember that you need to wait for the changes to propagate, what can take a couple of hours.

And that's it. You are ready to start serving your websites from your own VPS.

Thanks for reading it!