Mohsen Noparvar
Fullstack PHP Developer
Mohsen Noparvar
Fullstack PHP Developer
Blog Post

Automating Apache Virtual Host Creation with a Bash Script

Automating Apache Virtual Host Creation with a Bash Script

If you’ve ever set up local development environments with Apache, you know the drill – creating folders, editing configuration files, generating self-signed certificates, and updating the hosts file. It’s a manual process that can be time-consuming and error-prone. However, in this blog post, I’ll introduce you to the power of ‘Automating Virtual Host Creation with Bash Script’.

This script simplifies the creation of Apache virtual hosts, making it a breeze to set up new projects on your local machine. With just a few commands, it handles folder creation, configuration file generation, SSL certificate creation, and hosts file updates, streamlining your workflow and saving you valuable time.

Features

1. Automating Virtual Host Creation with Bash Script

The script takes care of creating the necessary directories for your virtual host, ensuring proper permissions and ownership.

# Usage
./create_vhost.sh -s example.test

2. PHP Version Selection

Choose your preferred PHP version (default is 8.2, with optional versions 8.1 and 7.4).

# Usage with PHP version
./create_vhost.sh -s example.test -p 8.1

3. SSL Support

Enable SSL with a simple flag, and the script will generate self-signed certificates for you.

# Usage with SSL
./create_vhost.sh -s example.test --ssl

Script Walkthrough

The script does the following:

  • Parses command line options to get site name, PHP version, and SSL flag.
  • Creates directories for the virtual host, sets permissions, and ownership.
  • Generates the Apache virtual host configuration for HTTP (port 80) and HTTPS (port 443 if SSL is enabled).
  • Creates self-signed SSL certificates if SSL is enabled.
  • Checks if an index.php file exists and creates it if not.
  • Enables the virtual host in Apache, reloads the configuration, and updates the hosts file.

How to Use the Script

1. Download the Script

You can download the bash script from my GitHub repository.

2. Set Execution Permissions

Make the script executable:

chmod +x create_vhost.sh

3. Run the Script

Create a new virtual host:

./create_vhost.sh -s example.test

Customize the PHP version or enable SSL as needed.

Understanding the Script:

Default Values

# Default values
PHP_VERSION="8.2"
SSL_ENABLED=false
SSL_CERT_FILE=""
SSL_KEY_FILE=""

These lines set default values for PHP version, SSL enabling, and SSL certificate/key files.

usage Function

# Function to display usage information
usage() {
    echo "Usage: $0 -s <site_name> [-p <php_version>] [-ssl]"
    echo "Options:"
    echo "  -s   Site name (e.g., example.test)"
    echo "  -p   PHP version (default is 8.2, optional: 8.1, 7.4)"
    echo "  -ssl Enable SSL"
    exit 1
}

This function displays usage information and exits the script with an error code.

generate_ssl Function

# Function to generate SSL certificate and key
generate_ssl() {
    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -keyout "/etc/ssl/private/$SITE_NAME.key" \
        -out "/etc/ssl/certs/$SITE_NAME.crt" \
        -subj "/C=US/ST=State/L=City/O=Organization/OU=Unit/CN=$SITE_NAME"
    SSL_CERT_FILE="/etc/ssl/certs/$SITE_NAME.crt"
    SSL_KEY_FILE="/etc/ssl/private/$SITE_NAME.key"
}

This function uses OpenSSL to generate a self-signed SSL certificate and key for the specified site.

update_hosts_file Function

# Function to update /etc/hosts file
update_hosts_file() {
    HOSTS_ENTRY="127.0.0.1       $SITE_NAME"
    sudo sed -i "/# The following lines are desirable for IPv6 capable hosts/ i $HOSTS_ENTRY" /etc/hosts
}

This function updates the /etc/hosts file by adding an entry for the specified site.

Parse Command Line Options

# Parse command line options
OPTIONS=$(getopt -o s:p: -l site-name:,php-version:,ssl -- "$@")
eval set -- "$OPTIONS"

while true; do
    case "$1" in
        -s|--site-name)
            SITE_NAME="$2"
            shift 2
            ;;
        -p|--php-version)
            PHP_VERSION="$2"
            shift 2
            ;;
        --ssl)
            SSL_ENABLED=true
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done

These lines parse command line options using getopt and set variables accordingly.

Check Required Options

# Check if required options are provided
if [ -z "$SITE_NAME" ]; then
    echo "Site name is required."
    usage
fi

Checks if the required site name is provided; exits the script with an error message if not.

Set Up Virtual Host Configuration

# Set up virtual host configuration
VHOST_CONF="/etc/apache2/sites-available/$SITE_NAME.conf"
VHOST_PUBLIC_FOLDER="/var/www/$SITE_NAME/public"
VHOST_MAIN_FOLDER="/var/www/$SITE_NAME"

These lines set up variables for the virtual host configuration and folder paths.

Create Site Directory

# Create the directory for the site
sudo mkdir -p "$VHOST_PUBLIC_FOLDER"
sudo chown -R $USER:www-data "$VHOST_MAIN_FOLDER"
sudo chmod -R o+r "$VHOST_MAIN_FOLDER"
sudo chmod -R g+w "$VHOST_MAIN_FOLDER"

Creates the directory for the site, sets ownership and permissions.

Create Virtual Host Configuration for HTTP (port 80)

# Create the virtual host configuration for HTTP (port 80)
HTTP_SECTION="
<VirtualHost $SITE_NAME:80>
    ServerAdmin admin@$SITE_NAME
    ServerName $SITE_NAME
    ServerAlias www.$SITE_NAME
    DocumentRoot $VHOST_PUBLIC_FOLDER
    DirectoryIndex index.php  

    <Directory $VHOST_PUBLIC_FOLDER>
        Options +Indexes
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
        SetHandler \"proxy:unix:/run/php/php$PHP_VERSION-fpm.sock|fcgi://localhost\"
    </FilesMatch>

    ErrorLog \${APACHE_LOG_DIR}/${SITE_NAME}_error.log
    CustomLog \${APACHE_LOG_DIR}/${SITE_NAME}_access.log combined
</VirtualHost>
"

Creates the configuration section for the virtual host on HTTP.

Create Virtual Host Configuration for HTTPS (port 443)

# Create the virtual host configuration for HTTPS (port 443)
HTTPS_SECTION=""
if [ "$SSL_ENABLED" = true ]; then
    generate_ssl
    HTTPS_SECTION="
<VirtualHost $SITE_NAME:443>
    ServerAdmin admin@$SITE_NAME
    ServerName $SITE_NAME
    ServerAlias www.$SITE_NAME
    DocumentRoot $VHOST_PUBLIC_FOLDER
    DirectoryIndex index.php

    <Directory $VHOST_PUBLIC_FOLDER>
        Options +Indexes
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
        SetHandler \"proxy:unix:/run/php/php$PHP_VERSION-fpm.sock|fcgi://localhost\"
    </FilesMatch>

    ErrorLog \${APACHE_LOG_DIR}/${SITE_NAME}_error.log
    CustomLog \${APACHE_LOG_DIR}/${SITE_NAME}_access.log combined

    SSLEngine on
    SSLCertificateFile $SSL_CERT_FILE
    SSLCertificateKeyFile $SSL_KEY_FILE
</VirtualHost>
"
fi

Conditionally creates the configuration section for the virtual host on HTTPS if SSL is enabled.

Concatenate HTTP and HTTPS Sections

# Concatenate the HTTP and HTTPS sections and create the virtual host configuration
{ echo "$HTTP_SECTION"; echo "$HTTPS_SECTION"; } | sudo tee "$VHOST_CONF" > /dev/null

Concatenates the HTTP and HTTPS sections and writes them to the virtual host configuration file.

Set Index.php File Path

# Set the index.php file path
INDEX_FILE="$VHOST_PUBLIC_FOLDER/index.php"

Sets the path for the index.php file.

Check If Index.php Already Exists

# Check if index.php already exists
if [ ! -e "$INDEX_FILE" ]; then
    # Create index.php in the public folder
    echo "<?php phpinfo(); ?>" | sudo tee "$INDEX_FILE" > /dev/null

    # Set ownership for the index.php file
    sudo chown "$USER:www-data" "$INDEX_FILE"
fi

Checks if the index.php file already exists. If not, it creates the file and sets ownership.

Enable the Site

# Enable the site
sudo a2ensite $SITE_NAME

Enables the virtual host in Apache.

Reload and Restart Apache

# Reload and Restart Apache to apply changes
sudo systemctl reload apache2
sudo systemctl restart apache2

Reloads and restarts Apache to apply the changes.

Update /etc/hosts File

# Update /etc/hosts file
update_hosts_file

Calls the update_hosts_file function to update the /etc/hosts file.

Print Success Message

echo "Virtual host for $SITE_NAME created successfully."

Prints a success message to the console.

SSL Certificate and Key Information

# If SSL is enabled, inform the user about the generated certificate and key
if [ "$SSL_ENABLED" = true ]; then
    echo "SSL certificate and key files generated:"
    echo "  Certificate: $SSL_CERT_FILE"
    echo "  Key: $SSL_KEY_FILE"
fi

Prints information about the generated SSL certificate and key if SSL is enabled.

Conclusion

This bash script, titled ‘Automating Virtual Host Creation with Bash Script,’ simplifies the process of creating Apache virtual hosts, saving you time and reducing the likelihood of errors. While tools like Docker offer convenience, this script is ideal for those who prefer working with local servers. Feel free to customize it to suit your specific needs and contribute to its improvement on GitHub.

Give it a try, and happy coding!

Taggs:
Write a comment