Setting up a Multi-Domain WordPress Server on Ubuntu Linux

This article will show you how to install WordPress for multi domain or multi tenant instances, step by step. This tutorial uses permissions designed to have WordPress sites on the server managed by a single maintainer. If planning on using  multiple maintainers for Web sites, you should investigate how to do this by granting secure permissions to each user so as to not allow a single maintainer access to all www folders.

Before proceeding, please read this post and understand the different types of multi-site configurations available. In this article, we are going to set up a single instance, single database multi-site WordPress, what WordPress refers to as a multisite network.

Requirements:

  • You will need basic understanding of router IP address forwarding / NAT
  • You will need basic understanding of how DNS works
  • You will need basic understanding of Linux and shell commands
  • You will need a Linux Ubuntu 20.04 server with SSH or console access
  • You will need a router with port forwarding and NAT capabilities if self-hosting locally
  • You will need a public static IP address
  • You will need a domain name and access to its authorative DNS zone 

     

    Installing WordPress

     

    To begin, make sure you have a fresh Ubuntu server instance installed, we will be using 20.04 LTS in this tutorial.

    Log in to your Ubuntu instance and run the following command to update the operating system:

    sudo apt update

    Once the updates are completed, it’s time to install packages and dependencies. Run the command: sudo apt install followed by the package name. You will need to install the following packages:

    apache2
    ghostscript
    libapache2-mod-php
    mysql-server
    php 
    php-bcmath
    php-curl
    php-imagick
    php-intl
    php-json
    php-mbstring
    php-mysql
    php-xml
    php-zip

    You can install all the packages and dependencies at once by spacing each package name after the apt update command:

    sudo apt install  apache2  ghostscript  libapache2-mod-php  mysql-server php php-bcmath php-curl php-imagick php-intl php-json php-mbstring php-mysql php-xml php-zip

    Now, we need to create an installation directory, set the permissions and the download the WordPress package.

    sudo mkdir –p /srv/www

    sudo chown www-data: /srv/www

    sudo curl https://wordpress.org/latest.tar.gz | sudo -u www-data tar zx -C /srv/www

    Next, create a file /etc/apache2/sites-available/wordpress.conf with nano (or your favorite text editor) and add the following lines. The server name should be replaced by the FQDN which you will use to access the Web site. Note: The server’s name should NOT include the host name, only the domain name and top-level domain name. For example:

    falconitservices.com NOT www.falconitservices.com.

    Make sure that you have a wildcard A record set up in your DNS that resolves to the WordPress server’s IP public address. In order to use multi-domain, you must have a wildcard DNS A record for the domain name in the authorative DNS zone. Some registrars refer to this as a ‘catch all’. Essentially, your DNS zone’s A record should be *.yourdomain.com. If done correctly, pinging any random host name in your domain should resolve to the WordPress server’s public IP address.

    sudo nano /etc/apache2/sites-available/wordpress.conf

    Add the following lines to the file:

    <VirtualHost *:80>

      ServerName yourdomain.com

        DocumentRoot /srv/www/wordpress

        <Directory /srv/www/wordpress>

            Options FollowSymLinks

            AllowOverride Limit Options FileInfo

            DirectoryIndex index.php

            Require all granted

        </Directory>

        <Directory /srv/www/wordpress/wp-content>

            Options FollowSymLinks

            Require all granted

        </Directory>

    </VirtualHost>

     

    image

     

    Next, let’s enable the site, rewrite and disable the default site with the following commands:

    sudo a2ensite wordpress
    sudo a2enmod rewrite
    sudo a2dissite 000-default
    sudo systemctl restart apache2

     

    Next, we need to configure the SQL database. Run the following command:

    sudo mysql -u root

     

    You will be prompted with the MySQL shell. Run the following commands:

    CREATE DATABASE wordpress;
    CREATE USER wordpress@localhost IDENTIFIED BY '<your-password>';

    Next we will grant access:

    GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER

        -> ON wordpress.*

        -> TO wordpress@localhost;

     

    image

     

    Finally:

    FLUSH PRIVILEGES;
    quit

    Now, let start the SQL server:

    sudo service mysql start

    Next, we  configure WordPress to connect to MySQL.

    sudo -u www-data cp /srv/www/wordpress/wp-config-sample.php /srv/www/wordpress/wp-config.php

    Let’s set the database credentials. Leave the commands below intact. only replace your-password with the password you previously chose for the SQL database.

    sudo -u www-data sed -i 's/database_name_here/wordpress/' /srv/www/wordpress/wp-config.php
    sudo -u www-data sed -i 's/username_here/wordpress/' /srv/www/wordpress/wp-config.php
    sudo -u www-data sed -i 's/password_here/<your-password>/' /srv/www/wordpress/wp-config.php
    

     

    Open the config file in nano or any text editor of your choice:

     

    sudo -u www-data nano /srv/www/wordpress/wp-config.php

     

    Find the following lines:

     

    define( ‘AUTH_KEY’,         ‘put your unique phrase here’ );

    define( ‘SECURE_AUTH_KEY’,  ‘put your unique phrase here’ );

    define( ‘LOGGED_IN_KEY’,    ‘put your unique phrase here’ );

    define( ‘NONCE_KEY’,        ‘put your unique phrase here’ );

    define( ‘AUTH_SALT’,        ‘put your unique phrase here’ );

    define( ‘SECURE_AUTH_SALT’, ‘put your unique phrase here’ );

    define( ‘LOGGED_IN_SALT’,   ‘put your unique phrase here’ );

    define( ‘NONCE_SALT’,       ‘put your unique phrase here’ );

     

    Replace ‘put your unique phrase here’ with a secure and lengthy phrase. If you are not the imaginative type,  and wish to avoid using well known phrases that may be hacked, simply go to  this WordPress site to cut and paste the text with the provided text, which already includes randomized keys.

    When finished, open a browser and navigate to the server’s internal IP address. Choose a language and then fill out the site details as shown below.

    image

     

    Click on the install WordPress button. Once the installation is complete, you will be prompted to log in. Welcome to WordPress, you have completed the initial installation!

    image

    Set up your site to use ‘pretty’ permalinks in the settings –> permalinks section.

    image

     

    Go to general settings and make sure that your URL’s DO NOT include host names. They should only include the domain name and top-level domain name. If they include the hostname (as shown below, please correct it).

    Incorrect:

    image

    Correct:

    image

     

    In order for your Web server to be accessible from the public Internet, you will need a static Public IP (from your ISP), port forwarding on your router (ports 80 and 443 if planning on using SSL) as well as a wildcard for your DNS zone. Instructions for these are beyond the scope of this tutorial unfortunately.

     

    Setting up WordPress for Multi-Site Hosting

    Open the wp-config.php fle:

    sudo  nano /srv/www/wordpress/wp-config.php

    Add the following lines just above where it states ‘That’s all stop editing’, then save and exit.

    /* Multisite */
    define( 'WP_ALLOW_MULTISITE', true );

    define(‘ADMIN_COOKIE_PATH’, ‘/’);
    define(‘COOKIE_DOMAIN’, ”);
    define(‘COOKIEPATH’, ”);
    define(‘SITECOOKIEPATH’, ”);

    The multi-site allow tells WordPress to allow viewing of the multi-site setup menu. The lines to define cookie paths are necessary so that you can access each site’s admin panel. Without this code, you will receive an error stating that cookies need to be enabled despite cookies being enabled on your browser.

    When finished, save your changes then refresh your WordPress site and the click on the tools menu. You should now see a sub menu under tools named Network Setup.

    Click on it and select whether you want to use sub domain or sub folder hosting. Select sub-domains, then enter an admin email address and click on the install button.

    In this article, we are going to use sub domain address types which is better suited for supporting a larger number of domains.

    image

    Once finished, WordPress will display the code you will need to copy to the wp-config.php and .htaccess files.

    image

    Follow the instruction outlined in the page. Add the first text box’s code  to the wp-config.php file and replace the existing code in .httaccess with the second text box’s code.

     

    sudo  nano /srv/www/wordpress/wp-config.php

     

    In the wp-config.php file, look for the line that reads ‘That’s all stop editing’ and enter the provided code just above it:

    For the .htaccess file,  replace the existing rewrite code with the new code.

    sudo  nano /srv/www/wordpress/.htaccess

    image

    Log out of WordPress and back in and you should now see a network admin menu option.

    image

     

    Check the WordPress site on multi-site administration for more details and instructions on how to manage multi site WordPress instances.

     

    Creating a New Web Site in Multi-Domain WordPress

    To create a new Web site, go to MySites –> Network Admin –> Sites.  Click on the add new site button, then enter a site name. Since you will be hosting multiple sites, the name should be a short, alpha-numeric, friendly name that best describes the Web site. For example, if you are designing a site for Acme, Inc. choose ‘acme’ as the site’s URL host name so that the full UNMAPPED URL will be acme.yourdomain.com, then click on the add site button to finish. You should be able to access the site via the unmapped URL.

    Using Domain Mapping to Map Site URLs

    Next, we are going to map the site’s desired URL to the unmapped URL: Go to MySites –> Network Admin –> Sites and click to edit the newly created Web site. In the Site Address, enter the desired URL you wish to use for this site. In the example below, we will map www.rocketpropelledrollerskates.com to use the ‘acme’ site we recently created.

     

    image

     

    When WordPress receives a request to serve www.rocketpropelledrollerskates.com, it will render the site pages from acme.yourdomain.com as long as the DNS zone for www.rocketpropelledrollerskates.com has an A record that points to the WordPress server’s public IP address.

     

    Installing an SSL Certificate and Securing your Web Sites

    Installing an SSL certificate in WordPress from Let’s Encrypt is the best option since there is no fee for doing so and it’s a pretty straightforward process. Here is the article that we will follow in this tutorial. Before you begin, make sure that you have a backup or snapshot of the server in case you need to revert.

    To start, we need to install certbot on the WordPress server:

    sudo apt-get install python3-certbot-apache -y

    Next, we need to execute the certbot:

    sudo certbot –apache –d your.domain.com  -d your.otherdomain.com  -d yet.anotherdomain.com

    image

    Your primary domain will be found but Certbot will state that the vhosts  for your other domains cannot be found.

    image

    Click option # 2 so that they are automatically added to the SSL conf file.

    image

    You can choose to automatically redirect to HTTPS or you can manually do it yourself later. Choose option # 2 to redirect requests from http to https.  Navigate to your main site as well as to your sub sites to see your https splendor, compliments of WordPress and Let’s Encrypt.

     

    image

     

    image

     

    Finally, you want to set a cron job to renew your certificate, since Let’s Encrypt certificate is only valid for 90 days.

    Open crontab for editing:

    sudo crontab –e
     

    Add the following line

     

    00 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt.log
     

    image

    Save the file and certbot will automatically check every day if the certificate is up for renewal. When necessary, it will be automatically renewed.

    Leave a comment

    Your email address will not be published. Required fields are marked *

    Skip to content