Installing WordPress 4.9.6 to Ubuntu 18.04 LTS with nginx, mysql, and php 7.2 and setting ssl for https connections with letsencrypt

welcome to my tutorial on installing WordPress on Ubuntu 18.04 and launching the site. this tutorial assumes that

  1. you have a server or VPS installed with ubuntu 18.04
  2. you have access to a root terminal on the server
  3. you are comfortable with entering commands on this terminal
  4. you have never installed WordPress before

if you qualify for all of these, you are ready to install WordPress! if not, you can head over to this guide on how to install WordPress for regular people.

Variables

WP_DOMAIN is going to be the fully qualified domain name for your site, which an example is provided. You should also choose a strong password for your WP_ADMIN_PASSWORD.

WP_DOMAIN="blog.bvzzdesign.com"
WP_ADMIN_USERNAME="admin"
WP_ADMIN_PASSWORD="admin"
WP_ADMIN_EMAIL="no@spam.org"
WP_DB_NAME="wordpress"
WP_DB_USERNAME="wordpress"
WP_DB_PASSWORD="wordpress"
WP_PATH="/var/www/wordpress"
MYSQL_ROOT_PASSWORD="root"

Software Dependencies

now its time for us to install our software, for this we used nginx, PHP, and MySQL. For those of you that prefer Apache, I will refer you to NGINX vs. Apache: Our View of a Decade-Old Question. For those of you who still prefer Apache, stay tuned for a future tutorial or refer to How To Install WordPress with LAMP on Ubuntu 16.04 .

By default mysql-server is going to ask for the root password, and we automate that withdebconf-set-selections“`.

echo "mysql-server-5.7 mysql-server/root_password password $MYSQL_ROOT_PASSWORD" | sudo debconf-set-selections
echo "mysql-server-5.7 mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD" | sudo debconf-set-selections
sudo apt install -y nginx  mysql-server

there are some server configurations that have issues installing nginx, if you get errors on your nginx install running sudo service apache2 stop will fix those issues most of the time. also it may be fitting to your use case to disable apache at boot which can be acheived with sudo systemctl disable apache2.service or configure apache2 to listen on a different port

now let’s install PHP 7.2 for nginx

first, we are going to add the apt repository and update it

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/nginx-mainline
sudo apt update

next, we will run the command to install PHP 7.2 and the related modules.

sudo apt install php7.2-fpm php7.2-common php7.2-mbstring php7.2-xmlrpc php7.2-soap php7.2-gd php7.2-xml php7.2-intl php7.2-mysql php7.2-cli php7.2-zip php7.2-curl

after installing the modules be sure to restart nginx and php7.2-fpm services to reload PHP configurations

sudo systemctl restart nginx.service
sudo systemctl restart php7.2-fpm.service

Configure Nginx

first we are going to create paths for our websites source code to be stored, and for our log files

sudo mkdir -p $wp_path/public $wp_path/logs

and then we are going to create our config file for nginx, in this tutorial we use the tee command because later on, we are going to learn how to automate this process. if you prefer to edit this file by hand using a text editor, such as vim or nano, simply

sudo nano /etc/nginx/sites-available/blog.bvzzdesign.com

and then add the data by hand. otherwise, copy and paste

sudo tee /etc/nginx/sites-available/$WP_DOMAIN <<EOF
server {
  listen 80;
  listen [::]:80;
  server_name $WP_DOMAIN www.$WP_DOMAIN;

  root $WP_PATH/public;
  index index.php;

  access_log $WP_PATH/logs/access.log;
  error_log $WP_PATH/logs/error.log;

  location / {
  try_files \$uri \$uri/ /index.php?\$args;
  }

  location ~ \.php\$ {
  include snippets/fastcgi-php.conf;
  fastcgi_pass unix:/run/php/php7.2-fpm.sock;
  }
}
EOF

now we are going to make a symlink from our newly created file located at /etc/nginx/sites-available/$WP_DOMAIN to /etc/nginx/sites-enabled.

sudo ln -s /etc/nginx/sites-available/$WP_DOMAIN /etc/nginx/sites-enabled/

let’s test our configuration for errors

sudo nginx -t

and then restart the systemd service

sudo service nginx restart

oh no something went wrong!

If you have some issues with nginx, never fear! There are plenty of ways to debug

  • Check the nginx process logs by typing: sudo journalctl -u nginx
  • Check the nginx access logs by typing: sudo less /var/log/nginx/access.log
  • Check the nginx error logs by typing: sudo less /var/log/nginx/error.log
  • Check nginx configuration fiels by typing: sudo nginx -t

Configure MySQL

we are now going to create a user and database for wordpress

mysql -u root -p$MYSQL_ROOT_PASSWORD <<EOF
CREATE USER '$WP_DB_USERNAME'@'localhost' IDENTIFIED BY '$WP_DB_PASSWORD';
CREATE DATABASE $WP_DB_NAME;
GRANT ALL ON $WP_DB_NAME.* TO '$WP_DB_USERNAME'@'localhost';
EOF

ignore the warning that it is insecure to use passwords on the command line, and if you are curious on why that warning appears, refer to this post on serverfault.

Install Certbot and Generate an SSL Certificate

The first step to using Let’s Encrypt to obtain an SSL certificate is to install the Certbot software on your server.

Certbot is in very active development, so the Certbot packages provided by Ubuntu tend to be outdated. However, the Certbot developers maintain an Ubuntu software repository with up-to-date versions, so we’ll use that repository instead.

First, add the repository.

sudo add-apt-repository ppa:certbot/certbot

now we update the package list to pick up the new repository’s package info

sudo apt-get update

and now let’s install certbot

sudo apt install python-certbot-nginx

now that certbot is installed, let’s use certbot to install our SSL certificate for our domain

sudo certbot --nginx -d $WP_DOMAIN

certbot will then prompt you with a message asking for your email address used for urgent renewal and security notices
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): no@spam.com

then it will prompt you with a terms of service agreement, press A and then enter to accept

“`

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at

https://acme-v01.api.letsencrypt.org/directory

(A)gree/(C)ancel:
“`

it will then ask you if you would like to share your email with the Electronic Frontier Foundation press y or n and hit enter

“`

Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let’s Encrypt project and the non-profit
organization that develops Certbot? We’d like to send you email about EFF and

our work to encrypt the web, protect its users and defend digital rights.

(Y)es/(N)o:
“`

then you will be prompted with an option to redirect all http traffic to https thus removing http traffic, normally I choose option 1 in this situation, but this is heavily dependent on your use case

“`

<h2>Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.</h2>

1: No redirect – Make no further changes to the webserver configuration.
2: Redirect – Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this

<h2>change by editing your web server's configuration.</h2>

Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

“`

after you hit enter, the configuration will be updated and you should see a success message similar to this

“`
IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your cert will
expire on 2017-10-23. To obtain a new or tweaked version of this
certificate in the future, simply run certbot again with the
"certonly" option. To non-interactively renew <em>all</em> of your
certificates, run "certbot renew"
– Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

“`
now let make sure that our auto renewal is functional on our certbot script

sudo certbot renew --dry-run

If you see no errors, then congratulations you now have successfully installed an SSL certificate that will automatically renew

Installing WordPress

now that our system is configured for WordPress, we are ready to install it.

let’s start with recreating the directory that will contain our source code, with a new directory with the correct permissions, and then change our working directory to that directory

sudo rm -rf $WP_PATH/public/ # !!!
sudo mkdir -p $WP_PATH/public/
sudo chown -R $USER $WP_PATH/public/
cd $WP_PATH/public/

now we will download WordPress with wget, unarchive it, and remove the archive

wget https://wordpress.org/latest.tar.gz
tar xf latest.tar.gz --strip-components=1
rm latest.tar.gz

we are now going to edit some configuration files using sed and echo

mv wp-config-sample.php wp-config.php
sed -i s/database_name_here/$WP_DB_NAME/ wp-config.php
sed -i s/username_here/$WP_DB_USERNAME/ wp-config.php
sed -i s/password_here/$WP_DB_PASSWORD/ wp-config.php
echo "define('FS_METHOD', 'direct');" >> wp-config.php

next let’s change the owrnership back to www-data to the directory that our source code is located

sudo chown -R www-data:www-data $WP_PATH/public/

finally we can update our username and password with a curl command

curl "http://$WP_DOMAIN/wp-admin/install.php?step=2" \
  --data-urlencode "weblog_title=$WP_DOMAIN"\
  --data-urlencode "user_name=$WP_ADMIN_USERNAME" \
  --data-urlencode "admin_email=$WP_ADMIN_EMAIL" \
  --data-urlencode "admin_password=$WP_ADMIN_PASSWORD" \
  --data-urlencode "admin_password2=$WP_ADMIN_PASSWORD" \
  --data-urlencode "pw_weak=1"

or do it manually by navigating to the domain name that you have set up

Congratulations! you now have a working WordPress website!

3 Replies to “Installing WordPress 4.9.6 to Ubuntu 18.04 LTS with nginx, mysql, and php 7.2 and setting ssl for https connections with letsencrypt”

    1. If you have set
      $MYSQL_ROOT_PASSWORD
      then executing
      mysql -u root -p$MYSQL_ROOT_PASSWORD <
      won't require you to enter a password. does that answer your question?

  1. I’ve run into this problem at the point of installing php:

    The following packages have unmet dependencies:
    php7.2-fpm : Depends: php7.2-common (= 7.2.9-1+ubuntu18.04.1+deb.sury.org+1) but 7.2.10-0ubuntu0.18.04.1 is to be installed
    E: Unable to correct problems, you have held broken pakages.

    Any ideas?

Leave a Reply

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