This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| computing:selfhostedwp [2023/06/29 06:15] – oemb1905 | computing:selfhostedwp [2026/04/12 15:53] (current) – oemb1905 | ||
|---|---|---|---|
| Line 13: | Line 13: | ||
| 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:// | 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:// | ||
| - | 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 apt install apache2 mariadb-server php8.4 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 |
| | | ||
| - | 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 as follows: | + | 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 |
| | | ||
| - | sudo apt-get install php8.2-{common, | + | sudo apt-get install php8.4-{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: | 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: | ||
| Line 29: | Line 29: | ||
| | | ||
| sudo apt remove libapache2-mod-php* --purge | sudo apt remove libapache2-mod-php* --purge | ||
| + | sudo apt install php8.4-fpm php8.4-cgi | ||
| sudo a2enmod ssl | sudo a2enmod ssl | ||
| sudo a2enmod headers | sudo a2enmod headers | ||
| sudo a2enmod cache | sudo a2enmod cache | ||
| sudo a2enmod rewrite | sudo a2enmod rewrite | ||
| - | sudo a2enmod setenvif | + | sudo a2enmod setenvif |
| + | sudo a2dismod php8.1 | ||
| sudo a2dismod php8.2 | sudo a2dismod php8.2 | ||
| + | sudo a2dismod php8.3 | ||
| sudo a2dismod mpm_prefork | sudo a2dismod mpm_prefork | ||
| sudo a2enmod mpm_event | sudo a2enmod mpm_event | ||
| sudo a2enmod proxy | sudo a2enmod proxy | ||
| sudo a2enmod proxy_fcgi | sudo a2enmod proxy_fcgi | ||
| - | sudo a2enconf php8.2-fpm | + | sudo a2enconf php8.4-fpm |
| - | sudo a2enconf php8.2-cgi | + | sudo a2enconf php8.4-cgi |
| sudo apache2ctl configtest | sudo apache2ctl configtest | ||
| sudo systemctl restart apache2 | sudo systemctl restart apache2 | ||
| - | sudo systemctl restart php8.2-fpm | + | sudo systemctl restart php8.4-fpm |
| There are two standard ways to configure php-fpm. One of those is to use ProxyPassReverse, | There are two standard ways to configure php-fpm. One of those is to use ProxyPassReverse, | ||
| < | < | ||
| - | SetHandler " | + | SetHandler " |
| </ | </ | ||
| Line 97: | Line 100: | ||
| Let's now shell into our instance and set up WordPress. | Let's now shell into our instance and set up WordPress. | ||
| - | ssh root@wordpress.com | + | ssh root@site1.com |
| - | mkdir Downloads | + | |
| - | cd ~/ | + | |
| - | mkdir wpdownload | + | |
| - | cd wpdownload | + | |
| curl -O https:// | curl -O https:// | ||
| tar xzvf latest.tar.gz | tar xzvf latest.tar.gz | ||
| - | | + | |
| - | sudo chmod 640 ~/Downloads/ | + | |
| - | cp ~/Downloads/ | + | |
| - | | + | |
| Okay, we will need the files and directories I created once we get it running. | Okay, we will need the files and directories I created once we get it running. | ||
| sudo mv ~/ | sudo mv ~/ | ||
| - | When the website is in production, use these permissions: | + | Now, create proper |
| - | sudo chown -R www-data: | + | sudo chown -R www-data: |
| sudo find / | sudo find / | ||
| sudo chmod 755 / | sudo chmod 755 / | ||
| Line 144: | Line 140: | ||
| After isntalling memcached and enabling those modules, navigate to your web root and adjust your .htaccess as follows: | After isntalling memcached and enabling those modules, navigate to your web root and adjust your .htaccess as follows: | ||
| - | | + | < |
| - | ExpiresActive On | + | < |
| - | ExpiresByType image/jpg " | + | ExpiresActive On |
| - | ExpiresByType image/jpeg " | + | ExpiresByType image/jpg " |
| - | ExpiresByType image/gif " | + | ExpiresByType image/jpeg " |
| - | ExpiresByType image/png " | + | ExpiresByType image/gif " |
| - | ExpiresByType text/css " | + | ExpiresByType image/png " |
| - | ExpiresByType text/html " | + | ExpiresByType text/css " |
| - | ExpiresByType text/ | + | ExpiresByType text/html " |
| - | ExpiresDefault " | + | ExpiresByType text/ |
| - | </ | + | ExpiresDefault " |
| + | </ | ||
| + | </code> | ||
| - | | + | < |
| - | RewriteEngine On | + | < |
| - | RewriteRule .* - [E=HTTP_AUTHORIZATION: | + | RewriteEngine On |
| - | RewriteBase / | + | RewriteRule .* - [E=HTTP_AUTHORIZATION: |
| - | RewriteRule ^index\.php$ - [L] | + | RewriteBase / |
| - | 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 " | + | < |
| - | </ | + | Header set Timing-Allow-Origin " |
| - | </ | + | </ |
| + | </ | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | < | ||
| + | # X-origin core security headers | ||
| + | Header always set X-Content-Type-Options " | ||
| + | Header always set X-Frame-Options " | ||
| + | Header always set Referrer-Policy " | ||
| + | # HSTS | ||
| + | Header always set Strict-Transport-Security " | ||
| + | # Feature Policy | ||
| + | Header always set Permissions-Policy " | ||
| + | # Cross Origin Openerand Embedder policies permissive for Gutenberg/ | ||
| + | Header always set Cross-Origin-Opener-Policy " | ||
| + | Header always set Cross-Origin-Embedder-Policy " | ||
| + | # Cache and download protections; | ||
| + | < | ||
| + | Header set X-Download-Options " | ||
| + | Header set X-Permitted-Cross-Domain-Policies " | ||
| + | Header set Pragma " | ||
| + | Header set Cache-Control " | ||
| + | </ | ||
| + | # Safe CSP for WordPress + Gutenberg | ||
| + | < | ||
| + | Header set Content-Security-Policy " | ||
| + | script-src ' | ||
| + | style-src ' | ||
| + | img-src ' | ||
| + | font-src ' | ||
| + | connect-src ' | ||
| + | frame-src ' | ||
| + | media-src ' | ||
| + | object-src ' | ||
| + | base-uri ' | ||
| + | form-action ' | ||
| + | upgrade-insecure-requests;" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | I was getting a stubborn TLS redirect error for images. To address this, I went into ''/ | ||
| + | |||
| + | /** added this to secure images **/ | ||
| + | <meta http-equiv=" | ||
| - | < | ||
| - | Header always set X-Content-Type-Options " | ||
| - | < | ||
| - | SetEnvIf Origin " | ||
| - | </ | ||
| - | 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 " | ||
| - | </ | ||
| - | </ | ||
| - | 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: | + | 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. Note: you can also just use ssh nowadays as openssh-server includes a ready made sftp server. I retain this for historical knowledge. |
| sudo apt install proftpd ftp ftp-ssl | sudo apt install proftpd ftp ftp-ssl | ||
| Line 224: | Line 241: | ||
| 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, | 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, | ||
| - | --- //[[jonathan@haacksnetworking.org|oemb1905]] | + | --- //[[alerts@haacksnetworking.org|oemb1905]] |