This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
computing:selfhostedwp [2018/11/26 13:27] – created oemb1905 | computing:selfhostedwp [2023/12/16 20:33] (current) – oemb1905 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ------------------------------------------- | ||
+ | * **selfhostedwp** | ||
+ | * **Jonathan Haack** | ||
+ | * **Haack' | ||
+ | * **netcmnd@jonathanhaack.com** | ||
+ | ------------------------------------------- | ||
+ | // | ||
- | Set up ftp server and then set up content mgt & mySQL | + | ------------------------------------------- |
- | sudo apt install proftpd ftp ftp-ssl ftpd-ssl | + | This tutorial is for setting up a self-hosted WordPress instance on Debian GNU/Linux. This tutorial assumes you have some familiarity setting up a LAMP stack. If you need help with that, check out [[https:// |
- | cd /etc/proftpd | + | |
- | sudo openssl req -new -x509 -days 7300 -nodes -out ftpd-rsa.pem | + | sudo apt install apache2 mariadb-server php8.2 php-common php-cgi php-cli php-zip php-mysql php-mbstring php-intl php-fpm php-curl php-gd php-imagick php-xml php-xmlrpc php-soap php-opcache php-apcu php-bcmath memcached wget unzip |
- | sudo nano / | + | |
| | ||
- | < | + | Sometimes dpkg can choose which version of php you want and it's not always the version you want. In those cases, you can explicitly specify the version you need. Some packages are only available as '' |
- | | + | |
- | | + | |
- | | + | |
- | # Are clients required to use FTP over TLS when talking to this server? | + | |
- | | + | |
- | | + | |
- | | + | |
- | # Authenticate clients that want to use FTP over TLS? | + | |
- | | + | |
- | </ | + | |
| | ||
- | sudo systemctl restart proftpd.service | + | sudo apt-get install php8.2-{common, |
+ | |||
+ | Apache2 will set up a 000-default.conf automatically and your host should now resolve. Be sure to set up TLS with certbot. Here's my preferred method: | ||
- | Might change the TLS version/ | + | sudo apt install certbot letsencrypt python3-certbot-apache |
- | + | sudo certbot --authenticator standalone --installer apache | |
- | sudo apt install mysql-server php7.0 phpmyadmin apache2-utils php libapache2-mod-php php-mcrypt php-mysql | + | |
- | | + | |
- | | + | |
| | ||
- | < | + | Once you have the LAMP stack setup and TLS properly configured, it's time to make some decisions on your php handler and your apache2 multi-processing module (mpm). There' |
- | DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm | + | |
- | </ | + | |
| | ||
- | sudo systemctl restart | + | |
- | + | sudo apt install php8.3-fpm php8.3-cgi | |
- | Secure phpmyadmin with user phpmyadmin | + | sudo a2enmod ssl |
+ | sudo a2enmod headers | ||
+ | sudo a2enmod cache | ||
+ | sudo a2enmod rewrite | ||
+ | sudo a2enmod setenvif | ||
+ | sudo a2dismod php8.1 | ||
+ | sudo a2dismod php8.2 | ||
+ | sudo a2dismod php8.3 | ||
+ | sudo a2dismod mpm_prefork | ||
+ | sudo a2enmod mpm_event | ||
+ | sudo a2enmod proxy | ||
+ | sudo a2enmod proxy_fcgi | ||
+ | sudo a2enconf php8.3-fpm | ||
+ | sudo a2enconf php8.3-cgi | ||
+ | sudo apache2ctl configtest | ||
+ | | ||
+ | sudo systemctl restart php8.3-fpm | ||
+ | |||
+ | There are two standard ways to configure php-fpm. One of those is to use ProxyPassReverse, | ||
+ | |||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | That takes care of configuring php-fpm | ||
+ | |||
+ | sudo apachectl -M | grep ' | ||
+ | sudo apachectl -M | grep ' | ||
+ | sudo apache2ctl configtest | ||
+ | |||
+ | The output of mpm should show mpm_event and the output of proxy grep should show proxy_module and proxy_fcgi_module in use. If not, trace back over the steps above and see what went wrong. As for configtest, it should either tell you what's wrong or return " | ||
+ | sudo apt install phpmyadmin | ||
sudo htpasswd -c / | sudo htpasswd -c / | ||
- | sudo nano / | + | sudo nano / |
+ | < | ||
+ | < | ||
+ | < | ||
+ | <Require valid-user> | ||
+ | |||
+ | If you don't need something as heavy as phpmyadmin, you can optionally create a phpinfo page instead: | ||
+ | |||
+ | sudo nano / | ||
+ | sudo htpasswd -c / | ||
+ | sudo nano / | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <Require valid-user> | ||
+ | |||
+ | Use these tools to make sure your handler and multi-processing module are configured to your preference and functional. After that's all working, let's make sure that your WordPress index.php is set to top priority as follows: | ||
| | ||
- | | + | |
- | AuthName " | + | |
- | AuthUserFile | + | |
- | | + | Close and save the file. Let's now set up a database now for the WordPress instance as follows: |
- | + | ||
- | sudo systemctl restart apache2.service | + | |
- | + | ||
- | Now, the MySQL - more here than neeeded in case of trouble: | + | |
sudo mysql -u root -p | sudo mysql -u root -p | ||
- | | + | CREATE DATABASE |
- | | + | GRANT ALL ON databasename.* TO ' |
- | | + | FLUSH PRIVILEGES; |
- | mysql> GRANT ALL ON database2name.* TO ' | + | EXIT; |
- | mysql> | + | |
- | | + | Next up, it is time to allow overrides in your primary apache configuration. This is optional but/and it allows WordPress extensions to make configuration changes to .htaccess and/or other changes to the web server. It's often helpful, but you can leave it off if you prefer and configure everything manually. |
- | Install PHP, configure .htaccess to allow overrides, enable apache modules: | ||
- | | ||
- | sudo apt update | ||
- | sudo apt-get install php-curl php-gd php-mbstring php-mcrypt php-xml php-xmlrpc | ||
sudo nano / | sudo nano / | ||
+ | < | ||
| | ||
- | < | + | Let's now shell into our instance and set up WordPress. |
- | AllowOverride All | + | |
- | </ | + | |
- | + | ||
- | sudo systemctl restart apache2 | + | |
- | sudo a2enmod rewrite | + | |
- | sudo apache2ctl configtest | + | |
- | + | ||
- | If you have not set the fully qualified domain name, you may get an error - that can safely be ignored unless you desire it. | + | |
- | | + | |
- | mkdir wpdownload | + | |
- | cd wpdownload | + | |
curl -O https:// | curl -O https:// | ||
tar xzvf latest.tar.gz | tar xzvf latest.tar.gz | ||
- | | + | |
- | | + | |
- | cp ~/ | + | Okay, we will need the files and directories I created once we get it running. |
- | mkdir ~/ | + | |
- | sudo cp -ar ~/ | + | sudo mv ~/ |
- | sudo cp -ar ~/ | + | |
- | sudo chown -R username:www-data | + | Now, create proper permissions for your Word Press directories and files: |
- | sudo chown -R username:www-data /var/www/site2.com/ | + | |
+ | sudo chown -R www-data: | ||
sudo find / | sudo find / | ||
- | | + | sudo chmod 755 / |
- | | + | sudo chmod -R 755 / |
- | sudo chmod g+w / | + | sudo chmod -R 755 / |
- | sudo chmod -R g+w / | + | |
- | sudo chmod -R g+w / | + | It's now time to configure your '' |
- | sudo chmod -R g+w / | + | |
- | sudo chmod -R g+w / | + | |
- | + | ||
- | Grab secure values from Word Press for wp-config.php: | + | |
| | ||
curl -s https:// | curl -s https:// | ||
- | sudo nano / | + | sudo nano / |
- | <swap the defined values from first curl> | + | <Replace |
| | ||
- | curl -s https://api.wordpress.org/secret-key/ | + | Sometimes, for reasons I am not sure about, WordPress does not allow users direct uploading. If/when that happens, add the entry to wp-config.php. If anyone knows why this is needed, please let me know! |
- | sudo nano / | + | |
- | < | + | |
- | + | ||
- | Enter user name and password for database in wp-config.php: | + | |
sudo nano / | sudo nano / | ||
- | | + | |
- | . . . | + | |
- | | + | Let's now visit site1.com in a web browser. Enter the credentials that you created for the database above. Choose the settings you prefer and set up an admin account and record your credentials securely. You should now have a proper WordPress site! Now that you have a WordPress, check the SiteHealth tab and follow its advice and/or know why you don't. In my case, I typically adjust cache, rewrites, and headers. |
- | /** MySQL database username */ | + | |
- | | + | |
- | | + | nano /etc/default/memcached |
- | define(' | + | |
- | . . . | + | |
- | | + | |
- | + | | |
- | | + | |
- | + | ||
- | | + | After isntalling memcached and enabling those modules, navigate to your web root and adjust your .htaccess as follows: |
- | | + | |
- | | + | |
- | | + | ExpiresActive On |
- | /** MySQL database password */ | + | ExpiresByType image/jpg " |
- | | + | ExpiresByType image/jpeg " |
- | . . . | + | |
- | | + | |
- | + | | |
- | sudo systemctl restart apache2 | + | |
- | + | | |
- | 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: [[https:// | + | |
+ | | ||
- | sudo nano / | ||
- | | ||
- | # BEGIN WordPress | ||
< | < | ||
- | | + | |
- | RewriteBase / | + | |
- | RewriteRule ^index\.php$ - [L] | + | |
- | RewriteCond %{REQUEST_FILENAME} !-f | + | RewriteRule ^index\.php$ - [L] |
- | RewriteCond %{REQUEST_FILENAME} !-d | + | RewriteCond %{REQUEST_FILENAME} !-f |
- | RewriteRule . /index.php [L] | + | RewriteCond %{REQUEST_FILENAME} !-d |
+ | RewriteRule . /index.php [L] | ||
+ | < | ||
+ | Header set Timing-Allow-Origin " | ||
+ | </ | ||
</ | </ | ||
- | # END WordPress | ||
- | Visit wordpress site and configure by opening a web browser of your choice and entering site1.com and site2.com in separate tabs. | + | < |
+ | Header always set X-Content-Type-Options " | ||
+ | < | ||
+ | SetEnvIf Origin "^(.+)$" CORS=$0 | ||
+ | </ | ||
+ | Header set Access-Control-Allow-Origin %{CORS}e env=CORS | ||
+ | Header set Access-Control-Allow-Credentials " | ||
+ | < | ||
+ | Header set X-Frame-Options " | ||
+ | Header set X-XSS-Protection " | ||
+ | Header set X-Download-Options " | ||
+ | Header set X-Permitted-Cross-Domain-Policies " | ||
+ | Header set X-DNS-Prefetch-Control " | ||
+ | Header set Pragma " | ||
+ | Header set Age " | ||
+ | Header set Cache-Control "" | ||
+ | Header set Strict-Transport-Security " | ||
+ | Header set Referrer-Policy "" | ||
+ | Header set Cross-Origin-Embedder-Policy " | ||
+ | Header set Cross-Origin-Opener-Policy " | ||
+ | Header set Report-To ' | ||
+ | Header set Content-Security-Policy " | ||
+ | Header set Referrer-Policy " | ||
+ | Header set Feature-Policy " | ||
+ | </ | ||
+ | </ | ||
- | localhost | + | Personally, I don't think anyone should be using ftp. Sftp is fine, and if someone needs that, here's an example of a simple sftp server using proftp: |
- | Add Joomla, symlinks, directory permissions for low hanging fruit on WP, | + | sudo apt install proftpd ftp ftp-ssl |
+ | sudo a2enmod tls | ||
+ | cd / | ||
+ | sudo openssl req -new -x509 -days 7305 -nodes -out ftpd-rsa.pem -keyout ftpd-rsa-key.pem | ||
+ | sudo nano / | ||
+ | <enter parameters> | ||
| | ||
- | Addenda | + | Next, enter the TLS module in tls.conf underneath ''# |
+ | |||
+ | sudo nano / | ||
+ | < | ||
+ | | ||
+ | | ||
+ | | ||
+ | # Are clients required to use FTP over TLS when talking to this server? | ||
+ | | ||
+ | | ||
+ | | ||
+ | # Authenticate clients that want to use FTP over TLS? | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | sudo systemctl restart proftpd.service | ||
+ | |||
+ | Refresh WordPress and it should see the sftp server and allow you to make changes that way. Note: The sftp server is public and anyone can access this with proper credentials even if it not for WordPress so use a proper password and make sure your TLS configuration is working. Your instance should now be pretty solid. The only other thing you might want is more than one WordPress site subdomain, for example, site1.cooldomain.com, | ||
+ | |||
+ | --- // |