Install Apache Web server on Azure VM instance

How to run a static website on Azure VM instance using Apache Server and Ubuntu 22.04

Azure offers a nice range of VM instances suited for various types of workloads. Starting from $3.8 per month (Bs Series), it has options available in varying price ranges. The process of instance creation through the Azure console is easy and you can create an instance for your use and install a server within minutes. You need to have an Azure subscription before you can create an instance.

Create Azure VM Instance

Start with instance creation. For resource group, select ‘create new’. Give your instance /virtual machine a name. Select the machine image. Choose ‘Ubuntu Server 22.04 LTS-x64 gen2’. If you do not find it in the dropdown menu, click on show all images and then search for Ubuntu Server 22.04. Select it as your machine image.

Now, select the size of your virtual machine. The dropdown menu only shows the vendor prescribed sizes. So, click on all sizes to check them out. You will find prices listed against VMs in the last row apart from other specifications including CPUs and RAM size. Select the one you want.

Next, you need to specifiy the ssh credentials and whether you would like to ssh using public key or password. If you select password, add a username and then a strong password which you can use to connect to your Azure VM instance later through ssh.

Move on to inbound port rules and for public inbound ports select ‘Allow selected ports’. Select all the three ports including 80, 443 and 22. This will let your server receive traffic on http and https and the port 22 is for ssh connection.

In the next step, you will create a new disk for your VM instance.  At the bottom you will find the option to create and attach a new disk. Click on it and then select the right size for your VM instance. The system will automatically attach the disk to your instance.

In the networking tab, you can continue with the default settings. The system will assign you a default virtual network and subnet to connect your server to the internet. Move on to tags and add tags to your instance and then hit review and create.

The system will validate the configurations and then once the validation is passed, you will see a notice at the top mentioning validation passed. Now, click on create button at the bottom.  The system will start deploying the instance and you will see the notification that deployment is in progress.

The deployment can take a few minutes following which you will receive the notification that deployment is complete. Now, you can go to the resource (VM Instance).

Click on the connect button at the top. If you have opted to login with public key, follow the instructions on the page. Otherwise, if you have opted to login with password, just ssh to your instance using your favorite client. Run the command:

$ssh username@IPAddress

When the system prompts if you want to continue connecting, answer yes. Provide the password for the user you created when prompted to and you will be connected. Once you have connected to the instance using SSH, it is time to install an Apache webserver on your instance.

Install the Apache Webserver on Azure VM Instance

Install Apache webserver on your Azure VM Instance. First run the updates:

$sudo apt update

Now, install Apache with the following command:

$sudo apt install apache2

Once the installation is complete, check the status of the Apache web server using the following command:

$sudo systemctl status apache2

The following output shows that the server is active and running.

  • apache2.service - The Apache HTTP Server

     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)

     Active: active (running) since Tue 2023-03-28 17:51:07 UTC; 54s ago

       Docs: https://httpd.apache.org/docs/2.4/

   Main PID: 8789 (apache2)

      Tasks: 55 (limit: 1076)

     Memory: 9.2M

        CPU: 31ms

     CGroup: /system.slice/apache2.service

             ├─8769 /usr/sbin/apache2 -k start

             ├─8771 /usr/sbin/apache2 -k start

             └─8772 /usr/sbin/apache2 -k start

Now, enable the server to start at every system boot using the following command:

$ sudo systemctl enable apache2

The output will look like the following:

Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.

Executing: /lib/systemd/systemd-sysv-install enable apache2

Now, we can open the required ports through the firewall to allow our server to connect to the internet on these ports. Run the following command:

$ sudo ufw app list

The output will be as follows :-

Available applications:

  Apache

  Apache Full

  Apache Secure

  OpenSSH

Now, you can select to allow Apache full access which will open both http and https ports; ports 80 and 443; or since we have not installed ssl yet, you can only open port 80 right now.

Run the following command:

$ sudo ufw allow ‘Apache’

The root folder on Apache web server is /var/www/html. If you want to run your website from a different directory like /var/www/domain/public_html, you can create the directory using mkdir command. (You can run more than one sites from the same server for which you will need to create different root folders for each one and separate vhost files.)

Suppose, you have a domain named examplesite.com and you want to create a new root dierctory for it. You can run the following command:

$sudo mkdir /var/www/examplesite

Assign the ownership of the folder to the current user.

$ sudo chown -R $USER:$USER /var/www/examplesite

S sudo chmod -R 755 /var/www/examplesite

Now, you can upload a simple index.html file to see how your site loads at the front end.  However, to serve the content included in the index.html file, first you need to add a vhost file with the correct directives.

You can create a new vhost file inside the sites-available directory with the following command:

$ sudo nano /etc/apache2/sites-available/examplesite.conf

Now add this vhost configuration to this file specifying the document root and site name.

<VirtualHost *:80>

ServerAdmin webmaster@localhost

ServerName  examplesite.com

ServerAlias  www.examplesite.com

DocumentRoot /var/www/examplesite

ErrorLog       ${APACHE_LOG_DIR}/error.log

CustomLog   ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

Replace the ServerName and ServerAlias with the appropriate domain names. For the DocumentRoot folder, specify the folder you are planning to use to load your website. If you selected to continue with the default directory, it is /var/www/html. If you are planning to run only one website on the server, you can continue with the default root folder or create new ones named after the website so they are easy to remember and find.

To enable the new vhost file for your domain, run the following command:

$sudo a2ensite examplesite.conf

You will receive an output saying enabling site examplesite.

You can now disable the default website specified inside the 000-default.conf with the following command:

$sudo a2dissite 000-default.conf

Once done, check for configuration errors using:

$sudo apache2ctl configtest

The output should look like – Syntax OK.

Now, we can restart the Apache server so that the changes we have made can take effect.

$ sudo systemctl restart apache2

You can start, stop, or reload the Apache server on Ubuntu Jammy using the following commands:

$ sudo systemctl start apache2

$ sudo systemctl stop apache2

$sudo systemctl reload apache2

Now, if you check the public ip of your instance, you will see the default Ubuntu page at this stage.

It shows that Apache webserver is installed and working on your VM instance. To check with a simple static website, you can add an index.html file to the root folder:

$ sudo nano /var/www/domain_name/index.html

And the following content to this file :-

<html>

    <head>

        <title>Welcome to my blog!</title>

    </head>

    <body>

        <h1>Thanks for visiting!</h1>

<p> This is just a test website. Soon you will see some wonderful content here. </p>

    </body>

</html>

Save and exit. Ctrl X + Y and enter.

For example, I have used the default index.html, which contains the html and css for the default Ubuntu page and made some edits to make it look like the following:-

Now, you have a static website hosted on your Apache server on Azure VM Instance. When uploading your own files to the default root folder, you must first delete the Ubuntu default index.html page. If you have created a different document root, then no problem.

Install Apache Web Server using Azure CLI

You can also install the Apache web server on your VM instance using the Azure CLI, if you have the CLI installed. Installing and connecting through Azure CLI is easy. First, install the CLI using the MSI installer for your OS.

Or you can download it using winget. If you are using Windows 11, winget is already installed there and also on some modern versions of Windows 10. Run the following command from Windows Powershell or command prompt to install or update Azure CLI:

$ winget install -e --id Microsoft.AzureCLI

For example, I have the CLI installed on my system and I run the above command to update it with the following output:

The `msstore` source requires that you view the following agreements before using.

Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction

The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. "US").

Do you agree to all the source agreements terms?

[Y] Yes  [N] No: Y

Found an existing package already installed. Trying to upgrade the installed package...

No applicable upgrade found.......................................

Once you have installed the CLI, you can run commands using az.

To connect (login to CLI), using your device, run the following command:

$ az login --use-device-code

The output will include a code which you can submit on the following url:

https://microsoft.com/devicelogin

Output looks like this:

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code HWZABC3PP to authenticate.”

Now, go to the url and authenticate using the code.

Once authentication is complete, you can start running commands. (When you login for the first time, the system will provide the details related to your subscription, login email, and type of subscription.

Now, we will move ahead to install the Apache Web Server on the instance using the Azure CLI. All you need to perform this task is the resource name under which you have created your instance and the name of your instance. You can find out these details using the following command:

$ az vm list

The output will contain the name of the VM and the resource group as well as other details like the attached disk.

Sample Output : –

[

  {

    "additionalCapabilities": null,

    "applicationProfile": null,

    "availabilitySet": null,

    "billingProfile": null,

    "capacityReservation": null,

    "diagnosticsProfile": {

      "bootDiagnostics": {

        "enabled": true,

        "storageUri": null

      }

    },

    "evictionPolicy": null,

    "extendedLocation": null,

    "extensionsTimeBudget": null,

    "hardwareProfile": {

      "vmSize": "Standard_B1s",

      "vmSizeProperties": null

    },

    "host": null,

    "hostGroup": null,

    "id": "/subscriptions/ 25bacd99-1de7-4999-abcd-b31ee9e7e777/resourceGroups/ 

ABCDEF_GROUP/providers/Microsoft.Compute/virtualMachines/Abcdef",

    "identity": null,

    "instanceView": null,

    "licenseType": null,

    "location": "eastus",

    "name": "Abcdef",     < -------(name of your VM instance)

    "networkProfile": {

      "networkApiVersion": null,

      "networkInterfaceConfigurations": null,

      "networkInterfaces": [

        {

          "deleteOption": "Detach",

          "id": "/subscriptions/ 25bacd99-1de7-4999-abcd-b31ee9e7e777/resourceGroups/ Abcdef_group/providers/Microsoft.Network/networkInterfaces/Abcdef982",

          "primary": null,

          "resourceGroup": "Abcdef_group"  < ----- (name of resource group)

        }

      ]

………………………………………………………………………

You can copy the name of the instance and the resource group from the above output and then run the command to install Apache web server on your instance.

$ az vm run-command invoke --resource-group $RESOURCE_GROUP_NAME --name $VM_NAME --command-id RunShellScript --scripts "sudo apt-get update && sudo apt-get install -y apache2"

The above command will install the apache web server on your instance. You can check the status of your instance using the following command:

$ az vm run-command invoke --resource-group $RESOURCE_GROUP_NAME --name $VM_NAME --command-id RunShellScript --scripts "sudo systemctl status apache2"

You can stop the Apache server using Azure CLI with the following command:

$ az vm run-command invoke --resource-group $RESOURCE_GROUP_NAME --name $VM_NAME --command-id RunShellScript --scripts "sudo systemctl stop apache2"

When you stop the Apache web server, using the above command, the output will look like the following :-

{

  "value": [

    {

      "code": "ProvisioningState/succeeded",

      "displayStatus": "Provisioning succeeded",

      "level": "Info",

      "message": "Enable succeeded: \n[stdout]\n\n[stderr]\n",

      "time": null

    }

  ]

}

Once you have stopped the server, you can check the status of the Apache web server:

$ az vm run-command invoke --resource-group resource_group --name resource_name --command-id RunShellScript --scripts "sudo systemctl status apache2"

The output will show that Apache web server has stopped or is inactive:

{

  "value": [

    {

      "code": "ProvisioningState/succeeded",

      "displayStatus": "Provisioning succeeded",

      "level": "Info",

      "message": "Enable succeeded: \n[stdout]\n○ apache2.service - The Apache HTTP Server\n    

Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)\n   

Active: inactive (dead) since Wed 2023-03-29 05:38:11 UTC; 56s ago\n       Docs: https://httpd.apache.org/docs/2.4/\n    Process: 13534 ExecStop=/usr/sbin/apachectl graceful-stop (code=exited, status=0/SUCCESS)\n   Main PID: 9497 (code=exited, status=0/SUCCESS)\n      

CPU: 2.550s\n\nMar 28 18:31:53 Abcdef systemd[1]: apache2.service: Deactivated successfully.\nMar 28 18:31:53 Abcdef systemd[1]: Stopped The Apache HTTP Server.\nMar 28 18:31:53 Abcdef systemd[1]: Starting The Apache HTTP Server...\nMar 28 18:31:53 Abcdef systemd[1]: Started The Apache HTTP Server.\nMar 29 05:38:11 Abcdef systemd[1]: Stopping The Apache HTTP Server...\nMar 29 05:38:11 Abcdef systemd[1]: apache2.service: Deactivated successfully.\nMar 29 05:38:11 Abcdef systemd[1]: Stopped The Apache HTTP Server.\nMar 29 05:38:11 Abcdef systemd[1]: apache2.service: Consumed 2.550s CPU time.\n\n[stderr]\n",

      "time": null

    }

  ]

}

Now, restart the Apache web server from the Azure CLI:

$ az vm run-command invoke --resource-group resource_group --name VM_name --command-id RunShellScript --scripts "sudo systemctl restart apache2"

You will again see the same output as when you stopped the Apache webserver using the CLI. To verify, you can check the status of the Apache webserver as we did in the previous step.

$ az vm run-command invoke --resource-group resource_group --name resource_name --command-id RunShellScript --scripts "sudo systemctl status apache2"

Now, you can SSH to your server to create a new document root directory and to create a vhost file as well as assign ownership to the current user like we did in the first part of this tutorial. The rest of the process to host a static website on Apache server follows the same procedure.

At the end, if you want to delete a VM instance, you can run the following command:

$ az vm delete -g resource_group -n VM_name --yes

This will delete the instance without asking for yes or no.