<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Josephat Kene</title>
    <description>The latest articles on DEV Community by Josephat Kene (@k3n3).</description>
    <link>https://dev.to/k3n3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1459230%2F2cc79429-d830-42e4-a469-c3268064093f.png</url>
      <title>DEV Community: Josephat Kene</title>
      <link>https://dev.to/k3n3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/k3n3"/>
    <language>en</language>
    <item>
      <title>Bash Script: A Demo of User Account and Group Creation.</title>
      <dc:creator>Josephat Kene</dc:creator>
      <pubDate>Sat, 06 Jul 2024 07:19:54 +0000</pubDate>
      <link>https://dev.to/k3n3/bash-script-a-demo-of-user-account-and-group-creation-3na3</link>
      <guid>https://dev.to/k3n3/bash-script-a-demo-of-user-account-and-group-creation-3na3</guid>
      <description>&lt;p&gt;As a SysOps engineer, part of your job will be to manage user accounts and groups effectively for least privilege on the company's systems/servers to maintain security and access control.&lt;br&gt;
Using Bash Script can greatly enhance your performance in that regard and also management and configuration of the systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisite&lt;/li&gt;
&lt;li&gt;What is Bash&lt;/li&gt;
&lt;li&gt;What is Bash Scripting &lt;/li&gt;
&lt;li&gt;Demo

&lt;ul&gt;
&lt;li&gt;Solution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Linux system. (Ubuntu, CentOS, etc) with bash installed.&lt;/li&gt;
&lt;li&gt;Basic Knowledge of Linux Commands.&lt;/li&gt;
&lt;li&gt;Basic Knowledge of Bash Scripting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is Bash&lt;/strong&gt;&lt;br&gt;
Bash means Bourne again shell. It is the shell that Linux environment uses to communicate with the kernel to make requests and receive feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Bash Scripting?&lt;/strong&gt;&lt;br&gt;
Bash scripting involves writing scripts using the Bash (Bourne Again Shell) command language to automate tasks on Unix-like operating systems. These scripts can range from simple commands executed sequentially to complex programs with control structures and functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;br&gt;
Your company has employed many new developers. As a SysOps engineer, write a bash script called create_users.sh that reads a text file containing the employee’s usernames and group names, where each line is formatted as user; groups.&lt;br&gt;
The script should create users and groups as specified, set up home directories with appropriate permissions and ownership, generate random passwords for the users, and log all actions to /var/log/user_management.log. Additionally, stores the generated passwords securely in /var/secure/user_passwords.txt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br&gt;
First is to create a directory with the command &lt;code&gt;mkdir HNG_Tasks&lt;/code&gt;&lt;br&gt;
Then inside the directory, create a script file with the command &lt;code&gt;touch create_users.sh&lt;/code&gt;&lt;br&gt;
Next is to open the script with a text editor by running the command &lt;code&gt;sudo vi create_users.sh&lt;/code&gt;&lt;br&gt;
Then populate the script with the code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Log file and password file creation
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Ensure script is run as root/sudo
if [ "$EUID" -ne 0 ]; then
    echo "Please run as root or use sudo."
    exit 1
fi

# Create directories and files if they don't exist, and set permissions
mkdir -p /var/log
mkdir -p /var/secure
touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

# Function to create log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# Function to generate a random password
generate_password() {
    echo $(openssl rand -base64 12)
}

# Check if the input file is provided
if [ -z "$1" ]; then
    echo "Usage: sudo bash $0 &amp;lt;name-of-text-file&amp;gt;"
    exit 1
fi

# Read the input file
INPUT_FILE=$1

# Process each line in the input file
while IFS=';' read -r username groups; do
    # Ignore empty lines and lines that start with a hash (#)
    if [[ -z "$username" || "$username" == \#* ]]; then
        continue
    fi

    # Removing all whitespace from username and groups
    username=$(echo "$username" | xargs)
    groups=$(echo "$groups" | xargs)

    # Check if user already exists
    if id "$username" &amp;amp;&amp;gt;/dev/null; then
        log_message "User '$username' already exists."
    else
        # Create user with home directory and bash shell
        useradd -m -s /bin/bash "$username"
        if [ $? -eq 0 ]; then
            log_message "Created user '$username'."
        else
            log_message "Failed to create user '$username'."
            continue
        fi

        # Create personal group with the same name as the user
        usermod -g "$username" "$username"
        if [ $? -eq 0 ]; then
            log_message "Created personal group for user '$username'."
        else
            log_message "Failed to create personal group for user '$username'."
        fi

        # Generate and set a random password for the user
        password=$(generate_password)
        echo "$username:$password" | chpasswd
        if [ $? -eq 0 ]; then
            log_message "Set password for user '$username'."
        else
            log_message "Failed to set password for user '$username'."
        fi

        # Save the password to the secure file
        echo "$username,$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    fi

    # Add user to specified groups if there are any
    if [ -n "$groups" ]; then
        # Split groups by comma and loop through each group
        IFS=',' read -r groups_list &amp;lt;&amp;lt;&amp;lt; "$groups"
        for group in ${groups_list//,/ }; do
            group=$(echo "$group" | xargs) # Trim whitespace
            if getent group "$group" &amp;amp;&amp;gt;/dev/null; then # Checking if group exist
                usermod -aG "$group" "$username"
                if [ $? -eq 0 ]; then
                    log_message "Added user '$username' to group '$group'."
                else
                    log_message "Failed to add user '$username' to group '$group'."
                fi
            else
                groupadd "$group"
                if [ $? -eq 0 ]; then
                    usermod -aG "$group" "$username"
                    log_message "Created and added user '$username' to group '$group'."
                else
                    log_message "Failed to create group '$group' or add user '$username' to group."
                fi
            fi
        done
    fi

done &amp;lt; "$INPUT_FILE"

log_message "User creation and group assignment completed."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Breakdown&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Log file and password file creation
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Ensure script is run as root/sudo
if [ "$EUID" -ne 0 ]; then
    echo "Please run as root or use sudo."
    exit 1
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The block of code above starts with the Shebang line, defines the log file and the password file as variables to their paths, and makes sure the script is ran as a root user or with sudo to avoid any permission issues. (&lt;code&gt;if [ "$EUID" -ne 0 ]; then:&lt;/code&gt; This condition checks if the effective user ID (EUID) is not equal to 0. In Unix-like systems, the root user has an EUID of 0.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /var/log
mkdir -p /var/secure
touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

# Function to create log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above creates directories for the log and password files if those directories don't exist already. The &lt;code&gt;-p&lt;/code&gt; flag makes sure no error is thrown if the directories already exist.&lt;br&gt;
Using the variable declaration in the first block of code, creates a log file and a password file.&lt;br&gt;
It changes the permission of the password file to '600' for the owner to have read and write permission of the file, to restrict access to the password file. &lt;br&gt;
The next line of code creates a function called &lt;code&gt;log_message&lt;/code&gt;. Tis function captures the current date and time and prints it alongside the echo command which is pipped (|) to the &lt;code&gt;tee&lt;/code&gt; command. The &lt;code&gt;tee&lt;/code&gt; command writes the output to both the standard output (so it appears in the terminal) and appends it (with the -a flag) to the log file specified by LOG_FILE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Function to generate a random password
generate_password() {
    echo $(openssl rand -base64 12)
}

# Check if the input file is provided
if [ -z "$1" ]; then
    echo "Usage: sudo bash $0 &amp;lt;name-of-text-file&amp;gt;"
    exit 1
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Code above has a function that generates random passwords with openssl rand -base64 12: The openssl command is used to generate random data. The rand subcommand generates random bytes, and the -base64 option encodes the output in Base64. The 12 specifies the number of random bytes to generate, which after Base64 encoding results in a 16-character string. The 'echo $' captures and prints the random password.&lt;br&gt;
The code also checks if the script is run with an argument. The if condition checks if the first parameter/argument ($1) is empty with the '-z' flag and terminates with an exit status of 1 if no argument is run with the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Read the input file
INPUT_FILE=$1

# Process each line in the input file
while IFS=';' read -r username groups; do
    # Ignore empty lines and lines that start with a hash (#)
    if [[ -z "$username" || "$username" == \#* ]]; then
        continue
    fi

    # Removing all whitespace from username and groups
    username=$(echo "$username" | xargs)
    groups=$(echo "$groups" | xargs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next block of code assigns the variable "INPUT_FILE" to the value of the first argument "$1", and uses a while loop to read the input file line by line and with the &lt;code&gt;IFS=';'&lt;/code&gt; splits each line into fields based on the semicolon, reads each line and splits it into two variables: username and groups. With an if statement checks if the username is empty or if it's a comment and skips to the next condition if they are both true and uses the &lt;code&gt;xargs&lt;/code&gt; command to remove leading and trailing whitespace from username and groups.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # Check if user already exists
    if id "$username" &amp;amp;&amp;gt;/dev/null; then
        log_message "User '$username' already exists."
    else
        # Create user with home directory and bash shell
        useradd -m -s /bin/bash "$username"
        if [ $? -eq 0 ]; then
            log_message "Created user '$username'."
        else
            log_message "Failed to create user '$username'."
            continue
        fi

        # Create personal group with the same name as the user
        usermod -g "$username" "$username"
        if [ $? -eq 0 ]; then
            log_message "Created personal group for user '$username'."
        else
            log_message "Failed to create personal group for user '$username'."
        fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This block of code uses an if condition to check if a user already exists, with the &lt;code&gt;id "$username"&lt;/code&gt; attempts to retrieve user information for username, &lt;code&gt;&amp;amp;&amp;gt;/dev/null&lt;/code&gt; redirects both standard output and standard error to /dev/null, effectively silencing any output from the id command. And if the user doesn't exist, with the &lt;code&gt;useradd -m -s /bin/bash "$username"&lt;/code&gt; it creates the user, a home directory for the user with the &lt;code&gt;-m&lt;/code&gt; flag and  sets the user default shell to bash with the &lt;code&gt;-s /bin/bash&lt;/code&gt;. After creating a user, it creates a personal group for the user with the code &lt;code&gt;usermod -g "$username" "$username"&lt;/code&gt; where &lt;code&gt;usermod&lt;/code&gt; modifies a user account, &lt;code&gt;-g "$username"&lt;/code&gt; sets the primary group of the user to a group with the same name as the user and the &lt;code&gt;$username&lt;/code&gt; specifies the username to be modified. It checks the exit status of the &lt;code&gt;usermod&lt;/code&gt; command, If the group modification is successful, it logs a message indicating the personal group was created and logs the failure message if it fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   # Generate and set a random password for the user
        password=$(generate_password)
        echo "$username:$password" | chpasswd
        if [ $? -eq 0 ]; then
            log_message "Set password for user '$username'."
        else
            log_message "Failed to set password for user '$username'."
        fi

        # Save the password to the secure file
        echo "$username,$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This part of the script handles generating and setting a random password for the newly created user, and then saving the password to a secure file. Let's go through it step-by-step:&lt;br&gt;
The first line calls the function &lt;code&gt;generate_password&lt;/code&gt;, and stores the value of the function in the variable. The &lt;code&gt;echo "$username:$password" | chpasswd&lt;/code&gt; prints the username and password in the format required by &lt;code&gt;chpasswd&lt;/code&gt; and pipes this input to the &lt;code&gt;chpasswd&lt;/code&gt; command, which updates the user's password in the system. It checks the exit status of the password if it set the password for the user or not and appends the username and password to a file specified by the variable PASSWORD_FILE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; if [ -n "$groups" ]; then
        # Split groups by comma and loop through each group
        IFS=',' read -r groups_list &amp;lt;&amp;lt;&amp;lt; "$groups"
        for group in ${groups_list//,/ }; do
            group=$(echo "$group" | xargs) # Trim whitespace
            if getent group "$group" &amp;amp;&amp;gt;/dev/null; then # Checking if group exist
                usermod -aG "$group" "$username"
                if [ $? -eq 0 ]; then
                    log_message "Added user '$username' to group '$group'."
                else
                    log_message "Failed to add user '$username' to group '$group'."
                fi
            else
                groupadd "$group"
                if [ $? -eq 0 ]; then
                    usermod -aG "$group" "$username"
                    log_message "Created and added user '$username' to group '$group'."
                else
                    log_message "Failed to create group '$group' or add user '$username' to group."
                fi
            fi
        done
    fi

done &amp;lt; "$INPUT_FILE"

log_message "User creation and group assignment completed."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section of the script assigns newly created users to specific groups. It checks if the groups exist and creates them if they don't exist. It checks if the variable is empty with the'-n' flag, sets the field separator to a comma (,), and reads the comma-separated groups into group_list. It starts a for loop to go over the group_list, replacing the comma(,) with a space, trims white space from the group variable, it checks if the group exists. If the group exists, it adds the user to the group, but if it does not, it creates the group and then adds the user. It logs the final message indicating the user creation and group assignment. &lt;/p&gt;

&lt;p&gt;The next step is to save the script, exit the text editor, and make the script executable by running the command &lt;code&gt;chmod +x create_users.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then create a users.txt file with the command &lt;code&gt;touch users.txt&lt;/code&gt; for the script to read from. Open with a code editor with the command &lt;code&gt;sudo vi users.txt&lt;/code&gt; and populate with users and groups of your choice. Eg&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz711ftiosqaoepfjx5u.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz711ftiosqaoepfjx5u.PNG" alt="Image of users and groups" width="494" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then run the script with the command &lt;code&gt;sudo ./create_users.sh users.txt&lt;/code&gt;&lt;br&gt;
The output the script gives is in the picture below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo3fm21z1ep8cn4b0hfn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo3fm21z1ep8cn4b0hfn.PNG" alt="Image of script outpu" width="719" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
At the end of this article, you have learned what bash and bash scripting is, why we use bash script, and understand the code used in the demo. This is a task for the &lt;a href="https://hng.tech/internship" rel="noopener noreferrer"&gt;HNG&lt;/a&gt; internship stage one program. You can check out available roles at HNG with this &lt;a href="https://hng.tech/hire" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>automation</category>
    </item>
    <item>
      <title>Ansible with Task Automation Demo</title>
      <dc:creator>Josephat Kene</dc:creator>
      <pubDate>Mon, 20 May 2024 18:28:11 +0000</pubDate>
      <link>https://dev.to/k3n3/ansible-with-task-automation-demo-3k8m</link>
      <guid>https://dev.to/k3n3/ansible-with-task-automation-demo-3k8m</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Table of Content&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Introduction

&lt;ul&gt;
&lt;li&gt;What is Ansible&lt;/li&gt;
&lt;li&gt;How Ansible Works&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Demo

&lt;ul&gt;
&lt;li&gt;Solution&lt;/li&gt;
&lt;li&gt;Inventory&lt;/li&gt;
&lt;li&gt;Connecting to Slave Nodes&lt;/li&gt;
&lt;li&gt;Playbook &lt;/li&gt;
&lt;li&gt;Playbook Breakdown

&lt;ul&gt;
&lt;li&gt;Updating Packages&lt;/li&gt;
&lt;li&gt;Installing Apache&lt;/li&gt;
&lt;li&gt;Starting Apache and Opening Port 80 in the CentOS System&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Running the Playbook&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You got that lucky break and bagged an internship in cloud engineering. One of your duties is managing over 10 servers on the cloud, updating and upgrading the packages, and installing new applications on new servers.&lt;/p&gt;

&lt;p&gt;You'll be wondering how to SSH into all the servers and run all those commands one after the other. That sounds like a lot. However, a way to automate that and make your life easy is by using Ansible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Ansible?&lt;/strong&gt;&lt;br&gt;
Ansible is an open-source IT automation engine that automates provisioning, configuration management, application deployment, orchestration, and many other IT processes. It is free to use, and the project benefits from the experience and intelligence of its thousands of contributors.&lt;/p&gt;

&lt;p&gt;So imagine you have many machines for different purposes and tasks and you have to manage all of them, Ansible is a super robot that helps you connect to those machines and you tell Ansible what you want it to do in all of those machines and it does it for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Ansible works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ansible needs a master node or controller that will be used to connect to all other nodes, machines, or servers to manage them. &lt;br&gt;
It uses an Inventory file that stores the IP of all the machines it should connect to and perform tasks on.&lt;br&gt;
It also needs a playbook which is a YAML file that tells ansible what it wants it to do and the tasks to perform on all other nodes or machines it is connected to.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Demo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To explain how Ansible works better, You will use a demonstration. In this demo, you are going to provision 3 Linux servers. Two will be Ubuntu and one will be CentOS. The Master node (controller) will be any of the Ubuntu servers and the slave node will be One Ubuntu server and the CentOS server. &lt;br&gt;
You are going to run a playbook that installs Apache on the slave nodes. In the CentOS server, you will start the Apache and enable port 80 in the firewall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, you have to provision 3 virtual machines using Vagrant. An alternative is your AWS EC2.&lt;/p&gt;

&lt;p&gt;In the master node, first, install ansible on your master node with the command:&lt;br&gt;
&lt;code&gt;sudo apt install ansible&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then create a directory with any name of your choice. This directory will house all the files and playbooks related to our Ansible project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5jt5ixel9z3bwxentc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5jt5ixel9z3bwxentc.PNG" alt="making directory" width="555" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Inventory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you have to create your Inventory file. An Inventory in Ansible contains the IP address or domain name of all the servers or slave nodes we want to manage with Ansible.&lt;br&gt;
It can also contain some other data like groupings, group variables, and host variables (which we will address later for better understanding). The inventory file should be inside the directory we created.&lt;br&gt;
To create an inventory file, run the command:&lt;br&gt;
&lt;code&gt;sudo vim inventory&lt;/code&gt;&lt;br&gt;
The picture below is the inventory file with the IP addresses of both our slave nodes. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1gnopxfgc8lddvwrf7m.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1gnopxfgc8lddvwrf7m.PNG" alt="Inventory file" width="300" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that an inventory file can contain data like groupings? That means that we can group our slave nodes into whatever groups we want to put them in. The groups can be web servers, databases, or by their Linux distribution. &lt;br&gt;
The picture below shows how to group the IP addresses of our slave nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzc36bcgy4atflcjan3tk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzc36bcgy4atflcjan3tk.PNG" alt="Inventory groupings" width="321" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Connecting to Slave nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For Ansible to be able to run tasks on your slave nodes with the playbook, it needs some form of connection to those slave nodes in your inventory. &lt;br&gt;
The way to get that connection is to generate an SSH key on your master node or controller, copy the public keys, and paste them into the authorized keys of your slave nodes. &lt;br&gt;
The command to generate the SSH key is:&lt;br&gt;
&lt;code&gt;ssh-keygen -t ed25519 -C "default"&lt;/code&gt;&lt;br&gt;
The "ssh-keygen" is the command line utility for generating SSH keys, the "-t ed25519" specifies the type of key to create which is ed25519, the "-C "default" add a comment 'default' to key for information purposes. &lt;br&gt;
The picture below is the result after creating the ssh key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb3z05e423fvznffkto2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb3z05e423fvznffkto2.PNG" alt="Ansible default key" width="800" height="428"&gt;&lt;/a&gt;&lt;br&gt;
Do the same thing for the second one but this time the comment will be ansible and you will change the path to where the keys will to /home/vagrant/.ssh/ansible.pub&lt;br&gt;
This is how your ansible key creation will look&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyjd46uzp7bngyrtym01.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyjd46uzp7bngyrtym01.PNG" alt="ssh key creation for ansible" width="800" height="314"&gt;&lt;/a&gt;&lt;br&gt;
For this article, please don't create a password when you create the SSH keys. To get the public key, navigate into /home/vagrant/.ssh/ the copy the keys of ansible.pub and id_ed25519.pub. Then paste it into the authorized key file in your slave nodes separately.&lt;br&gt;
The default key is for you to be able to connect or SSH into your slave nodes from the controller and the Ansible key is the one Ansible will use to connect to the slave nodes.&lt;br&gt;
To be sure your master node can connect to your slave nodes in your inventory, make sure your slave nodes are up and running then run the command in the directory that has your inventory:&lt;br&gt;
&lt;code&gt;ansible all --key-file ~/.ssh/ansible -i inventory -m ping&lt;/code&gt;&lt;br&gt;
"ansible" is the command line tool. You are calling ansible.&lt;br&gt;
"all" is specifying that the command should run against all the IP addresses or hosts in the inventory file.&lt;br&gt;
"--key-file ~/.ssh/ansible" is telling ansible the particular SSH key to use for authentication. In the case the key located in (~/.ssh/ansible)&lt;br&gt;
"-i inventory" is you specifying the inventory file that contains all the IP addresses of your slave nodes&lt;br&gt;
"-m ping" specifies the ansible module to use. In this case 'ping' which just testing to check if the IPs in the Inventory are reachable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feugp5rczbcczfe4bgdf0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feugp5rczbcczfe4bgdf0.PNG" alt="Ansible ping result" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Playbook&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A playbook in Ansible is like a blueprint of tasks you want to automate. These tasks are executed with little manual effort across all the hosts in your inventory. The playbook tells Ansible what to do and which device to do it in. &lt;br&gt;
One or more tasks are combined to make a play and these tasks can be mapped to a specific host, a group of hosts, or all the hosts. A playbook can also include one or more plays. The tasks/plays are executed the way they are written.&lt;br&gt;
Tasks are executed by Ansible modules. These modules contain some data that determines when and where a task is executed and the user that executes the tasks.&lt;/p&gt;

&lt;p&gt;Now to open a playbook file, still inside the directory you created that your inventory is in, run the command:&lt;br&gt;
&lt;code&gt;sudo vim playbook.yml&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;The playbook for our demo is the code block below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
- hosts: all
  become: true
  pre_tasks:
    - name: install updates (centOS)
      tags: always
      yum:
        update_only: yes
        update_cache: yes
      when: ansible_os_family == 'RedHat'

    - name: install updates (Ubuntu)
      tags: always
      apt:
        upgrade: dist
        update_cache: yes
      when: ansible_os_family == 'Ubuntu'

#Installing apache for ubuntu and centos
- hosts: all
  become: true
  tasks:
    - name: install apache for ubuntu server
      tags: apache,apache2,ubuntu
      apt:
        name: apache2
        state: latest
      when: ansible_distribution == "Ubuntu"

    - name: install Apache for CentOS server
      tags: apache,centos,httpd
      yum:
        name: httpd
        state: latest
      when: ansible_distribution == "CentOS"

    #Start and enable apache for CentOS
    - name: start httpd (CentOS)
      tags: apache,centos,httpd
      service:
        name: httpd
        state: started
        enabled: yes
      when: ansible_distribution == "CentOS"

    #Open port 80/tcp for CentOS
    - name: Open port 80/tcp in firewalld
      firewalld:
        service: http
        permanent: yes
        state: enabled
      when: ansible_distribution == "CentOS
      notify: Reload firewalld

    #Reload Firewall for CentOS
  handlers:
    - name: Reload firewalld
      service:
        name: firewalld
        state: reloaded
      when: ansible_distribution == "CentOS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N.B You should note that when writing your ansible playbook, your indentation is very important. You miss a single line of indentation in a task or a play and that particular task or play won't run. Sometimes the entire playbook might not work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Component Breakdown&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updating Package
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
- hosts: all
  become: true
  pre_tasks:
    - name: install updates (centOS)
      tags: always
      yum:
        update_only: yes
        update_cache: yes
      when: ansible_os_family == 'RedHat'

    - name: install updates (Ubuntu)
      tags: always
      apt:
        upgrade: dist
        update_cache: yes
      when: ansible_os_family == 'Ubuntu'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;---&lt;/code&gt; represents the beginning of a YAML file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;- hosts: all&lt;/code&gt; specifies that the playbook should run on all hosts. You can also pick any specific host group.
&lt;code&gt;become: true&lt;/code&gt; This ensures that all tasks are executed with sudo privileges. Although it is optional. Your plays can run without it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pre_tasks:&lt;/code&gt; You can also use "tasks" here however, using pre_tasks means the tasks here are executed before any other tasks. 
The first part of the task here updates the packages for the CentOS servers and the second task does the same for the Ubuntu server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; This is the description of the tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt; when running an ansible playbook, you can specify a tag you want the playbook to run on, setting this tag to always makes sure these tasks run regardless of the tags specified when running the playbook. It is also optional.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yum&lt;/code&gt; and &lt;code&gt;apt&lt;/code&gt; These are modules used to manage packages in the RedHat and Debian-based systems.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;update_only&lt;/code&gt; This ensures only updates are installed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update_cache&lt;/code&gt; This refreshes the package database cache 
-&lt;code&gt;upgrade&lt;/code&gt; Specifies the type of upgrade to perform. 'dist' in this case performs a full distribution upgrade.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;when&lt;/code&gt; This is a conditional statement in Ansible that states a task should run on Ubuntu or RedHat systems. &lt;br&gt;&lt;br&gt;
So the above Play is you going into that system to run &lt;code&gt;sudo apt update&lt;/code&gt; or &lt;code&gt;sudo yum upgrade&lt;/code&gt; as it is best practice to update your packages before any installation but this time you are doing it remotely with Ansible!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installing Apache&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; #Installing apache for ubuntu and centos
- hosts: all
  become: true
  tasks:
    - name: install apache for ubuntu server
      tags: apache,apache2,ubuntu
      apt:
        name: apache2
        state: latest
      when: ansible_distribution == "Ubuntu"

    - name: install apache for CentOS server
      tags: apache,centos,httpd
      yum:
        name: httpd
        state: latest
      when: ansible_distribution == "CentOS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code block above is the part of the playbook that installs Apache for both Ubuntu and CentOS systems. &lt;br&gt;
Now if you had used 'tasks' instead of 'pre_tasks' you would not have to repeat the &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;become&lt;/code&gt;, and &lt;code&gt;tasks&lt;/code&gt; parts. It will all be under the first one. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; describes the name of the task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt; keywords to use in running a specific task by adding &lt;code&gt;--tags "apache,ubuntu,httpd,apache2"&lt;/code&gt; to the ansible command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apt&lt;/code&gt; and &lt;code&gt;yum&lt;/code&gt; These are modules used to manage Ubuntu and RedHat-based systems

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; This is the name of the package to install. "apache2" 
for Ubuntu and "httpd" for centOS&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;state&lt;/code&gt; This ensures the package installed is up to date by 
setting it to "latest"&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;when&lt;/code&gt; This is a conditional statement that makes sure the tasks run on Ubuntu or CentOS systems. &lt;br&gt;&lt;br&gt;
This play is you going into the slave nodes to run the command &lt;code&gt;sudo apt install apache2&lt;/code&gt; or &lt;code&gt;sudo yum install httpd&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Starting Apache and Opening Port 80 in the CentOS System&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Start and enable apache for CentOS
    - name: start httpd (CentOS)
      tags: apache,centos,httpd
      service:
        name: httpd
        state: started
        enabled: yes
      when: ansible_distribution == "CentOS"

    #Open port 80/tcp for CentOS
    - name: Open port 80/tcp in firewalld
      firewalld:
        service: http
        permanent: yes
        state: enabled
      when: ansible_distribution == "CentOS
      notify: Reload firewalld

    #Reload Firewall for CentOS
  handlers:
    - name: Reload firewalld
      service:
        name: firewalld
        state: reloaded
      when: ansible_distribution == "CentOS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tasks configure Apache or httpd as it is called for the CentOS system.&lt;br&gt;
Here, you are using a few different modules and their arguments. The new modules used are the &lt;code&gt;service&lt;/code&gt; module which manages the state of a service and &lt;code&gt;firewalld&lt;/code&gt; module which manages firewall settings.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first task using the service module, starts the service (httpd) and enables it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second task using the firewalld module, enables the http service (which corresponds to port 80), makes the change permanent, and enables it.&lt;br&gt;
It uses notify to alert the handler which is used in the third task that a change has been made. The handler will only run if the change was made.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The third task introduces a new concept called "handlers". It is used to perform actions when notified of a task. It is mostly used to perform actions like restarting services or reloading configurations only when necessary. &lt;br&gt;
In this case, from the arguments of the service module, it is used to reload the firewalld service.&lt;br&gt;
You can also find out more about the ansible module with the ansible &lt;a href="https://docs.ansible.com/ansible/2.9/modules/list_of_all_modules.html"&gt;documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;- Running the Playbook&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that you understand what the entire playbook does, it's time to check if it works. The command to run an ansible playbook is:&lt;br&gt;
&lt;code&gt;ansible-playbook -i inventory playbook.yml&lt;/code&gt;&lt;br&gt;
The "inventory" should be the name of your inventory file and the playbook.yml should be the name of your playbook file.&lt;br&gt;
This command should be run inside the directory that has your playbook and inventory file&lt;br&gt;
If your playbook runs successfully you should get this output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p7q284mh8apswpo8pct.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p7q284mh8apswpo8pct.PNG" alt="Playbook output" width="800" height="423"&gt;&lt;/a&gt;&lt;br&gt;
If you check the play recap at the bottom, you will see that no task failed for each of the slave nodes.&lt;/p&gt;

&lt;p&gt;Now if you check the IP address of your slave nodes on your browser to be sure Apache was installed, you should get the Apache default page as shown in the pictures below&lt;/p&gt;

&lt;p&gt;Apache default page for Ubuntu&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhygn5z5y04kc56h9uube.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhygn5z5y04kc56h9uube.PNG" alt="Apache page for Ubuntu" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apache default page for CentOS&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fueutpfhined4on019j94.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fueutpfhined4on019j94.PNG" alt="Apache page for centos" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;- Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this article you have learned what Ansible is, how it works and a few concepts used like the playbook and inventory using a demo. You should also remember that indentations are important when writing your playbooks.&lt;/p&gt;

&lt;p&gt;The playbook written in this article is not the best way to write a playbook as there are a few repetitions. We can consolidate it by using variables and Roles. Those will be discussed in the second part of this article! &lt;/p&gt;

</description>
      <category>ansible</category>
      <category>automation</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploying Laravel on Lamp Stack with Linux(Ubuntu)</title>
      <dc:creator>Josephat Kene</dc:creator>
      <pubDate>Thu, 09 May 2024 17:33:17 +0000</pubDate>
      <link>https://dev.to/k3n3/deploying-laravel-on-lamp-stack-with-linuxubuntu-89a</link>
      <guid>https://dev.to/k3n3/deploying-laravel-on-lamp-stack-with-linuxubuntu-89a</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Table of Content&lt;/strong&gt;
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Introduction

&lt;ul&gt;
&lt;li&gt;Lamp Stack&lt;/li&gt;
&lt;li&gt;Laravel&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prerequisites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Steps of Deploying Laravel with Lamp&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing Lamp&lt;/li&gt;
&lt;li&gt;Installing PHP Dependencies&lt;/li&gt;
&lt;li&gt;Downloading Composer&lt;/li&gt;
&lt;li&gt;Cloning the Laravel Git Repository and installing 
Dependencies&lt;/li&gt;
&lt;li&gt;Installing Composer Dependencies and Setting up Environment 
Variables&lt;/li&gt;
&lt;li&gt;Setting Up MySQL Database&lt;/li&gt;
&lt;li&gt;Reconfigure Apache&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclusion&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;There is a cool website that is being built and you are tasked with deploying the website on a Linux server and to make the website work, you have to install Lamp stack.&lt;/p&gt;

&lt;p&gt;In this article i will guide you through the steps of manually setting up laravel with lamp stack. By the end of this article, you will know the steps of doing that and what the commands actually mean or do and why you had to run some of the commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lamp Stack&lt;/strong&gt;&lt;br&gt;
Lamp is a web development platform that consist of four main components. They are: Linux, Apache, MySQL, PHP. You can say LAMP is an acronym for those four components.&lt;/p&gt;

&lt;p&gt;Linux: This is the Operating System which the other 3 components of the stack runs. It is chosen because of its security, stability and it is open source. It’s a good foundation to host web applications. &lt;/p&gt;

&lt;p&gt;Apache: This is the web server software that handles requests from your web browsers and responds to it. Basically, when you open a web browser and search for a website, your web browser makes a request for that website and you get your desired web page (that is the response). That whole process is handled by apache.&lt;/p&gt;

&lt;p&gt;MySQL: This is a database management system that is used for storing, sorting and managing the web application’s data like usernames, passwords etc. These are all sorted and managed by MySQL.&lt;/p&gt;

&lt;p&gt;PHP: This is the server-side scripting language for developing dynamic web pages. Can be called backend side. It helps the server that is hosting the web application understand what and it should do when someone visits the web application page. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel&lt;/strong&gt;&lt;br&gt;
This is an open source PHP framework used for web development, providing rich sets of features for efficient and structured way of building web applications. &lt;br&gt;
It is basically like a set of instruction template or booklet that web developers get to follow or use in organizing the ready to use tools for building web applications so they don’t get to start from scratch every time.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A Linux(Ubuntu) Operating System or a virtual machine running the Ubuntu OS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A user on your Linux OS with sudo privileges or a root user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terminal window or command line (i prefer git bash)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Knowledge of some linux command&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Steps of Deploying Laravel with Lamp Stack&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;- Installing Lamp&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first thing to is to update your Linux server. It is best practice to always update so you can get recent packages on your server. You can also upgrade the packages if you want. It is like updating your windows OS.&lt;/p&gt;

&lt;p&gt;So run  &lt;code&gt;sudo apt update&lt;/code&gt; for updating your Linux packages. And &lt;code&gt;sudo apt upgrade&lt;/code&gt; to upgrade the packages&lt;/p&gt;

&lt;p&gt;The next step is to install the Linux, Apache, MySQL and PHP.&lt;/p&gt;

&lt;p&gt;Now the command to install Apache is:&lt;br&gt;
&lt;code&gt;sudo apt install apache2 -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check if apache is active by using the command: &lt;br&gt;
&lt;code&gt;sudo systemctl status apache2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or you could enter the IP of your virtual machine on your browser, and you should get the picture below which is the apache default page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdwgm7sujo0j3ku7skbq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdwgm7sujo0j3ku7skbq.PNG" alt="Image of apache default page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To Install MySQL, the command to run is: &lt;br&gt;
&lt;code&gt;sudo apt install mysql-server -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now for PHP, you need to install the PHP version 8.2 or a higher version because that is the version Laravel works with, and by default the sudo apt install module installs a version of PHP that is lower than PHP8.2.&lt;br&gt;
So to get the PHP version 8.2 command you need to first run the command: &lt;br&gt;
&lt;code&gt;sudo add-apt-repository ppa:ondrej/php&lt;/code&gt;&lt;br&gt;
This command adds a Personal Package Archive (PPA) maintained by Ondřej Surý, which contains PHP packages, to the system's list of repositories. This enables the system to install PHP8.2 packages from this PPA using the apt package manager. &lt;/p&gt;

&lt;p&gt;After this, you can now install PHP8.2 with the command &lt;br&gt;
&lt;code&gt;sudo apt install php8.2 -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Installing PHP Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now Laravel needs some dependencies to run on your PHP and it doesn’t come when you install the PHP8.2 so you have to install those dependencies.&lt;/p&gt;

&lt;p&gt;To check the default dependencies you have, run the command:&lt;br&gt;
&lt;code&gt;php -m&lt;/code&gt;&lt;br&gt;
The output below are the dependencies that are installed with php8.2&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d9lddjvquae40hicdpq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d9lddjvquae40hicdpq.PNG" alt="image of PHP8.2 dependencies already installed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install the other dependencies needed, run the command:&lt;br&gt;
&lt;code&gt;sudo apt install php8.2-curl php8.2-dom php8.2-mbstring php8.2-xml php8.2-mysql zip unzip -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Downloading Composer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why Download Composer?&lt;br&gt;
Remember those PHP dependencies you installed? Composer is the tool used in managing them, ensuring that the correct version of these packages are installed and compatible with each other. It generates autoloader for your project. This autoloader allows Laravel load classes and files automatically.&lt;/p&gt;

&lt;p&gt;First step to installing composer is to change directory into an executable path. You do that by running the command &lt;br&gt;
&lt;code&gt;cd /usr/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you run the command below which uses the curl command that transfers data from and to a server to download the Composer installer script from the official Composer website (&lt;a href="https://getcomposer.org/installer" rel="noopener noreferrer"&gt;https://getcomposer.org/installer&lt;/a&gt;), uses the grep symbol (|) to pipe it to sudo php and then executes it. The -sS means its should run in silent mode and show error if it occurs.&lt;br&gt;
&lt;code&gt;curl -sS https://getcomposer.org/installer | sudo php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result of the is you having a composer.phar file. For better readability and usability you should renamed it to just composer with the command below:&lt;br&gt;
&lt;code&gt;sudo mv composer.phar composer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Cloning the Laravel Git Repository and installing Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First you want to run these next commands in your home directory so you change back to your home directory with the command: &lt;br&gt;
&lt;code&gt;cd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Considering you will be hosting the Laravel on Apache, you navigate to our default apache directory hosting the default apache page with the command: &lt;br&gt;
&lt;code&gt;cd /var/www/html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This path is where you will clone your Laravel repository, so it’s best you remove the content html directory and change the owner of the directory to your current user (you could just clone the repository on that directory without removing the contents of the html though) with the next 2 commands: &lt;br&gt;
&lt;code&gt;sudo rm -r *&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo chown -R $USER:$USER /var/www/html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now to actually clone the git repository, you need to be sure you are in the /var/www/html directory. You can run the command &lt;code&gt;cd /var/www/html&lt;/code&gt; to be sure.&lt;/p&gt;

&lt;p&gt;Then clone with the command:&lt;br&gt;
&lt;code&gt;git clone https://github.com/laravel/laravel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It is important you do not run the command above with sudo because it changes the ownership of the cloned repository to root. Which should not happen considering we changed the owner to the current user. You only use sudo if you are running the command as a root user. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Installing Composer Dependencies and Setting up Environment Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next set of command should be executed in the Laravel directory so run the command &lt;br&gt;
&lt;code&gt;cd laravel/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, install composer managed dependencies with the command&lt;br&gt;
&lt;code&gt;sudo composer install --optimize-autoloader --no-dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command above tells composer to install the dependencies listed in the composer.json file. It reads the json file, resolve dependencies and the required packages into the vendor directory. &lt;br&gt;
The &lt;code&gt;–optimize-autoloader&lt;/code&gt; tells composer to generate an optimized autoloader for better performance and &lt;code&gt;--no-dev&lt;/code&gt; tells composer to exclude development dependencies to reduce the size of installed packages and speed up installation.&lt;br&gt;
Now you have installed the environment variables, they are saved in the env.example file and this application has been configured to read variables from the .env file. So the next step is to copy the .env.example file to the .env file (you can also rename instead by using mv instead of cp) with the command &lt;br&gt;
&lt;code&gt;sudo cp .env.example .env&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above should be executed in the Laravel directory&lt;br&gt;
Now if you open the .env file with a code editor, you’ll see that the APP_KEY part of the configuration is empty. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsr1w745zics7zv3jc65e.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsr1w745zics7zv3jc65e.PNG" alt="Image of APP_KEY"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To populate it, execute the command:&lt;br&gt;
&lt;code&gt;sudo php artisan key:generate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The application key is important because is used for encrypting various types of data, like cookies and passwords. Without a proper key, your application's security could be compromised.&lt;br&gt;
The image below shows the generated app key after running the command to generate it&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eix47jkq6hde2hw9jp6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eix47jkq6hde2hw9jp6.PNG" alt="Image of app key genrated"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In many web server configurations, the web server process for apache runs as a specific user for security reasons. To get that user for apache, execute the command below&lt;br&gt;
&lt;code&gt;ps aux | grep “apache” | awk ‘{print $1}’ | grep -v root | head -n 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result of command above is used to change the ownership of laravel’s storage directory and the bootstrap/cache directory so that apache is able to read into it and avoid permission issues. The commands to do these are the next commands to execute. Run them one after the other&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo chown -R www-data storage&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo chown -R www-data bootstrap/cache&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Setting Up MySQL Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Setting up a database for deploying Laravel is important because Laravel utilizes a database to store and retrieve application data. &lt;br&gt;
Some of the reasons why you need to set up a database are for storing and retrieving data, data security and scalability. &lt;br&gt;
So for Laravel to work properly you have to create a new database. And doing that means you have to create a database name, user and password. &lt;br&gt;
To do that you should run the following commands one after the other:&lt;br&gt;
&lt;code&gt;sudo mysql -uroot&lt;br&gt;
CREATE DATABASE database_name; &lt;br&gt;
CREATE USER 'Username'@'localhost' IDENTIFIED BY 'Password';&lt;br&gt;
GRANT ALL PRIVILEGES ON *.* TO 'Username'@'localhost';&lt;br&gt;
SHOW DATABASES;&lt;br&gt;
exit&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;N.B&lt;/strong&gt;: Replace “database_name”, “Username” and “Password” with your preferred names for these values&lt;br&gt;
The output will look like the picture below if you did it correctly:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fod83ciu0nsg2942e542q.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fod83ciu0nsg2942e542q.PNG" alt="Database setup success"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that .env file, you have to populate it with the values of the database details you created. Change the value of DB_CONNECTION to “mysql”, The values of the DB_DATABASE, DB_USERNAME, DB_PASSWORD to the names of the database, username and the password of the database you created. Run the command;&lt;br&gt;
&lt;code&gt;sudo vim .env&lt;/code&gt;&lt;br&gt;
The image below is the part of the .env file you should populate&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4en0u9avf7g3ze0k9ob3.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4en0u9avf7g3ze0k9ob3.PNG" alt="Image of the env file before"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After making the changes, putting the values of your database name, username and password, the .env file should look like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ersi480n222lox7o5us.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ersi480n222lox7o5us.PNG" alt="Image of .env file after"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To confirm that the .env file configuration and the Laravel application are in sync, run the command &lt;br&gt;
&lt;code&gt;php artisan migrate&lt;/code&gt;&lt;br&gt;
The output should be the picture below&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjuw8oyoynsef5ft3te5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjuw8oyoynsef5ft3te5.PNG" alt="Image of artisan migrate success"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Reconfigure Apache&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;To access the Laravel page directly from the IP of your virtual machine, or the local host or assigned domain name, you have to reconfigure apache. &lt;/p&gt;

&lt;p&gt;The default apache configuration is located in the sites-available file. So change directory to the path of the sites-available file with the command:&lt;br&gt;
&lt;code&gt;cd /etc/apache2/sites-available/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you create a new configuration file with the command: &lt;br&gt;
&lt;code&gt;sudo vim Laravel.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Populate it with the new configuration file with the details below:&lt;br&gt;
&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br&gt;
    ServerName webmaster@localhost&lt;br&gt;
    DocumentRoot /var/www/html/laravel/public&lt;br&gt;
       &amp;lt;Directory /var/www/html/laravel&amp;gt;&lt;br&gt;
             Options Indexes FollowSymLinks&lt;br&gt;
         AllowOverride All&lt;br&gt;
             Require all granted&lt;br&gt;
    &amp;lt;/Directory&amp;gt;&lt;br&gt;
    ErrorLog ${APACHE_LOG_DIR}/demo-error.log&lt;br&gt;
    CustomLog ${APACHE_LOG_DIR}/demo-access.log combined&lt;br&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next thing to do is to disable the default configuration of apache with the command:&lt;br&gt;
&lt;code&gt;sudo a2dissite 000-default.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now enable the Laravel configuration file you created with the command:&lt;br&gt;
&lt;code&gt;sudo a2ensite Laravel.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For your new configuration to kick in, restart apache with the command:&lt;br&gt;
&lt;code&gt;sudo systemctl reload apache2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N.B&lt;/strong&gt;: If you are getting any errors when you try to reload apache, check the laravel.conf file you created and make sure the configuration lines are well indented. &lt;br&gt;
The configuration should look like the picture below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvcda7sboqqk0mfgitbr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvcda7sboqqk0mfgitbr.PNG" alt="Laravel configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when you enter the IP of your virtual machine in your browser, your output would look like the picture below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfqekmkknlzxkpzz9l95.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfqekmkknlzxkpzz9l95.PNG" alt="Image of laravl page"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Now you can manually deploy Laravel with lamp stack on an ubuntu server or an ubuntu virtual machine. Also knowing why you had to use some of the commands that were complicated. &lt;br&gt;
This process can be automated with bash script also which is on this &lt;a href="https://github.com/Jovals/Altschool-Second-Semester-Cloud-Exam.git" rel="noopener noreferrer"&gt;Git Repository&lt;/a&gt;. I automated this process with bash script and ran it on a slave node using ansible. &lt;/p&gt;

</description>
      <category>laravel</category>
      <category>linux</category>
      <category>lamp</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Enable a Virtual Machine on Your Windows Laptop With Vagrant and Git Bash</title>
      <dc:creator>Josephat Kene</dc:creator>
      <pubDate>Tue, 30 Apr 2024 17:33:41 +0000</pubDate>
      <link>https://dev.to/k3n3/how-to-enable-a-virtual-machine-on-your-windows-laptop-with-vagrant-and-git-bash-54gn</link>
      <guid>https://dev.to/k3n3/how-to-enable-a-virtual-machine-on-your-windows-laptop-with-vagrant-and-git-bash-54gn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
For someone wanting to learn and use linux and you have a windows machine, You most likely won’t want to remove the windows OS on your laptop and lose all your files. &lt;br&gt;
Maybe you want to learn Linux for a course you are running or something else, the good news is you can enable a virtual machine on your windows machine. &lt;/p&gt;

&lt;p&gt;What is a virtual machine and what does it do? A virtual machine is a software that emulates your physical computer. You can see it as a box(software) that allows you have another computer inside your physical computer (host machine) without messing up the files on it or having to delete anything. &lt;br&gt;
You can run multiple virtual machines with multiple OS on your host machine. Each separate machine behaves like a computer on its own with its own CPU, OS, memory and network interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Vagrant?&lt;/strong&gt; &lt;br&gt;
This is a software or tool that helps us simplify the process of creating and configuring a virtual machine. you basically tell it, “this is the kind of virtual machine we want", and it creates it for you automatically. It can manage all the virtual machines you create. &lt;/p&gt;

&lt;p&gt;In this article I will walk you through setting up a virtual machine in your windows computer where you can run a Linux OS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tools you need to download and install on your computer for this article are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable Virtualization on your computer via the BIOS&lt;/li&gt;
&lt;li&gt;Command line or Terminal. I prefer &lt;a href="https://git-scm.com/downloads"&gt;Git Bash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.vagrantup.com"&gt;Vagrant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.virtualbox.org/wiki/Downloads"&gt;Oracle VirtualBox 7.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170"&gt;Microsoft visual C++ 2019&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And of course you need an internet connection for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to Run a Linux(Ubuntu) Virtual Machine on Your Computer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now that you have all your tools installed, the following steps are used to provision a Linux Ubuntu machine on your laptop and it will run virtually.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new folder on your desktop or anywhere in your computer (your computer will be called local machine from here on out). Now you can do this via your normal windows desktop by right clicking on your desktop screen and create a new folder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After creating the folder, right click on the folder and click “open git bash here” and you will get the output below&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ks4dtq1mxzl9o3g8822.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ks4dtq1mxzl9o3g8822.PNG" alt="output when you open a folder with git bash" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the git bash terminal, type the command &lt;code&gt;vagrant init ubuntu/focal64&lt;/code&gt; and press enter. NB: the commands should all be in lowercase. This places a vagrant file which contains the configuration of the Linux(ubuntu) OS inside the folder your created. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm4p8fkka9vsu0b5ke8n.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm4p8fkka9vsu0b5ke8n.PNG" alt="output of vagrant init ubuntu/focal64" width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The next step is to type &lt;code&gt;vagrant up&lt;/code&gt; and press enter. This command is to start your virtual machine. It is more like booting up your local machine but this time you are booting up your virtual machine!!!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrj70l7i7jb2u4xbhuqn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrj70l7i7jb2u4xbhuqn.PNG" alt="output of vagrant up" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The next step is for you to be able to access the Linux OS you created so you can be able to do…well just about anything you want to do there. So the next command to run is &lt;code&gt;vagrant ssh&lt;/code&gt; and press enter. And that is it!!! You are now on your Linux(ubuntu) server!!!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftti7ua2owngj9q3jaf38.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftti7ua2owngj9q3jaf38.PNG" alt="output of vagrant ssh" width="800" height="387"&gt;&lt;/a&gt;&lt;br&gt;
From the picture above, you can see that path on your terminal before the &lt;code&gt;vagrant ssh&lt;/code&gt; is a path on your local machine, but after that command, it welcomes you to Ubuntu 20.04.6. Below the screen you can see the time and date of your login, which means your are logged in to the ubuntu server. And there is also the "Vagrant@ubuntu-focal" before the prompt which means at the moment you are logged into the ubuntu-focal server as vagrant. These are how you know you are inside your linux virtual machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
So after reading through this article, you have learnt what virtual machines and vagrant are, you have installed all the softwares needed to boot up a virtual machine with vagrant and you have seen the steps of how to boot up a virtual machine on your local machine running a Linux(ubuntu) OS with vagrant on your computer &lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>linux</category>
      <category>bash</category>
      <category>virtualmachine</category>
    </item>
  </channel>
</rss>
