computing:selfhostedwp [Haack's Wiki]

User Tools

Site Tools


  • selfhostedwp
  • Jonathan Haack
  • Haack's Networking


This tutorial is for setting up a self-hosted WordPress instance on Debian GNU/Linux. This tutorial assumes you already have a LAMP stack with active TLS. If not, you should read the Apache Survival tutorial first. Once you do that, begin with some common php extensions needed for Word Press to function well:

sudo apt install php-cgi php-cli php-zip php-mysql php-mbstring php-intl php-fpm php-curl php-gd php-mbstring php-imagick php-xml php-xmlrpc wget unzip php-gd php-zip libapache2-mod-php

Or …

sudo apt-get install php7.4-{cgi,cli,zip,mysql,mbstring,intl,fpm,curl,gd,imagick,xml,xmlrpc,gpm}

Okay, let's now enable fast cgi and rewrite php modules and then check your config.

sudo a2enmod rewrite
sudo a2enmod proxy_fcgi
sudo a2enconf php7.3-fpm
sudo apache2ctl configtest  

Move index.php to the top priority as follows:

sudo nano /etc/apache2/mods-enabled/dir.conf
<DirectoryIndex index.php index.html index.cgi index.xhtml index.htm>

Optionally, we can install phpmyadmin, and if you do, you should secure as follows:

sudo htpasswd -c /etc/apache2/.phpmyadmin phpmyadmin  
sudo nano /usr/share/phpmyadmin/.htaccess

Enter the following in the file that opens:

<AuthType Basic>
<AuthName "Restricted Files">
<AuthUserFile /etc/apache2/.phpmyadmin>
<Require valid-user>

Close and save the file. Let's set up a database now for the WordPress instance:

sudo mysql -u root -p
CREATE DATABASE databasename DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON databasename.* TO 'databaseuser'@'localhost' IDENTIFIED BY 'passwordhere';

Next up, it is time to allow overrides in your primary apache configuration:

sudo nano /etc/apache2/apache2.conf
<Directory /var/www/>
<AllowOverride All>

If you have not set the fully qualified domain name, you may get an error - that can safely be ignored unless you desire it. If you want to get rid of that, navigate to /etc/apache2/apache.conf and enter a ServerName. Otherwise, time to download Word Press:

cd ~/Downloads
mkdir wpdownload
cd wpdownload
curl -O
tar xzvf latest.tar.gz
touch ~/Downloads/wpdownload/wordpress/.htaccess
sudo chmod 640 ~/Downloads/wpdownload/wordpress/.htaccess
cp ~/Downloads/wpdownload/wordpress/wp-config-sample.php ~/Downloads/wpdownload/wordpress/wp-config.php
mkdir ~/Downloads/wpdownload/wordpress/wp-content/upgrade

Okay, we will need the files and directories I created once we get it running. Now, let's move the wordpress directory to the proper location for self-hosting.

sudo mv ~/Downloads/wpdownload/wordpress /var/www/

Now, let's set up permissions and ownership:

sudo chown -R www-data:www-data /var/www/
sudo find /var/www/ -type d -exec chmod g+s {} \;
sudo chmod 755 /var/www/
sudo chmod -R 755 /var/www/
sudo chmod -R 755 /var/www/

Ok, time to grab 'secure values' from and then set up wp-config.php for the installation, and also enter in the database credentials from above:

curl -s
sudo nano /var/www/

Let's also add the following line to the wp-config.php file for updates:

sudo nano /var/www/

Plug-ins and other WP services can mess with the .htaccess file often, so use this default configuration below when that happens; more templates can be found here: WP Codex

sudo nano /var/www/

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

Visit wordpress site and configure by opening a web browser of your choice and entering If you need more than one site, but do not want to set up a separate virtual host, for example using, then you should read Word Press Multisite. Optimizing WP is a different matter, for caching and header security, and other best practices, consider the following.

apt install memcached
nano /etc/default/memcached
a2enmod cache

You can optionally require an sftp server instead of using the default installer. Here's an example using proftp, which is still maintained:

sudo apt install proftpd ftp ftp-ssl 
cd /etc/proftpd
sudo openssl req -new -x509 -days 7305 -nodes -out ftpd-rsa.pem -keyout ftpd-rsa-key.pem
sudo nano /etc/proftpd/proftpd.conf

<IfModule mod_tls.c>
   TLSEngine on
   TLSLog /var/log/proftpd-tls.log
   TLSProtocol TLSv1
   # Are clients required to use FTP over TLS when talking to this server?
   TLSRequired off
   TLSRSACertificateFile    /etc/proftpd/ftpd-rsa.pem
   TLSRSACertificateKeyFile /etc/proftpd/ftpd-rsa-key.pem
   # Authenticate clients that want to use FTP over TLS?
   TLSVerifyClient off
   TLSOptions NoSessionReuseRequired

Put this snippet under #Include /etc/proftpd/tls.conf and then restart the service:

sudo systemctl restart proftpd.service

Happy hacking!

oemb1905 2019/08/09 05:32

computing/selfhostedwp.txt · Last modified: 2023/06/09 23:12 by oemb1905