IBM Cloud Docs
PHP web application on a LAMP Stack in VPC

PHP web application on a LAMP Stack in VPC

This tutorial may incur costs. Use the Cost Estimator to generate a cost estimate based on your projected usage.

This tutorial walks you through the creation of an Ubuntu Linux virtual server with Apache web server, MySQL database and PHP scripting on IBM Cloud Virtual Private Cloud (VPC) Infrastructure. This combination of software - more commonly called a LAMP stack - is often used to deliver websites and web applications. Using IBM Cloud VPC you will quickly deploy your LAMP stack and if desired add logging and monitoring. To experience the LAMP server in action, you will also install and configure the free and open source WordPress content management system.

Objectives

  • Provision a virtual server instance (VSI) in a VPC.
  • Install the latest Apache, MySQL and PHP software.
  • Host a website or blog by installing and configuring WordPress.
  • Configure logging and monitoring to detect outages and monitor for slow performance (optional).
  • Resize the VSI (optional).

Architecture diagram
Figure 1. Architecture diagram of the tutorial

  1. End user accesses the LAMP server running on a VPC using a web browser.
  2. The VSI is configured to use data from an encrypted Block Storage volume (optional).

Before you begin

This tutorial requires:

  • An IBM Cloud billable account,
  • IBM Cloud CLI,
    • IBM Cloud VPC plugin (vpc-infrastructure),
  • terraform to use Infrastructure as Code to provision resources,
  • jq to query JSON files,
  • git to clone source code repository,

You will find instructions to download and install these tools for your operating environment in the Getting started with solution tutorials guide. To avoid the installation of these tools you can use the Cloud Shell.

Create services

In this section, you will provision a VPC, Subnet, Security Group and a Virtual Server Instance (VSI) using the IBM Cloud Shell and the IBM Cloud CLI. VSIs often address peaks in demand after which they can be suspended or powered down so that the cloud environment perfectly fits your infrastructure needs.

If you prefer to use a Terraform template to generate these resources, you can use the template that is available here: https://github.com/IBM-Cloud/vpc-tutorials/tree/master/vpc-lamp and follow the instructions in the README.md. This template can also be used in Schematics.

  1. While logged in to your IBM Cloud account, launch the IBM Cloud Shell.
  2. In the shell, you are automatically logged into one of the IBM Cloud regions, you can switch to a different region if desired by running the following command:
    ibmcloud target -r <region-name> -g <resource-group>
    

Create SSH Key(s)

  1. In VPC an SSH key is used for administrator access to a VSI instead of a password. Create an SSH Key by running the following command and accept the defaults when prompted. For more information on SSH keys, see the docs SSH Keys.

    ssh-keygen -t rsa -b 4096
    

    The above command generates two files inside of the ~/.ssh directory: id_rsa and id_rsa.pub. Your Cloud Shell session is short lived, any files you create inside of IBM Cloud Shell should be saved in a safe location for future re-use. There is a download and upload file option in Cloud Shell on the upper right section of the screen.

    If you have an existing SSH key that you would like to re-use, you can upload it to your Cloud Shell session instead.

  2. Add the SSH key to your account.

    SSHKEY_ID=$(ibmcloud is key-create sshkey-lamp-tutorial @$HOME/.ssh/id_rsa.pub --json | jq -r '.id')
    

Create VPC, Subnet(s) and Security Group(s)

  1. Create a VPC. For more information, see the docs for creating a VPC in the console or CLI.

    VPC_ID=$(ibmcloud is vpc-create vpc-lamp-tutorial --json | jq -r '.id')
    
  2. Create the subnet for your VPC.

    SUBNET_ID=$(ibmcloud is subnet-create subnet-lamp-1 $VPC_ID --zone $(ibmcloud target --output json | jq -r '.region.name')-1 --ipv4-address-count 256 --json | jq -r '.id')
    
  3. Create the security group for your VPC.

    SG_ID=$(ibmcloud is security-group-create sg-lamp-1 $VPC_ID --json | jq -r '.id')
    
  4. Add a rule to limit inbound to SSH port 22.

    ibmcloud is security-group-rule-add $SG_ID inbound tcp --port-min 22 --port-max 22 --json
    

    You can restrict access to the SSH port to a subset of addresses, use --remote <IP address or CIDR> in the above command to limit who can access this server, i.e. ibmcloud is security-group-rule-add $SG_ID inbound tcp --remote YOUR_IP_ADDRESS --port-min 22 --port-max 22 --json

  5. Add a rule to limit inbound to HTTP port 80.

    ibmcloud is security-group-rule-add $SG_ID inbound tcp --port-min 80 --port-max 80 --json
    

    You can also restrict access to the HTTP port to a subset of addresses, use --remote <IP address or CIDR> in the above command to limit who can access this server, i.e. ibmcloud is security-group-rule-add $SG_ID inbound tcp --remote YOUR_IP_ADDRESS --port-min 80 --port-max 80 --json

  6. Add a rule to allow outbound to all, this is required to install software, it can be disabled or removed later on.

    ibmcloud is security-group-rule-add $SG_ID outbound all --json
    

Create Virtual Server Instance

  1. IBM Cloud periodically updates the Ubuntu image with the latest software, obtain the image ID for latest Ubuntu 20.x by running the following command.
    IMAGE_ID=$(ibmcloud is images --json | jq -r '.[] | select (.name=="ibm-ubuntu-22-04-1-minimal-amd64-3") | .id')
    
  2. Create virtual server instance
NIC_ID=$(ibmcloud is instance-create vsi-lamp-1 $VPC_ID $(ibmcloud target --output json | jq -r '.region.name')-1 cx2-2x4 $SUBNET_ID --image-id $IMAGE_ID --key-ids $SSHKEY_ID --security-group-ids $SG_ID --json | jq -r '.primary_network_interface.id')
  1. Reserve a Floating IP
    FLOATING_IP=$(ibmcloud is floating-ip-reserve fip-lamp-1 --nic-id $NIC_ID --json | jq -r '.address')
    
  2. Connect to the server with SSH, note that it may take a minute for the newly created server to be accessible via SSH.
    ssh root@$FLOATING_IP
    
    You will need to know the Floating IP for accessing the virtual server via your browser. Since it was captured in a shell variable earlier, you can run the following command to obtain the Floating IP address echo $FLOATING_IP or by running ibmcloud is floating-ips --json and searching for the name used to create the Floating IP fip-lamp-1 in the result. You can also find the server's floating IP address from the web console: https://{DomainName}/vpc-ext/compute/vs.

Install Apache, MySQL, and PHP

In this section, you'll run commands to update Ubuntu package sources and install Apache, MySQL and PHP with latest version.

When the server is spun up for the first time, it is possible that it is already running system updates and blocks you from running the commands below, you can check the status of system updates by running ps aux | grep -i apt, and either wait for the automated system updates task to complete or kill the task.

  1. Disable interactive mode during updates
    export DEBIAN_FRONTEND=noninteractive
    
  2. Update packages
    apt update
    
  3. Install the Apache
    apt install apache2 -y
    
  4. Install the MySQL
    apt install mysql-server -y
    
  5. Install the PHP
    apt install php libapache2-mod-php php-mysql php-common php-cli -y
    

Verify the installation and configuration

In this section, you'll verify that Apache, MySQL and PHP are up to date and running on the Ubuntu image. You'll also implement the recommended security settings for MySQL.

  1. Verify Ubuntu by opening the Floating IP address in the browser. You should see the Ubuntu welcome page.
    Verify Ubuntu
    Verify Ubuntu
  2. Review the Apache, MySQL and PHP versions installed by using the following commands.
    apache2 -v
    
    mysql -V
    
    php -v
    
  3. Open a mysql prompt.
    mysql
    
  4. Run the following commands substituting your password for yourPassword.
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourPassword';
    
  5. Exit the mysql prompt.
    exit
    
  6. Run the following script to secure the MySQL database. Choose the options that best fit your preferences or simply press the ENTER key to quickly steps through the setup.
    mysql_secure_installation
    
  7. Additionally, you can quickly create a PHP info page with the following command.
    echo "<?php phpinfo(); ?>" > /var/www/html/info.php
    
  8. View the PHP info page you created: open a browser and go to http://{FloatingIPAddress}/info.php. Substitute the floating IP address of your VSI. It will look similar to the following image.

PHP info
PHP info

Install and configure WordPress

Experience your LAMP stack by installing an application. The following steps install the open source WordPress platform, which is often used to create websites and blogs. For more information and settings for production installation, see the WordPress documentation.

  1. Run the following command to install WordPress.
    apt install wordpress -y
    
  2. Configure WordPress to use MySQL and PHP. Run the following command to open a text editor and create the file /etc/wordpress/config-localhost.php.
    sensible-editor /etc/wordpress/config-localhost.php
    
  3. Copy the following lines to the file substituting yourPassword with your MySQL database password and leaving the other values unchanged. Save and exit the file.
    <?php
    define('DB_NAME', 'wordpress');
    define('DB_USER', 'wordpress');
    define('DB_PASSWORD', 'yourPassword');
    define('DB_HOST', 'localhost');
    define('WP_CONTENT_DIR', '/usr/share/wordpress/wp-content');
    ?>
    
  4. Open a mysql prompt and supply your password.
    mysql -u root -p
    
  5. Run the following commands substituting your database password for yourPassword and leaving the other values unchanged.
    CREATE DATABASE wordpress;
    CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'yourPassword';
    GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON wordpress.* TO 'wordpress'@'localhost';
    FLUSH PRIVILEGES;
    
  6. Exit the mysql prompt.
    exit
    
  7. Move the WordPress installation to the web server document root.
    ln -s /usr/share/wordpress /var/www/html/wordpress
    mv /etc/wordpress/config-localhost.php /etc/wordpress/config-default.php
    
  8. Complete the WordPress setup and publish on the platform. Open a browser and go to http://{FloatingIPAddress}/wordpress/wp-admin. Substitute the floating IP address of your instance. It should look similar to the following image.
    WordPress site running
    WordPress site running

Configure domain

To use an existing domain name with your LAMP server, update the A record to point to the VSI's floating IP address.

Server monitoring and log management

To ensure server availability and the best user experience, monitoring should be enabled on every production server. Several options are available to monitor your VSI and capture logs in a central location for analysis.

Server monitoring

You can monitor CPU, volume, memory, and network usage of your VSI instances after you set up an instance of the IBM Cloud Monitoring service. If you would like to configure the monitoring service follow the steps outlined in the Monitoring a Linux host documentation.

Server logging

You can use IBM Log Analysis to manage system and application logs in the IBM Cloud.

IBM Log Analysis offers administrators, DevOps teams, and developers advanced features to filter, search, and tail log data, define alerts, and design custom views to monitor application and system logs

If you would like to configure the logging service follow the steps outlined in the Managing Ubuntu logs with IBM Log Analysis

Configure a Bring-Your-Own-Key (BYOK) Encrypted Data Volume (Optional)

The VSI was created with a provider managed encrypted Boot volume of 100 GB, however if you delete that VSI any data you want to safeguard will need to get moved before you delete the VSI. An alternative is to create a Data volume which can be persisted even if the VSI is deleted and attached to a new VSI. You can also encrypt the volume with your own key. If that is your desired outcome, follow the steps outlined below to create a data volume and attach it to your VSI.

  1. Create a data volume configuration file.

    VOLUME_ID=$(ibmcloud is volume-create volume-lamp-1 10iops-tier $(ibmcloud target --output json | jq -r '.region.name')-1 --capacity 100 --json | jq -r '.id')
    

    In VPC you also have a choice of using a customer managed encryption key. For storing your own encryption keys, you can use one of two available services: (1) A FIPS 140-2 Level 3 service IBM Key Protect. See the Provisioning the IBM Key Protect service topic in the documentation. (2) A FIPS 140-2 Level 4 service IBM Cloud Hyper Protect Crypto Services, see the Getting started with IBM Cloud Hyper Protect Crypto Services topic in the documentation. While creating the volume you can specify the --encryption-key parameter with the CRN to the encryption key you want to use.

  2. Capture the ID of the VSI created earlier by listing all instances and filtering based on the instance name:

    VSI_ID=$(ibmcloud is instances --json | jq -r '.[] | select(.name == "vsi-lamp-1") | .id')
    
  3. Attach the data volume to your existing VSI.

    ibmcloud is instance-volume-attachment-add attachment-data-1 $VSI_ID $VOLUME_ID --auto-delete false --json
    
  4. Connect to the server with SSH.

    ssh root@$FLOATING_IP
    
  5. Configure the newly created data volume on the VSI, run each line below one at a time.

    new_bsv=$(echo $(parted -l 2>&1) | awk 'NR==1{print $2}' | sed 's/:$//')
    parted $new_bsv mklabel gpt
    parted -a opt $new_bsv mkpart primary ext4 0% 100%
    new_part=${new_bsv}1
    mkfs.ext4 -L lamp-data ${new_part}
    mkdir /data
    mount ${new_part} /data
    echo "${new_part} /data ext4 defaults,relatime 0 0" | tee -a /etc/fstab
    mount -a
    

Configure Apache to use the new /data file system

  1. Stop the Apache service
    service apache2 stop
    
  2. Move the Apache directory from /var to /data
    mv /var/www /data/
    
  3. Create a link to the new location
    ln -s /data/www /var/www
    
  4. Start the Apache service
    service apache2 start
    

Configure MySQL to use the new /data file system

  1. Stop the MySQL service
    service mysql stop
    
  2. Move the MySQL directory from /var to /data
    mkdir /data/lib
    mv /var/lib/mysql /data/lib/
    
  3. Create a link to the new location
    ln -s /data/lib/mysql /var/lib/mysql
    
  4. Add an alias of the new location to AppArmor, otherwise AppArmor will block the access.
    echo "alias /var/lib/mysql/ -> /data/lib/mysql/," >> /etc/apparmor.d/tunables/alias
    
  5. Restart the AppArmor service
    systemctl restart apparmor
    
  6. Start the MySQL service
    service mysql start
    
  7. Open a browser and go to http://{FloatingIPAddress}/wordpress. Substitute the floating IP address of your instance. You should be able to access your WordPress page just as you had it before you added the new Data volume.

Resize VSI (Optional)

The VSI was created using one of the smallest profiles available in VPC, i.e. 2 vCPU and 4GiB RAM. It is possible based on your usage requirements to increase - or decrease - the amount of vCPU and RAM available, see Resizing a virtual server instance.

  1. Capture the ID of the VSI created earlier by listing all instances and filtering based on the instance name:

    VSI_ID=$(ibmcloud is instances --json | jq -r '.[] | select(.name == "vsi-lamp-1") | .id')
    
  2. Stop the instance.

    ibmcloud is instance-stop $VSI_ID
    
  3. Resize the instance.

    ibmcloud is instance-update $VSI_ID --profile cx2-4x8
    

    You can get a list of alternative profiles by issuing the following command ibmcloud is instance-profiles, note however the restrictions on resizing based on current/target profiles in the Resizing a virtual server instance topic.

  4. Start the instance.

    ibmcloud is instance-start $VSI_ID
    
  5. You may need to wait a couple of minutes as the VSI is placed on an appropriate host and started. Open a browser and go to http://{FloatingIPAddress}/wordpress. Substitute the floating IP address of your instance. You should be able to access your WordPress page just as you had it before the resizing.

Remove resources

  1. In the VPC console, click on Floating IPs, then on the IP address for your VSIs, then in the action menu select Release. Confirm that you want to release the IP address.
  2. Next, switch to Virtual server instances, Delete your instance.
  3. Once the VSIs are gone, switch to Subnets. Delete your subnet.
  4. After the subnets have been deleted, switch to VPC tab and delete your VPC.
  5. If you created the optional Data Volume and no longer need it, switch to Block storage volumes tab and delete the volume.

When using the console, you may need to refresh your browser to see updated status information after deleting a resource.

Depending on the resource it might not be deleted immediately, but retained (by default for 7 days). You can reclaim the resource by deleting it permanently or restore it within the retention period. See this document on how to use resource reclamation.