How to install WordPress on Debian 10 with NGINX (LEMP)

This is mostly a guide for myself so I can remember how to install a WordPress-site – but if somebody else finds it helpful that’s great.

We begin with installing the web server, the MySQL relational database management system and PHP.

apt install nginx mariadb-server php

While we’re at it let’s install a firewall that is easy to manage.

apt install ufw

Now we enable the firewall and allow HTTP-traffic (port 80) and HTTPS-traffic (port 443).

ufw enable ufw allow 80/tcp ufw allow 443/tcp

It’s time to configure the MySQL-database. We start by doing a secure installation – choose a good password!

mysql_secure_installation

Let’s add a database and a user – whereupon we give that user permissions to use that database.

mysql -u root -p CREATE DATABASE website_db; CREATE USER website_user@localhost IDENTIFIED BY 'super-secure-password'; GRANT ALL PRIVILEGES ON website_db.* TO website_user@localhost; FLUSH PRIVILEGES; QUIT;
Code language: CSS (css)

Now we create the NGINX-configuration. We will be using HTTP and not HTTPS since it is presumed we have a reverse proxy pointing at the server.

nano /etc/nginx/sites-available/website.com

Add the following configuration. Remember to change website.com to whatever site you are using.

server { listen 80; root /var/www/html/website.com; server_name website.com; location / { index index.php index.html; try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
Code language: PHP (php)

And now we enable it by making a soft link of the configuration file to /etc/nginx/sites-enabled/.

unlink /etc/nginx/sites-enabled/default ln -s /etc/nginx/sites-available/website.com /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx
Code language: JavaScript (javascript)

In order to hide some server info like NGiNX version number and OS variant from prying eyes, uncomment the following line in /etc/nginx/nginx.conf.

server_tokens off;

Time to install some needed PHP packages.

apt install php-curl php-gd php-intl php-mbstring php-soap php-xml php-xmlrpc php-zip php7.3-opcache php7.3-mysql php7.3-cli php7.3-fpm
Code language: CSS (css)

It’s finally time to download the latest WordPress. We then copy it to our chosen folder and create a config file. Finally we change the permissions.

wget https://wordpress.org/latest.tar.gz -P /tmp tar xzf /tmp/latest.tar.gz --strip-components=1 -C /var/www/html/website.com cp /var/www/html/website.com/wp-config-sample.php /var/www/html/website.com/wp-config.php chown -R www-data:www-data /var/www/html/website.com
Code language: JavaScript (javascript)

Use the following command to get your authentication unique keys and salts.

curl -s https://api.wordpress.org/secret-key/1.1/salt/
Code language: JavaScript (javascript)

You will get something like this.

define('AUTH_KEY', ',?Hmr:|+LZ;)Zsd?w]]F!3||@Ov|b)qeCzvi9oPLs%}XCwb dd#[P^[`KtPFwV3U'); define('SECURE_AUTH_KEY', 'O@{,Mud,nvBEse3u hs]=tmR|WqHs-tMt`_`Se4-&Ol8z,`2^Wz4F04r.ENsWw;|'); define('LOGGED_IN_KEY', '.fQshMa_vEXVm(NhV4V./*H(F#&-Kj~u.4`S6{g,8++{o6%-/tB+/?6]FW_`XpE3'); define('NONCE_KEY', 'YO6;Y-M*h?x31WTpj$6Ff@A&Ewf/FObV IrL(NHmfa EX2|l^V]#;qcI43knKTbQ'); define('AUTH_SALT', 'q)x^?N+%g=.mWD5Aqlgy;A2VaV-&DdJgg.(pKz46}K1G;Q[e^%evH`<.Y^Ikisel'); define('SECURE_AUTH_SALT', 'I_R%nZ(?5s>Y2q*vg-^(Fc;sIM5euDh-H 0DVu?q/P.Mi JmK|A|}XZS@8f60Dvk'); define('LOGGED_IN_SALT', 'vyZ?hUhL<$ZZd;q#`Hj&3U/q1K,y iD2-bRa.gnU6rh?+Vp2O.|Eb,|`^bFX`QQm'); define('NONCE_SALT', ' 7--}-Q/;Ig9<0i/J5! +vTp*WHdGr `nNOAFg05Y(yyO+i+xN7+D06T(oNueMo`');
Code language: JavaScript (javascript)

Copy it and open the WordPress config file.

nano /var/www/html/website.com/wp-config.php
Code language: JavaScript (javascript)

Change the these lines.

. . . /** The name of the database for WordPress */ define( 'DB_NAME', 'website_db' ); /** MySQL database username */ define( 'DB_USER', 'website_user' ); /** MySQL database password */ define( 'DB_PASSWORD', 'super-secure-password' ); . . . /**#@+ * Authentication Unique Keys and Salts. * * Change these to different unique phrases! * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key serv$ * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to l$ * * @since 2.6.0 */ define('AUTH_KEY', ',?Hmr:|+LZ;)Zsd?w]]F!3||@Ov|b)qeCzvi9oPLs%}XCwb dd#[P^[`KtPFwV3U'); define('SECURE_AUTH_KEY', 'O@{,Mud,nvBEse3u hs]=tmR|WqHs-tMt`_`Se4-&Ol8z,`2^Wz4F04r.ENsWw;|'); define('LOGGED_IN_KEY', '.fQshMa_vEXVm(NhV4V./*H(F#&-Kj~u.4`S6{g,8++{o6%-/tB+/?6]FW_`XpE3'); define('NONCE_KEY', 'YO6;Y-M*h?x31WTpj$6Ff@A&Ewf/FObV IrL(NHmfa EX2|l^V]#;qcI43knKTbQ'); define('AUTH_SALT', 'q)x^?N+%g=.mWD5Aqlgy;A2VaV-&DdJgg.(pKz46}K1G;Q[e^%evH`<.Y^Ikisel'); define('SECURE_AUTH_SALT', 'I_R%nZ(?5s>Y2q*vg-^(Fc;sIM5euDh-H 0DVu?q/P.Mi JmK|A|}XZS@8f60Dvk'); define('LOGGED_IN_SALT', 'vyZ?hUhL<$ZZd;q#`Hj&3U/q1K,y iD2-bRa.gnU6rh?+Vp2O.|Eb,|`^bFX`QQm'); define('NONCE_SALT', ' 7--}-Q/;Ig9<0i/J5! +vTp*WHdGr `nNOAFg05Y(yyO+i+xN7+D06T(oNueMo`');
Code language: PHP (php)

You’re done! Now log in and do the final steps on your ip address, for example http://192.168.1.104.

If you found something wrong with the tutorial, don’t hesitate to write a comment!