Skip to main content

Installing Wordpress

Installing Wordpress in the most traditional way, using system packages, and fixing configuration files.

important

Before starting, make a snapshot of the VPS, so that we can revert easily all the changes that we make.

note

Let's also check the DNS configuration:

# apt install bind9-dnsutils
# which dig
dig www.user1.fs.al +short
dig wp1.user1.fs.al +short
dig wp2.user1.fs.al +short

1. Install LAMP Stack

1.1 Open ports 80 and 443

We have to open the port 80 and 443 on the firewall, which are needed by a web server:

firewall-cmd --list-all
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --reload
firewall-cmd --list-all
Test port accessibility

We can test the ports with netcat:

  1. Install it:

    apt list 'netcat*'
    apt purge netcat-traditional
    apt install netcat-openbsd
    which nc
  2. On the VPS, start listening to the port 80 (tcp):

    nc -l 80
  3. On a client (from outside VPS) connect to the port 80:

    # nc 188.245.242.143 80
    nc www.user1.fs.al 80
  4. Send messages back and forth from the client to the VPS. If messages are transmitted, the port 80 is open and accessible from outside VPS. Close the connection with Ctrl+c.

Try the same thing for the port 443

1.2 Install Apache Web Server

apt install apache2 apache2-utils
apache2 -v
systemctl status apache2
Testing
wget http://127.0.0.1
wget http://188.245.242.143/

Open in browser http://188.245.242.143/ or http://www.user1.fs.al

1.3 Install MariaDB

apt install mariadb-server mariadb-client
systemctl status mariadb
mysql_secure_installation
Try some MariaDB commands
mariadb
show databases;
use mysql;
show tables;
describe user;
select user, host from mysql.user;
show grants for root@localhost;

1.4 Install PHP

apt install \
php \
php-cli \
php-fpm \
php -v
apt install \
libapache2-mod-php \
php-mysql
ls /etc/apache2/mods-enabled/php*
# install some php modules needed by wordpress
apt install \
php-json \
php-pdo \
php-zip \
php-gd \
php-mbstring \
php-curl \
php-xml \
php-pear \
php-bcmath
Testing
  1. Create info.php on the DocumentRoot of apache2:

    ls /var/www/html/
    echo "<?php phpinfo(); ?>" > /var/www/html/info.php
    cat /var/www/html/info.php
  2. Open in browser http://www.user1.fs.al/info.php

  3. Once you confirme that it is working, remove the file info.php (for security reasons):

    rm /var/www/html/info.php

2. Install WP Site

We want to install a Wordpress site on http://wp1.user1.fs.al and http://www.wp1.user1.fs.al

Let's make sure first that the DNS configuration is OK:

dig wp1.user1.fs.al +short
dig www.wp1.user1.fs.al +short

It should return the IP of our VPS.

2.1 Create a Database

We will create a MariaDB database, a MariaDB user, and will grant to the user the rights and privileges for managing this database.

  1. Create a database:

    mariadb
    CREATE DATABASE wp1db;
    show databases;
  2. Create a user:

    CREATE USER 'wp1user'@'localhost' IDENTIFIED BY 'wp1pass';
    select user, host from mysql.user;
  3. Grant all privileges to the user on the WP database:

    GRANT ALL ON wp1db.* TO 'wp1user'@'localhost';
    show grants for 'wp1user'@'localhost';
    FLUSH PRIVILEGES;
    exit;

2.2 Get WP Code

  1. Download WP:

    wget https://wordpress.org/latest.tar.gz
    tar xpf latest.tar.gz
    ls wordpress/
    rm latest.tar.gz

    mv wordpress /var/www/wp1
    ls /var/www/wp1/
  2. Fix ownership and permissions:

    cd /var/www/wp1/
    ls -al
    chown -R www-data:www-data .
    find . -type d -exec chmod 755 {} \;
    find . -type f -exec chmod 644 {} \;
    ls -al

2.3 Create Apache vHost

  1. Explore apache config:

    cd /etc/apache2/
    ls
    ls sites-available/
    ls sites-enabled/
  2. Create config file sites-available/wp1.conf:

    cat <<'EOF' > sites-available/wp1.conf
    <VirtualHost *:80>
    ServerName wp1.user1.fs.al
    # ServerAlias www.wp1.user1.fs.al
    DocumentRoot /var/www/wp1

    <Directory /var/www/wp1>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/wp1-error.log
    CustomLog ${APACHE_LOG_DIR}/wp1-access.log combined
    </VirtualHost>
    EOF
    cat sites-available/wp1.conf
  3. Enable the config file:

    a2ensite wp1
    ls -l sites-enabled/
  4. Enable module rewrite:

    a2enmod rewrite
    ls mods-enabled/
  5. Restart apache2

    apachectl configtest
    apachectl -t

    systemctl restart apache2
    systemctl status apache2
Fix apache2 warning

When you test apache2 configuration with apachectl -t, you probably get this warning:

AH00558: apache2: Could not reliably determine the server's fully qualified domain name,
using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message

It can be fixed like this:

cd /etc/apache2/

echo "ServerName $(hostname)" > conf-available/servername.conf
cat conf-available/servername.conf

a2enconf servername
ls -l conf-enabled/

apachectl -t

2.4 Run WP wizard

Open http://wp1.user1.fs.al in browser. It will show the WP installation wizard. Insert the database credentials, etc.

3. Improvements

3.1 Add an Alias

An "alias" is another name for the same website.

Edit the config file /etc/apache2/sites-available/wp1.conf and uncomment this line:

ServerAlias www.wp1.user1.fs.al

Then reload apache and try to open in a browser tab http://www.wp1.user1.fs.al

systemctl reload apache2

3.2 Enable HTTPS

  1. Enable module SSL of apache2:

    ls mods-available/ssl*
    ls mods-enabled/ssl*
    a2enmod ssl
    ls mods-enabled/ssl*

    systemctl restart apache2
  2. Install package ssl-cert, which will also generate a self-signed SSL certificate (ssl-cert-snakeoil):

    apt install ssl-cert
  3. Append these lines to the site config file:

    cat <<'_EOF_' >> /etc/apache2/sites-available/wp1.conf
    <VirtualHost *:443>
    ServerName wp1.user1.fs.al
    ServerAlias www.wp1.user1.fs.al
    DocumentRoot /var/www/wp1

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    #SSLCertificateChainFile /etc/ssl/certs/ssl-cert-snakeoil.pem

    <Directory /var/www/wp1>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/wp1-error.log
    CustomLog ${APACHE_LOG_DIR}/wp1-access.log combined
    </VirtualHost>
    _EOF_
  4. Restart apache2:

    apachectl -t
    systemctl restart apache2
    systemctl status apache2

Now, open in browser https://wp1.user1.fs.al Notice that the browser complains that the SSL certificate is not valid (it is self-signed).

3.3 Get a LetsEncrypt certificate

With LetsEncrypt we can get an SSL certificate for our site. It is free and can be received quickly.

  1. Install certbot:

    apt install certbot
  2. Configure apache2 for letsencrypt:

    cat <<EOF > /etc/apache2/conf-available/letsencrypt.conf
    Alias /.well-known/acme-challenge /var/www/.well-known/acme-challenge
    <Directory /var/www/.well-known/acme-challenge>
    Options None
    AllowOverride None
    ForceType text/plain
    </Directory>
    EOF
    mkdir -p /var/www/.well-known/acme-challenge/
    a2enconf letsencrypt
    ls -l /etc/apache2/conf-enabled/
    apachectl -t
    systemctl reload apache2
  3. Get an SSL certificate:

    certbot --help
    certbot certonly --help

    certbot certonly --webroot -w /var/www --dry-run
    certbot certonly --webroot -w /var/www \
    -d wp1.user1.fs.al,www.wp1.user1.fs.al
    certbot certificates
  4. Edit /etc/apache2/sites-available/wp1.conf to use the new certificate:

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/wp1.user1.fs.al/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/wp1.user1.fs.al/privkey.pem
    #SSLCertificateChainFile /etc/ssl/certs/ssl-cert-snakeoil.pem
  5. Reload apache2 config:

    apachectl -t
    systemctl reload apache2
  6. Open https://wp1.user1.fs.al in browser and check the certificate.

  7. Let's also make sure that the certificate will be renewed automatically, before it expires:

    certbot renew --dry-run
    certbot renew

    systemctl status certbot.timer
    systemctl list-timers certbot.timer
    systemctl cat certbot.timer
    systemctl cat certbot.service

    There is no need for a cron job.

3.4 Redirect from HTTP to HTTPS

  1. Edit the config file /etc/apache2/sites-available/wp1.conf so that it looks like this:

    <VirtualHost *:80>
    ServerName wp1.user1.fs.al
    ServerAlias www.wp1.user1.fs.al
    Redirect / https://wp1.user1.fs.al/
    # Redirect permanent / https://wp1.user1.fs.al/
    </VirtualHost>
  2. Reload apache2 config

    apachectl -t
    systemctl reload apache2
  3. Test it, by trying to open HTTP://wp1.user1.fs.al in browser. It should redirect automatically to HTTPS.

note

After all the modifications that we have made to the virtual host config file, it should look like this:

<VirtualHost *:80>
ServerName wp1.user1.fs.al
ServerAlias www.wp1.user1.fs.al
Redirect / https://wp1.user1.fs.al:8443/
</VirtualHost>

<VirtualHost *:443>
ServerName wp1.user1.fs.al
ServerAlias www.wp1.user1.fs.al
DocumentRoot /var/www/wp1

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/wp1.user1.fs.al/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/wp1.user1.fs.al/privkey.pem
#SSLCertificateChainFile /etc/ssl/certs/ssl-cert-snakeoil.pem

<Directory /var/www/wp1>
Options -Indexes +FollowSymLinks
AllowOverride All
</Directory>

ErrorLog ${APACHE_LOG_DIR}/wp1-error.log
CustomLog ${APACHE_LOG_DIR}/wp1-access.log combined
</VirtualHost>
Download

Download it: wp1-config.apache2

wget https://linux-cli.fs.al/apps/part2/wp1-config.apache2
mv wp1-config.apache2 /etc/apache2/sites-available/wp1.conf
nano /etc/apache2/sites-available/wp1.conf

3.5 Install wp-cli

  1. Download and install:

    wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    chmod +x wp-cli.phar
    ls -l wp-cli.phar
    mv wp-cli.phar /usr/local/bin/wp
    which wp
  2. Create an alias:

    wp
    alias wp='sudo -u www-data wp'
    alias
    wp
  3. Add this alias to ~/.bashrc_custom as well, so that it is defined again next time that we login:

    echo "alias wp='sudo -u www-data wp'" >> ~/.bashrc_custom
    nano ~/.bashrc_custom
  4. Modify /etc/hosts and make sure that it contains this line:

    127.0.1.1  mycloud

    This will avoid a warning by sudo. Here, mycloud is the hostname (the result of the command hostname).

    tip

    Add also this line:

    127.0.0.1  wp1.user1.fs.al

    This way the app won’t have to query the public DNS, which may improve the overall stability.

  5. Try it:

    wp
    cd /var/www/wp1/
    wp option get siteurl
    wp option get home
    wp help user
    wp help user list
    wp user list

    wp help user create
    wp user create
    wp user create \
    dashamir \
    dashohoxha+1@gmail.com \
    --role=author \
    --first_name=Dashamir \
    --last_name=Hoxha
    wp user list

4. Install a second WP site

  1. Check DNS config:

    dig wp2.user1.fs.al +short
    dig www.wp2.user1.fs.al +short
  2. Create a DB:

    mariadb
    CREATE DATABASE wp2db;
    CREATE USER 'wp2user'@'localhost' IDENTIFIED BY 'wp2pass';
    GRANT ALL ON wp2db.* TO 'wp2user'@'localhost';
    FLUSH PRIVILEGES;
    exit;
  3. Download WP:

    wget https://wordpress.org/latest.tar.gz
    tar xpf latest.tar.gz
    rm latest.tar.gz

    mv wordpress /var/www/wp2
    cd /var/www/wp2/

    chown -R www-data:www-data .
    find . -type d -exec chmod 755 {} \;
    find . -type f -exec chmod 644 {} \;
  4. Create an apache2 virtual host:

    cd /etc/apache2/sites-available/
    cp wp1.conf wp2.conf
    sed -i wp2.conf -e 's/wp1/wp2/g'
    micro wp2.conf
    a2ensite wp2
    apachectl -t

    Notice that the SSL certificate is missing.

  5. Get a letsencrypt SSL certificate:

    certbot certonly \
    --webroot -w /var/www \
    -d wp2.user1.fs.al,www.wp2.user1.fs.al \
    -m dashohoxha@gmail.com \
    --agree-tos
    certbot certificates
  6. Reload apache2 config:

    apachectl -t
    systemctl reload apache2
  7. Open in browser https://wp2.user1.fs.al and complete the installation.