DEV Community

Cover image for How you can host websites from home
Dominik Rusac for Lloyds digital

Posted on • Edited on

How you can host websites from home

Have an old PC or laptop that you are not using anymore? Well, guess what? You can turn it into a web server and host your website from your home network to the whole world! If you happen to have a Raspberry Pi, that’s even better because Pi is silent and very low on power consumption.
However, any computer that can run Ubuntu or similar OS will do just fine!

We will talk about network setup, firewall, Apache, virtual hosts, dynamic IP problem and more. Go make yourself a cup of coffee and dive into building your own web server at home!


Requirements:

  • PC/Laptop/Raspberry Pi with Ubuntu/Ubuntu Server OS installed
  • Username and password for accessing router settings

We’ll talk about:

For setting up web server I will use Raspberry Pi 3 with Ubuntu 18.04 LTS installed. Always look for LTS (Long Term Support) version of Ubuntu when downloading it from the official website. If you are confident with terminal, you can also use Ubuntu Server. At the time of writing this blog, the latest Ubuntu LTS version is 20.04 and is supported until April 2025.

Port forwarding

Once you have your Ubuntu up and running, the first thing I recommend doing is to configure port forwarding on your home network. We are doing this to enable access to our web server over the internet. You can do this using any computer that is connected to your home network.

To access your router settings, you need default gateway IP address. To get it use Command Prompt/Terminal and enter one of three commands, depending on which OS you are currently using. Default gateway IP address is usually 192.168.1.1 or similar.

    ipconfig | findstr /i "Gateway"       // Windows - Command Prompt
    ip r | grep default                   // Ubuntu - Terminal
    route get default | grep gateway      // Mac OS
Enter fullscreen mode Exit fullscreen mode

Once you find your default gateway IP address, enter it in your web browser. You will need to enter the username and password to log in and get access to router settings. Those credentials could often be found at the bottom of a router, usually on a small sticker. If not, you can look online to find out the default credentials for your router model.

When you successfully log in, look for “Port forwarding” or “Virtual Servers Setup”. Different routers can name the same settings differently. You need to add two new entries to allow traffic through ports 22 for SSH and 80 for web server.

To do that correctly, you need the local IP address of the computer which will be used as a web server. In my case it’s Raspberry Pi which is on Ubuntu so to get Raspberry Pi local IP address all I have to do is open Terminal and enter this command:

    hostname -I
    // 192.168.1.22
Enter fullscreen mode Exit fullscreen mode

Raspberry Pi local IP address is similar but for sure different from default gateway IP address. We need to point incoming requests to our local server address and we’ll do that through ports 22 and 80, that’s why we need our local server IP address.

So, in your router settings, you need to add those two ports to allow traffic through them to your local server IP address. When adding port 22 you can name it “SSH”, under “Server IP Address” enter your local server IP (in my case it’s 192.168.1.22) and under “External/Internal Port Start/End” enter “22”. Use TCP protocol. Do the same for port 80 and name it “Apache”.

Ok, now you have these ports configured on the router side. Go to canyouseeme.org and check if ports 22 and 80 are opened. There are two fields, “Your IP” which shows you your public IP address and “Port to check”. Simply enter port number 22 or 80 and click “Check Port”.

Don’t worry if you get an “Error: I could not see your service on your_ip on your_port”, that’s perfectly fine. That’s because the firewall on your server is doing a good job blocking all disallowed connections. We will get to that.

Initial server and firewall configuration

On a freshly installed Ubuntu, it’s a good idea to do some basic server configuration so the server is ready for future use. To start configuring, open Terminal on your server (in my case Raspberry Pi) and follow along.

First of all, we'll create a new user which we’ll use to log in into the server over SSH, both inside and outside of our home network (local and external). Also, we will set a new user as “superuser” which means it will have root privileges.

This allows our new user to run commands with administrative privileges by putting the word “sudo” before each command. When creating a new user you will have to enter a password and some basic user info.

    sudo adduser john                  // create new user john
    sudo usermod -aG sudo john         // add user john to sudo group
Enter fullscreen mode Exit fullscreen mode

Our new Ubuntu user should now be ready, but before we can log in over SSH, we need to configure a firewall. We need to allow port 22 through the firewall so we can log in with our new user over SSH, both locally and externally.

    sudo ufw status numbered          // check current firewall status
    sudo ufw allow OpenSSH            // allow port 22 through firewall
    sudo ufw enable                   // enable firewall
Enter fullscreen mode Exit fullscreen mode

By enabling firewall and allowing port 22 through, now it’s possible to connect to our server using SSH. You should be able to connect to the server from any computer connected to your local network, and also if you have done port forwarding right you should be able to connect from anywhere in the world.

To connect to your server simply use Command Prompt or Terminal and enter the command:

    ssh john@192.168.1.22             // local connection - use your local server IP
    ssh john@xxx.xxx.xxx.xxx          // external connection - use your public IP
Enter fullscreen mode Exit fullscreen mode

If you want to connect externally, outside your local network, you can find your public IP at canyouseeme.org and also if you now check if port 22 is opened, you should get “Success: I can see your service on your_ip on port 22”. That means port forwarding and initial server setup are properly done. Good job!

Install Apache web server on Ubuntu

Apache web server is one of the most popular web servers and it’s fairly simple to install.

    sudo apt-get update               // update available software list
    sudo apt install apache2          // install apache2 package
Enter fullscreen mode Exit fullscreen mode

Apache is now installed and to make it work it’s necessary to modify firewall settings to allow external access to Apache web server.

Earlier we opened port 22 for connecting over SSH, now we need to open port 80 for Apache. If you are planning to install an SSL certificate on your website I recommend using the “Apache Full” profile which opens both 80 and 443. For non-SSL website “Apache” profile which opens only port 80 will do just fine.

    sudo ufw app list                 // list ufw application profiles
    // Available applications:
    //   Apache
    //   Apache Full
    //   Apache Secure
    //   OpenSSH

    sudo ufw allow 'Apache'           // opens port 80
    sudo ufw allow 'Apache Full'      // opens port 80 and 443
    sudo ufw allow 'Apache Secure'    // opens port 443 
Enter fullscreen mode Exit fullscreen mode

If you check your current firewall status, you should get a similar output. A firewall is now allowing traffic through port 80 if you used the “Apache" profile, and also through port 443 if you used the “Apache Full” profile.

    sudo ufw status                   // current firewall status
    // Status: active

    // To                         Action      From
    // --                         ------      ----
    // Apache Full                ALLOW       Anywhere
    // OpenSSH                    ALLOW       Anywhere
    // Apache Full (v6)           ALLOW       Anywhere (v6)
    // OpenSSH (v6)               ALLOW       Anywhere (v6)
Enter fullscreen mode Exit fullscreen mode

Go on canyouseeme.org and check if port 80 is opened. If you get “Success: I can see your service on your_ip on port 80” that means your server is accessible from the internet. Awesome!

Setting up Apache virtual hosts

Before configuring Apache to serve your own website, if you check Apache status you should get “active (running)”. To check if your website works locally enter local IP server address in your internet browser (in my case that’s 192.168.1.22).

For checking if your website is available on the internet I suggest using your smartphone. Turn off your Wi-Fi and use the mobile internet (3G/4G). Open your internet browser and enter the public IP address of your home network. If you get to default Apache landing page you can be sure your server is up and running!

    sudo systemctl status apache2   // check apache status
    hostname -I                  // get local server IP address like 192.168.1.22
    curl -4 icanhazip.com        // get public IP address of your home network
Enter fullscreen mode Exit fullscreen mode

Apache by default serves documents from the /var/www/html directory. We’ll leave this directory as is and create our new directory which we’ll use to serve our website from.

    sudo mkdir /var/www/mywebsite
    sudo nano /var/www/mywebsite/index.html
Enter fullscreen mode Exit fullscreen mode

Inside “mywebsite” directory, we’ll create an “index.html” file and paste some basic HTML markup, save and close the file.

    <html>
        <head>
            <title>Hello World!</title>
        </head>
        <body>
            <h1>My website is live!</h1>
        </body>
    </html>
Enter fullscreen mode Exit fullscreen mode

In order for Apache to serve this website, it’s necessary to create a new virtual host (.conf) file. The default configuration file is located at /etc/apache2/sites-available/000-default.conf and we’ll also leave this file as is and create our new mywebsite.conf file.

    sudo nano /etc/apache2/sites-available/mywebsite.conf
Enter fullscreen mode Exit fullscreen mode

Inside mywebsite.conf file paste following configuration which is similar to the default one, but updated with your ServerAdmin, ServerName and DocumentRoot.

    <VirtualHost *:80>
        ServerAdmin your@email.com             // your email
        ServerName xxx.xxx.xxx.xxx             // your public IP address
        DocumentRoot /var/www/mywebsite        // document root of your website
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
Enter fullscreen mode Exit fullscreen mode

At this point, we need to enable created website using a2ensite command.

    sudo a2ensite mywebsite.conf         // enable mywebsite
Enter fullscreen mode Exit fullscreen mode

Don’t forget to disable Apache default website using a2dissite.

    sudo a2dissite 000-default.conf      // disable default Apache website
Enter fullscreen mode Exit fullscreen mode

Run test for configuration errors. You should get a “Syntax OK” message.

    sudo apache2ctl configtest
    // Syntax OK
Enter fullscreen mode Exit fullscreen mode

Finally, restart the Apache server for the changes to take effect.

    sudo systemctl restart apache2
Enter fullscreen mode Exit fullscreen mode

On your smartphone, open your web browser and type in your public IP address and hit enter. If you see “My website is live!” text, you have successfully configured your Apache web server, congratulations!

Useful commands

Here are some commands that you might find useful while configuring your server.

    // UFW Firewall commands
    sudo ufw allow OpenSSH
    sudo ufw allow Apache
    sudo ufw status numbered
    sudo ufw delete X

    // SSH server commands
    sudo systemctl status ssh
    sudo systemctl stop ssh
    sudo systemctl start ssh
    sudo systemctl disable ssh
    sudo systemctl enable ssh

    // Apache server commands
    sudo systemctl start apache2
    sudo systemctl stop apache2
    sudo systemctl restart apache2
    sudo systemctl reload apache2
    sudo systemctl disable apache2
    sudo systemctl enable apache2
Enter fullscreen mode Exit fullscreen mode

Dynamic IP problem

In most cases for home networks, the public IP address changes every 24 hours. Also if your router gets disconnected from the internet you will automatically get a new IP address when reconnected.

That’s a problem because every time your IP changes, to access your website you need to use the current public IP address of your network and also you need to update Apache config file. If you have a static public IP address then you are fine. Usually, ISP charges extra for static IPs.

There is a solution for this without having to pay for static IP. You can use free dynamic DNS service like no-ip.com where you can choose a free domain name and point it to your public IP address. You also need to add that domain name and your no-ip.com account credentials in your dynamic DNS router settings.

After you do that, your router and dynamic DNS service will work together and update your public IP address as it changes. This way, to access your website, you can always use the same domain name chosen on your dynamic DNS service as it always points to your current, up to date public IP address.

Conclusion

You should now have a basic understanding of how the web server works. Setting up your own web server at home is a good way to train your server administration skills. Having knowledge of setting up a server at home, you shouldn’t have problems administrating one on AWS, DigitalOcean or similar services.

Where to go from here? Well, you could buy your own domain name like mydomain.com and point it to your server IP address. After that, you can create any number of subdomains like subdomain.mydomain.com and host multiple different sites, all from one Apache instance. Also, it’s a good idea to install an SSL certificate on your website. But more on that later, I need to leave some content for my next blog. 😉

Top comments (6)

Collapse
 
africaorginal profile image
blackman

1 Please what about if I have static ip how is settings going to be.? I am using virtual machines and I want all of them to accessible online. I used VMware

2 Secondly, with the port forwarding it hast internal host and external host. What ip address will enter in both?

Collapse
 
drusac profile image
Dominik Rusac
  1. If you have a static IP then you don't have dynamic IP problem so your setup should be easier and more stable. Other than that settings are pretty much the same.

  2. In both internal and external host you should enter IP address of your virtual machine. That way through the ports traffic will be routed to your server (virtual machine).

Sorry for later reply, didn't get notification, hope that helps.

Collapse
 
leopold_pitner_ea42865440 profile image
Leopold Pitner • Edited

I have a question, the server works, I go on my phone with cellular data type in my public IP Address and it shows up, but it doesn't show what I want it to show, it just says '403 Forbidden, You do not have access to this resource', I would like to know why this happens.

Collapse
 
drusac profile image
Dominik Rusac

Try giving 777 permissions to your website root folder. Use command "sudo chmod 777 /path/to/website/folder". If this works, next step would be to see how different permissions work, like 755 instead of 777 etc...

Collapse
 
monikandrew profile image
monikandrew

Hello, I have a VPN dedicated IP address, is it possible to host my website from home using this IP address? I need this VPN because I live in China and otherwise my page will be blocked.

Collapse
 
drusac profile image
Dominik Rusac

Not sure about that, before you try it out do some google research on that, good luck!