DOCS-1: Init document work
This commit is contained in:
164
content/wordpress/install-shared.md
Normal file
164
content/wordpress/install-shared.md
Normal file
@@ -0,0 +1,164 @@
|
||||
---
|
||||
title: "Install WordPress on Shared Hosting"
|
||||
description: "Install WordPress on Arcline shared hosting with cPanel — from one-click installers to manual setup and WordPress Toolkit."
|
||||
section: wordpress
|
||||
order: 1
|
||||
---
|
||||
|
||||
# Install WordPress on Shared Hosting
|
||||
|
||||
WordPress can be installed on Arcline shared hosting in a few minutes. This covers the one-click installer (fastest), the manual method (for full control), and WordPress Toolkit (for managing multiple sites).
|
||||
|
||||
---
|
||||
|
||||
## Option 1 — Softaculous one-click installer (recommended)
|
||||
|
||||
Softaculous is included with every Arcline cPanel account. It installs WordPress with one click and lets you choose the install location, admin credentials, and all settings upfront.
|
||||
|
||||
1. cPanel → **Software → WordPress Manager by Softaculous**
|
||||
2. Click **Install** at the top
|
||||
3. Fill in the form:
|
||||
|
||||
| Field | What to enter |
|
||||
|---|---|
|
||||
| Choose Protocol | `https://` (recommended) or `https://www.` |
|
||||
| Choose Domain | your domain from the dropdown |
|
||||
| In Directory | leave blank (for the root of your domain) or enter a subdirectory like `blog` |
|
||||
| Site Name | your site's title (can be changed later) |
|
||||
| Site Description | short tagline (optional) |
|
||||
| Admin Username | pick a unique username — **not** `admin` |
|
||||
| Admin Password | use a strong password or click the key icon to generate one |
|
||||
| Admin Email | your email address |
|
||||
|
||||
Scroll down and click **Install**. WordPress is ready in under a minute.
|
||||
|
||||
> Do not use `admin` as your username — it's the most targeted name for brute-force attacks. Pick something unique.
|
||||
|
||||
---
|
||||
|
||||
## Option 2 — Manual install
|
||||
|
||||
A manual install gives you full control over file placement, database setup, and the initial configuration.
|
||||
|
||||
### Step 1 — Create a database
|
||||
|
||||
1. cPanel → **Databases → MySQL Databases**
|
||||
2. Under **Create New Database**, enter a name (e.g., `wp_yoursite`) and click **Create Database**
|
||||
3. Under **Add New User**, create a user with a strong password
|
||||
4. Under **Add User To Database**, select the user and database, then click **Add**
|
||||
5. Check **All Privileges** and click **Make Changes**
|
||||
|
||||
Write down the database name, username, and password.
|
||||
|
||||
### Step 2 — Upload WordPress
|
||||
|
||||
1. Download the latest WordPress `.zip` from [wordpress.org](https://wordpress.org/download/)
|
||||
2. cPanel → **Files → File Manager**
|
||||
3. Navigate to `public_html` (or the subdirectory where you want WordPress)
|
||||
4. Click **Upload**, select the `.zip`, and wait for it to finish
|
||||
5. In File Manager, select the uploaded `.zip` and click **Extract**
|
||||
6. Move the extracted `wordpress/` folder contents into `public_html/` (or keep it in a subdirectory)
|
||||
7. Delete the `.zip` file and the now-empty `wordpress/` folder
|
||||
|
||||
### Step 3 — Run the installer
|
||||
|
||||
1. Visit `https://yourdomain.com` in your browser
|
||||
2. WordPress will detect no config file and show the setup screen
|
||||
3. Click **Let's go!**, then enter your database details:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Database Name | the database you created in Step 1 |
|
||||
| Username | the database user you created |
|
||||
| Password | the database user's password |
|
||||
| Database Host | `localhost` |
|
||||
| Table Prefix | `wp_` (default is fine, or change it for extra security) |
|
||||
|
||||
4. Click **Submit** → **Run the installation**
|
||||
5. Fill in the site info: site title, admin username (not `admin`), password, and your email
|
||||
6. Click **Install WordPress**
|
||||
|
||||
---
|
||||
|
||||
## Option 3 — WordPress Toolkit (for multiple sites)
|
||||
|
||||
WordPress Toolkit is included in cPanel and is ideal if you manage several WordPress sites on one account.
|
||||
|
||||
1. cPanel → **Software → WordPress Toolkit**
|
||||
2. Click **Install**
|
||||
3. Choose your domain, directory, and basic settings
|
||||
4. Click **Install**
|
||||
|
||||
After installation, WordPress Toolkit lets you:
|
||||
- Clone a site to a subdomain or another domain
|
||||
- Create staging sites (copy production to a test area)
|
||||
- Run WordPress, plugin, and theme updates from one screen
|
||||
- Reset passwords and toggle debug mode without logging into WordPress
|
||||
|
||||
---
|
||||
|
||||
## After installation
|
||||
|
||||
### Enable SSL
|
||||
|
||||
Your site should use HTTPS immediately. cPanel's AutoSSL will issue a certificate within a few minutes of installation. If it doesn't:
|
||||
|
||||
1. cPanel → **Security → SSL/TLS Status**
|
||||
2. Click **Run AutoSSL**
|
||||
3. Wait a few minutes and refresh
|
||||
|
||||
Once the certificate is issued, install **Really Simple SSL** in WordPress to automatically redirect HTTP to HTTPS and fix mixed content.
|
||||
|
||||
### Update permalinks
|
||||
|
||||
WordPress's default permalink structure (`?p=123`) is bad for SEO and usability. Change it immediately:
|
||||
|
||||
1. WordPress admin → **Settings → Permalinks**
|
||||
2. Choose **Post name** (the most common and SEO-friendly option)
|
||||
3. Click **Save Changes**
|
||||
|
||||
If you see a 404 error after switching permalinks, WordPress couldn't write to `.htaccess`. Copy the code WordPress shows at the bottom of the Permalinks page and paste it manually into `.htaccess` in File Manager.
|
||||
|
||||
### Install essential plugins
|
||||
|
||||
Start with these free plugins (install after you've confirmed the site works):
|
||||
|
||||
- **Really Simple SSL** — handles HTTPS redirect and mixed content
|
||||
- **Wordfence Security** — firewall, malware scanner, and login protection
|
||||
- **UpdraftPlus** — automated backups to remote storage (Google Drive, Dropbox, etc.)
|
||||
|
||||
### Set up automated backups
|
||||
|
||||
Don't rely on manual backups. Configure UpdraftPlus to run daily backups to off-server storage. See [Back Up and Restore a MySQL Database](/getting-started/mysql-backup/) for database backup details.
|
||||
|
||||
---
|
||||
|
||||
## Installing in a subdirectory
|
||||
|
||||
If you want WordPress at `https://yourdomain.com/blog/` rather than the root of your domain:
|
||||
|
||||
1. In Softaculous or during manual setup, enter `blog` as the directory
|
||||
2. WordPress files go into `public_html/blog/`
|
||||
3. Your homepage at `yourdomain.com` can be a static site or an HTML landing page
|
||||
|
||||
This is a common setup when your main site is not WordPress (e.g., a static business site with a separate blog).
|
||||
|
||||
---
|
||||
|
||||
## Common setup issues
|
||||
|
||||
**Error establishing a database connection** — the database credentials in `wp-config.php` don't match what you created in cPanel. Double-check the database name, username, and password. Note that all three are prefixed with your cPanel username (e.g., `cpaneluser_wp_yoursite`).
|
||||
|
||||
**White screen after install** — a PHP error. Enable debugging temporarily by adding this to `wp-config.php`:
|
||||
|
||||
```php
|
||||
define( 'WP_DEBUG', true );
|
||||
define( 'WP_DEBUG_LOG', true );
|
||||
```
|
||||
|
||||
Check `wp-content/debug.log` for the specific error. Remove or set to `false` after debugging.
|
||||
|
||||
**Can't upload files** — the `wp-content/uploads/` directory may have incorrect permissions. In File Manager, right-click the `uploads` folder and set permissions to **755**. If that doesn't fix it, try **775**.
|
||||
|
||||
**404 on all pages except home** — permalink rules aren't being applied. Go to Settings → Permalinks and click **Save Changes** twice (this forces WordPress to regenerate `.htaccess` rules). If it still doesn't work, check that your `.htaccess` file exists in `public_html/` and is writable.
|
||||
|
||||
341
content/wordpress/install-vps.md
Normal file
341
content/wordpress/install-vps.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
title: "Install WordPress on a VPS"
|
||||
description: "Set up WordPress on your Arcline VPS from scratch — LAMP or LEMP stack with PHP, MySQL, and Nginx or Apache."
|
||||
section: wordpress
|
||||
order: 2
|
||||
---
|
||||
|
||||
# Install WordPress on a VPS
|
||||
|
||||
Installing WordPress on a VPS gives you full control over the server configuration, performance tuning, and security. This guide covers both a LEMP stack (Linux, Nginx, MySQL, PHP-FPM) and a LAMP stack (Linux, Apache, MySQL, PHP).
|
||||
|
||||
If you haven't set up your VPS yet, start with [Initial VPS Setup](/vps/initial-setup/).
|
||||
|
||||
---
|
||||
|
||||
## Choose your stack
|
||||
|
||||
| Stack | Web Server | Best for |
|
||||
|---|---|---|
|
||||
| **LEMP** | Nginx + PHP-FPM | High traffic, static caching, modern setups |
|
||||
| **LAMP** | Apache + PHP | Simpler `.htaccess` support, beginner-friendly |
|
||||
|
||||
This guide covers the LEMP stack (Nginx) as the primary setup with LAMP (Apache) notes where they differ.
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Install the stack
|
||||
|
||||
### LEMP (Nginx)
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y nginx mysql-server php-fpm php-mysql php-curl php-gd \
|
||||
php-mbstring php-xml php-zip php-intl php-imagick unzip curl
|
||||
```
|
||||
|
||||
### LAMP (Apache)
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y apache2 mysql-server php libapache2-mod-php php-mysql \
|
||||
php-curl php-gd php-mbstring php-xml php-zip php-intl php-imagick unzip curl
|
||||
```
|
||||
|
||||
### Secure MySQL and create the database
|
||||
|
||||
```bash
|
||||
sudo mysql_secure_installation
|
||||
```
|
||||
|
||||
Follow the prompts — set a root password, remove anonymous users, disallow remote root login, remove test databases, and reload privileges.
|
||||
|
||||
Now create the WordPress database and user:
|
||||
|
||||
```bash
|
||||
sudo mysql -u root -p
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'a-strong-password-here';
|
||||
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
Replace `a-strong-password-here` with an actual strong password.
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Download and set up WordPress
|
||||
|
||||
```bash
|
||||
cd /tmp
|
||||
curl -O https://wordpress.org/latest.tar.gz
|
||||
tar xzf latest.tar.gz
|
||||
sudo mv wordpress /var/www/yourdomain.com
|
||||
sudo chown -R www-data:www-data /var/www/yourdomain.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Configure Nginx (LEMP)
|
||||
|
||||
Create the Nginx site configuration:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/yourdomain.com
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
root /var/www/yourdomain.com;
|
||||
index index.php index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
# Block access to sensitive files
|
||||
location ~* /\.(?!well-known\/) { deny all; }
|
||||
location ~* /wp-config\.php { deny all; }
|
||||
location ~* /xmlrpc\.php { deny all; }
|
||||
|
||||
# Cache static assets in the browser
|
||||
location ~* \.(css|js|ico|gif|jpg|jpeg|png|webp|svg|woff2?|ttf|otf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Enable the site and test the config:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
Replace `php8.1-fpm.sock` with the PHP version you installed. Check your PHP version:
|
||||
|
||||
```bash
|
||||
php -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3 (alt) — Configure Apache (LAMP)
|
||||
|
||||
```bash
|
||||
sudo nano /etc/apache2/sites-available/yourdomain.com.conf
|
||||
```
|
||||
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName yourdomain.com
|
||||
ServerAlias www.yourdomain.com
|
||||
DocumentRoot /var/www/yourdomain.com
|
||||
|
||||
<Directory /var/www/yourdomain.com>
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
Enable and restart:
|
||||
|
||||
```bash
|
||||
sudo a2ensite yourdomain.com.conf
|
||||
sudo a2enmod rewrite
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Set up SSL with Let's Encrypt
|
||||
|
||||
```bash
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
|
||||
```
|
||||
|
||||
For Apache, use `python3-certbot-apache` instead.
|
||||
|
||||
Certbot modifies your Nginx/Apache config to add SSL automatically. Certificates renew automatically via a systemd timer — verify with:
|
||||
|
||||
```bash
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Complete the WordPress install
|
||||
|
||||
Visit `https://yourdomain.com` in your browser and complete the WordPress setup wizard. When prompted for database credentials, enter:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Database Name | `wordpress` |
|
||||
| Username | `wpuser` |
|
||||
| Password | the password you set in Step 1 |
|
||||
| Database Host | `localhost` |
|
||||
| Table Prefix | `wp_` |
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — Configure file permissions
|
||||
|
||||
WordPress needs write access to `wp-content/uploads` (for media) but the rest of your install should be read-only for the web server to prevent tampering.
|
||||
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/yourdomain.com
|
||||
sudo find /var/www/yourdomain.com -type d -exec chmod 755 {} \;
|
||||
sudo find /var/www/yourdomain.com -type f -exec chmod 644 {} \;
|
||||
sudo chmod 640 /var/www/yourdomain.com/wp-config.php
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7 — Configure PHP-FPM for WordPress
|
||||
|
||||
Edit the PHP-FPM pool config:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
|
||||
```
|
||||
|
||||
Increase resource limits for a production WordPress site:
|
||||
|
||||
```ini
|
||||
pm = dynamic
|
||||
pm.max_children = 20
|
||||
pm.start_servers = 5
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 10
|
||||
pm.max_requests = 500
|
||||
```
|
||||
|
||||
Adjust `pm.max_children` based on your VPS RAM: roughly `(available_RAM - 512MB) / 50MB` per child.
|
||||
|
||||
Apply changes:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart php8.1-fpm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 8 — Set up a firewall
|
||||
|
||||
```bash
|
||||
sudo ufw allow 22/tcp
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
For stricter security, see [Set up fail2ban](/vps/fail2ban/).
|
||||
|
||||
---
|
||||
|
||||
## Step 9 — Configure WordPress cron properly
|
||||
|
||||
WordPress's default pseudo-cron runs on every page load, which is wasteful on a VPS. Replace it with a real system cron job:
|
||||
|
||||
```bash
|
||||
sudo crontab -u www-data -e
|
||||
```
|
||||
|
||||
Add:
|
||||
|
||||
```
|
||||
*/5 * * * * /usr/bin/php /var/www/yourdomain.com/wp-cron.php > /dev/null 2>&1
|
||||
```
|
||||
|
||||
Then disable WordPress pseudo-cron in `wp-config.php`:
|
||||
|
||||
```php
|
||||
define( 'DISABLE_WP_CRON', true );
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance tuning
|
||||
|
||||
### PHP opcache
|
||||
|
||||
Uncomment and tweak in `/etc/php/8.1/fpm/php.ini`:
|
||||
|
||||
```ini
|
||||
opcache.enable=1
|
||||
opcache.memory_consumption=256
|
||||
opcache.interned_strings_buffer=16
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=2
|
||||
opcache.fast_shutdown=1
|
||||
```
|
||||
|
||||
### MySQL tuning
|
||||
|
||||
For a 2 GB VPS, add to `/etc/mysql/mysql.conf.d/mysqld.cnf`:
|
||||
|
||||
```ini
|
||||
innodb_buffer_pool_size = 512M
|
||||
innodb_log_file_size = 128M
|
||||
query_cache_type = 0
|
||||
```
|
||||
|
||||
Run MySQLTuner after a few days of uptime for more specific recommendations:
|
||||
|
||||
```bash
|
||||
sudo apt install mysqltuner
|
||||
sudo mysqltuner
|
||||
```
|
||||
|
||||
### WordPress object caching with Redis
|
||||
|
||||
If your VPS has enough RAM (2 GB+ free), Redis dramatically speeds up WordPress:
|
||||
|
||||
```bash
|
||||
sudo apt install redis-server
|
||||
sudo systemctl enable redis-server
|
||||
```
|
||||
|
||||
Install the **Redis Object Cache** plugin in WordPress admin and click **Enable Object Cache**.
|
||||
|
||||
---
|
||||
|
||||
## Automating updates
|
||||
|
||||
Set up unattended security updates for the OS:
|
||||
|
||||
```bash
|
||||
sudo apt install unattended-upgrades
|
||||
sudo dpkg-reconfigure unattended-upgrades
|
||||
```
|
||||
|
||||
WordPress core auto-updates are enabled by default for minor versions. For plugins and themes, enable auto-updates in WordPress admin → Plugins → toggle **Enable auto-updates** on each plugin you trust.
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Configure W3 Total Cache](/wordpress/w3-total-cache/) for page caching and performance
|
||||
- [WordPress security hardening](/wordpress/security/) — tighten file permissions, disable XML-RPC, and set up login protection
|
||||
- [Automated backups with restic](/vps/restic-backups/) for off-site backups of your files and database
|
||||
|
||||
203
content/wordpress/security.md
Normal file
203
content/wordpress/security.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
title: "WordPress Security Hardening"
|
||||
description: "Lock down your WordPress site on Arcline — file permissions, login protection, XML-RPC hardening, and no third-party CDN required."
|
||||
section: wordpress
|
||||
order: 4
|
||||
---
|
||||
|
||||
# WordPress Security Hardening
|
||||
|
||||
Most WordPress compromises happen through outdated plugins or weak passwords — not through server vulnerabilities. These steps harden a standard WordPress install on Arcline against the most common attacks.
|
||||
|
||||
---
|
||||
|
||||
## Keep everything updated
|
||||
|
||||
The single most effective security measure is updating WordPress core, plugins, and themes promptly. Every Arcline cPanel account includes:
|
||||
|
||||
- **WordPress Toolkit** (cPanel → Software) — shows update status for all your WordPress sites at a glance. Click **Update** to apply security patches across all sites in one go.
|
||||
- **Softaculous** — can auto-update WordPress core. Go to Softaculous → **WordPress Manager → Settings** and enable auto-updates.
|
||||
|
||||
In WordPress admin, enable auto-updates for plugins and themes you trust. Go to **Plugins → Installed Plugins** and click **Enable auto-updates** next to each plugin.
|
||||
|
||||
---
|
||||
|
||||
## File permissions
|
||||
|
||||
WordPress files should be readable by the web server but not writable by anyone other than your cPanel user. Incorrect permissions are the most common way an attacker who gains access through a plugin vulnerability escalates to full site takeover.
|
||||
|
||||
Via cPanel **File Manager** or SFTP:
|
||||
|
||||
- **Directories:** `755` (rwxr-xr-x)
|
||||
- **Files:** `644` (rw-r--r--)
|
||||
- **wp-config.php:** `640` or `600` — the most sensitive file in your install
|
||||
- **wp-content/uploads/:** `755` — must be writable for media uploads
|
||||
|
||||
To fix permissions via SSH:
|
||||
|
||||
```bash
|
||||
find /home/username/public_html -type d -exec chmod 755 {} \;
|
||||
find /home/username/public_html -type f -exec chmod 644 {} \;
|
||||
chmod 640 /home/username/public_html/wp-config.php
|
||||
```
|
||||
|
||||
Run these as your cPanel user — not as root.
|
||||
|
||||
---
|
||||
|
||||
## Block XML-RPC
|
||||
|
||||
XML-RPC is a legacy API that's almost never needed by modern WordPress sites. It's heavily abused for brute-force attacks and DDoS amplification. Most sites can disable it entirely.
|
||||
|
||||
**Via .htaccess** (shared hosting):
|
||||
|
||||
```apache
|
||||
<Files xmlrpc.php>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
```
|
||||
|
||||
**Via Nginx** (VPS) — add to your site config:
|
||||
|
||||
```nginx
|
||||
location = /xmlrpc.php { deny all; }
|
||||
```
|
||||
|
||||
**Plugins that need XML-RPC** (don't disable it if you use these):
|
||||
- Jetpack (some features)
|
||||
- The WordPress mobile app
|
||||
- Trackbacks and pingbacks (disabled anyway on most sites)
|
||||
|
||||
If you use the WordPress mobile app, you need XML-RPC. For everyone else, disabling it has no downside.
|
||||
|
||||
---
|
||||
|
||||
## Protect wp-config.php
|
||||
|
||||
`wp-config.php` contains your database credentials. Anyone who reads this file owns your database.
|
||||
|
||||
**.htaccess** protection (add at the top of `.htaccess`):
|
||||
|
||||
```apache
|
||||
<Files wp-config.php>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
```
|
||||
|
||||
For defense in depth, move `wp-config.php` one directory **above** `public_html` — WordPress looks there automatically. If it's currently at `/home/username/public_html/wp-config.php`, move it to `/home/username/wp-config.php`. WordPress will find it.
|
||||
|
||||
---
|
||||
|
||||
## Disable file editing from the admin panel
|
||||
|
||||
By default, any WordPress administrator can edit theme and plugin files directly from the admin panel. If an attacker compromises an admin account, this lets them inject arbitrary PHP code and take over the entire server.
|
||||
|
||||
Add to `wp-config.php`:
|
||||
|
||||
```php
|
||||
define( 'DISALLOW_FILE_EDIT', true );
|
||||
```
|
||||
|
||||
This removes the **Appearance → Theme File Editor** and **Plugins → Plugin File Editor** menu items for everyone. You'll make file changes via SFTP or cPanel File Manager instead.
|
||||
|
||||
---
|
||||
|
||||
## Disable plugin and theme installation from the admin panel (advanced)
|
||||
|
||||
On a production site where you manage installations through SFTP, you can completely disable the ability to install plugins and themes from the admin panel:
|
||||
|
||||
```php
|
||||
define( 'DISALLOW_FILE_MODS', true );
|
||||
```
|
||||
|
||||
This blocks plugin/theme installs, updates, and deletions from the WordPress admin. Updates must be done via WP-CLI, WordPress Toolkit, or manually via SFTP. This is aggressive but very effective — it's a trade-off between convenience and security.
|
||||
|
||||
---
|
||||
|
||||
## Limit login attempts
|
||||
|
||||
WordPress has no built-in rate limiting on the login page, so attackers can try thousands of passwords without restriction.
|
||||
|
||||
Install **Wordfence Security** (free) or **Limit Login Attempts Reloaded**. Both block IPs after a configurable number of failed attempts.
|
||||
|
||||
**Wordfence settings:**
|
||||
- **Wordfence → Firewall → Brute Force Protection**
|
||||
- Set **Lock out after how many login failures** to `5`
|
||||
- Set **Lock out after how many forgot password attempts** to `5`
|
||||
- Set **Amount of time a user is locked out** to `1 hour`
|
||||
|
||||
Wordfence also includes a web application firewall (WAF) that blocks common WordPress attacks before they reach your site — enable it from the Wordfence dashboard.
|
||||
|
||||
---
|
||||
|
||||
## Use strong authentication
|
||||
|
||||
**Strong passwords** — use the password generator built into WordPress. A password like `myfavoritecat` is trivial to crack; a random one like `8*kF$2nP!xq` is effectively unbreakable.
|
||||
|
||||
**Two-factor authentication (2FA)** — install **Wordfence Login Security** (free, from the same developer as Wordfence Security) or **Two Factor** (official WordPress plugin). Both support TOTP (Google Authenticator, Authy, etc.) and backup codes.
|
||||
|
||||
**Change the default admin username** — never use `admin`, `administrator`, `root`, or your domain name as the admin username. If you already have an `admin` user, create a new administrator account with a unique username, log in with it, and delete the old `admin` account.
|
||||
|
||||
---
|
||||
|
||||
## Hide WordPress version
|
||||
|
||||
Every WordPress install outputs its version number by default, making it easy for attackers to target known vulnerabilities. Remove it with your security plugin (Wordfence → All Options → **Hide WordPress version**) or by adding a filter:
|
||||
|
||||
```php
|
||||
remove_action( 'wp_head', 'wp_generator' );
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Disable directory listing
|
||||
|
||||
If someone visits `https://yourdomain.com/wp-content/uploads/` directly, they should see a blank page or redirect — not a list of every file in the directory.
|
||||
|
||||
Add to `.htaccess`:
|
||||
|
||||
```apache
|
||||
Options -Indexes
|
||||
```
|
||||
|
||||
Arcline shared hosting has this enabled by default. Verify by visiting `https://yourdomain.com/wp-includes/` in your browser — you should see a 403 Forbidden, not a file list.
|
||||
|
||||
---
|
||||
|
||||
## Change the database table prefix
|
||||
|
||||
The default WordPress table prefix is `wp_`. Changing it to something random makes SQL injection attacks harder — the attacker has to guess your table names.
|
||||
|
||||
**For new installs:** change the prefix during installation when WordPress asks for it.
|
||||
|
||||
**For existing sites:** use the **Brozzme DB Prefix** plugin or do it manually (requires editing `wp-config.php` and renaming all database tables — not recommended unless you're comfortable with MySQL).
|
||||
|
||||
---
|
||||
|
||||
## Disable unused user enumeration
|
||||
|
||||
By default, visiting `https://yourdomain.com/?author=1` reveals the admin username in the URL or redirect. Attackers use this to collect usernames for brute-force attacks.
|
||||
|
||||
Block it with Wordfence (enabled by default) or add to your theme's `functions.php`:
|
||||
|
||||
```php
|
||||
if ( ! is_admin() && isset( $_SERVER['QUERY_STRING'] ) ) {
|
||||
if ( preg_match( '/author=([0-9]*)/', $_SERVER['QUERY_STRING'] ) ) {
|
||||
wp_redirect( home_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backup before you harden
|
||||
|
||||
Some security changes can break things. Before making any significant changes:
|
||||
|
||||
1. Take a full cPanel backup (cPanel → **Files → Backup**)
|
||||
2. Export your database separately (see [Back Up and Restore a MySQL Database](/getting-started/mysql-backup/))
|
||||
3. Test changes one at a time so you know which one caused a problem if something breaks
|
||||
|
||||
196
content/wordpress/w3-total-cache.md
Normal file
196
content/wordpress/w3-total-cache.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
title: "Configure W3 Total Cache Without a CDN"
|
||||
description: "Speed up your WordPress site with W3 Total Cache on Arcline — page caching, browser caching, and opcode caching without third-party CDNs."
|
||||
section: wordpress
|
||||
order: 3
|
||||
---
|
||||
|
||||
# Configure W3 Total Cache Without a CDN
|
||||
|
||||
W3 Total Cache (W3TC) is a free WordPress caching plugin that speeds up your site by storing pre-rendered pages, compressing assets, and leveraging browser caching. This guide configures W3TC for good performance **without** a third-party CDN — everything runs on your Arcline server.
|
||||
|
||||
---
|
||||
|
||||
## Why no CDN?
|
||||
|
||||
CDNs add a third party between your visitors and your server. You may not need one:
|
||||
|
||||
- Arcline servers are fast and colocated in well-connected data centers
|
||||
- A properly cached WordPress site on Arcline loads in under a second for most visitors
|
||||
- CDNs introduce an additional cost, privacy concern, and point of failure
|
||||
|
||||
If you do want CDN coverage later, W3TC supports Cloudflare, BunnyCDN, and generic pull CDNs — but you don't need one to get started.
|
||||
|
||||
---
|
||||
|
||||
## Install W3 Total Cache
|
||||
|
||||
1. WordPress admin → **Plugins → Add New**
|
||||
2. Search for "W3 Total Cache"
|
||||
3. Click **Install Now** → **Activate**
|
||||
|
||||
The plugin adds a **Performance** menu to the sidebar. All configuration lives there.
|
||||
|
||||
---
|
||||
|
||||
## Page cache (most important)
|
||||
|
||||
Page caching saves fully rendered HTML pages so WordPress doesn't process PHP and query the database for every request. A cached page is served in milliseconds.
|
||||
|
||||
1. **Performance → General Settings**
|
||||
2. Under **Page Cache**, check **Enable**
|
||||
3. Set **Page Cache Method** to **Disk: Enhanced**
|
||||
4. Click **Save all settings**
|
||||
|
||||
**Disk: Enhanced** writes static `.html` files to the cache directory and serves them directly via `.htaccess` or Nginx rules — WordPress isn't even loaded for cached pages. This is the fastest option that doesn't require extra server software.
|
||||
|
||||
### Verify it's working
|
||||
|
||||
Visit your site in an incognito window (so you're not logged in as admin) and view the page source. Scroll to the bottom — you should see:
|
||||
|
||||
```html
|
||||
<!-- Performance optimized by W3 Total Cache. Page Caching using disk: enhanced -->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Browser cache
|
||||
|
||||
Browser caching tells visitors' browsers to store images, CSS, and JavaScript files locally so they don't re-download on every page view.
|
||||
|
||||
1. **Performance → General Settings**
|
||||
2. Under **Browser Cache**, check **Enable**
|
||||
3. Click **Save all settings**
|
||||
|
||||
Then configure each section:
|
||||
|
||||
**Performance → Browser Cache → CSS & JS:**
|
||||
- Set **Expires header lifetime** to `31536000` seconds (1 year)
|
||||
- Check **Set cache control header**
|
||||
- Set **Cache Control policy** to `cache with max-age`
|
||||
|
||||
**Performance → Browser Cache → HTML & XML:**
|
||||
- Set **Expires header lifetime** to `3600` seconds (1 hour)
|
||||
- Check **Set cache control header**
|
||||
- Set **Cache Control policy** to `cache with max-age`
|
||||
|
||||
**Performance → Browser Cache → Media & Other Files:**
|
||||
- Set **Expires header lifetime** to `31536000` seconds (1 year)
|
||||
- **Cache Control policy** to `cache with max-age`
|
||||
|
||||
Click **Save all settings** after each tab.
|
||||
|
||||
---
|
||||
|
||||
## Minify (optional — test carefully)
|
||||
|
||||
Minification reduces file sizes by stripping whitespace and comments from HTML, CSS, and JS. It can improve load times but also **can break your site** if not configured correctly.
|
||||
|
||||
Start with HTML minification only — it's the safest:
|
||||
|
||||
1. **Performance → General Settings → Minify → Enable**
|
||||
2. Set **Minify mode** to **Manual** (not Auto)
|
||||
3. Click **Save all settings**
|
||||
|
||||
Then in **Performance → Minify → HTML & XML:**
|
||||
- Check **Enable** for HTML minify
|
||||
- Leave JS and CSS minify disabled for now
|
||||
- Click **Save all settings**
|
||||
|
||||
Test your site thoroughly. If anything looks wrong, disable minification for that type and try a different combination.
|
||||
|
||||
**If your theme CSS or JS files have incorrect paths after minifying**, you may need to add them to the "Never minify" list in the JS or CSS settings tab.
|
||||
|
||||
---
|
||||
|
||||
## Object cache
|
||||
|
||||
Object caching stores database query results in memory, reducing repeated database queries. On Arcline shared hosting, use **Disk** as the caching method:
|
||||
|
||||
1. **Performance → General Settings → Object Cache → Enable**
|
||||
2. Set **Object Cache Method** to **Disk**
|
||||
3. Click **Save all settings**
|
||||
|
||||
On a VPS with Redis installed, set the method to **Redis** instead and enter `127.0.0.1:6379` as the server. Redis object caching is significantly faster than disk-based caching.
|
||||
|
||||
---
|
||||
|
||||
## Database cache (use on VPS only)
|
||||
|
||||
Database caching stores query results. On shared hosting, it can slow things down if the disk is under load. On a VPS, it helps:
|
||||
|
||||
1. **Performance → General Settings → Database Cache → Enable**
|
||||
2. Set method to **Disk** (or **Redis** on a VPS with Redis)
|
||||
3. Click **Save all settings**
|
||||
|
||||
Skip this on shared hosting unless your site has heavy database usage (WooCommerce, membership sites, forums).
|
||||
|
||||
---
|
||||
|
||||
## Exclude pages from caching
|
||||
|
||||
Some pages should never be cached:
|
||||
|
||||
- **Cart, checkout, and account pages** (for WooCommerce)
|
||||
- **Login and registration pages**
|
||||
- **Admin pages**
|
||||
|
||||
**Performance → Page Cache → Advanced:**
|
||||
|
||||
In the **"Never cache the following pages"** field, add:
|
||||
|
||||
```
|
||||
wp-login.php
|
||||
wp-admin/*
|
||||
cart/*
|
||||
checkout/*
|
||||
my-account/*
|
||||
```
|
||||
|
||||
For WooCommerce specifically, W3TC should detect it and add these automatically. If not, add `/cart/`, `/checkout/`, `/my-account/` individually — one per line.
|
||||
|
||||
---
|
||||
|
||||
## Clear the cache
|
||||
|
||||
You'll need to clear the cache whenever you make significant site changes (new theme, updated plugins, content restructuring):
|
||||
|
||||
- **Performance → Dashboard → Empty all caches**
|
||||
- Or use the admin bar: **Performance → Purge All Caches**
|
||||
|
||||
Set up automatic purging for new posts:
|
||||
|
||||
- **Performance → Page Cache → Purge Policy:**
|
||||
- Check **Front page**, **Posts page**, and **Post page**
|
||||
|
||||
This keeps your cache fresh without manual intervention after publishing new content.
|
||||
|
||||
---
|
||||
|
||||
## Testing your cache setup
|
||||
|
||||
After configuring, test your site's performance:
|
||||
|
||||
1. Visit your site in an incognito window
|
||||
2. Open browser DevTools → Network tab
|
||||
3. Reload the page and check:
|
||||
- **HTML document:** should load in under 200 ms
|
||||
- **CSS/JS files:** should show "304 Not Modified" or "(disk cache)" on second load
|
||||
- **Images:** similar — cached after the first load
|
||||
|
||||
For more detailed testing, use [PageSpeed Insights](https://pagespeed.web.dev) or [GTmetrix](https://gtmetrix.com). Both give specific recommendations for improvement.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Site looks broken after enabling minify** — disable minification for the type that broke (JS, CSS, or HTML). Minify is the most likely setting to cause issues.
|
||||
|
||||
**Logged-in users see stale pages** — W3TC should skip caching for logged-in users by default. Check **Performance → Page Cache → Advanced → "Don't cache pages for logged in users"** is checked.
|
||||
|
||||
**Cache files filling up disk space** — W3TC has garbage collection that runs on WordPress cron. On a busy site, the cache directory can grow. Set a reasonable **Garbage collection interval** in **Performance → Page Cache → Advanced** (the default 3600 seconds / 1 hour is fine).
|
||||
|
||||
**CDN tab references** — ignore everything in the **CDN** settings section. That's for Cloudflare, BunnyCDN, or generic pull CDNs, which this guide intentionally avoids.
|
||||
|
||||
**"Disk: Enhanced" not available** — your server may not support the enhanced mode. Switch to **Disk: Basic** instead, which uses PHP to serve cached pages. It's slightly slower but works everywhere.
|
||||
|
||||
181
content/wordpress/woocommerce.md
Normal file
181
content/wordpress/woocommerce.md
Normal file
@@ -0,0 +1,181 @@
|
||||
---
|
||||
title: "Setting Up WooCommerce on Arcline"
|
||||
description: "Install and configure WooCommerce on your Arcline VPS or shared hosting plan."
|
||||
section: wordpress
|
||||
order: 5
|
||||
---
|
||||
|
||||
# Setting Up WooCommerce on Arcline
|
||||
|
||||
WooCommerce is the most popular e-commerce platform for WordPress. This guide covers installing it on Arcline shared hosting or a VPS and optimizing it for performance without a CDN.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- WordPress installed and running (see [Install WordPress](/wordpress/install-shared/) for shared hosting or [Install WordPress on a VPS](/wordpress/install-vps/) for VPS)
|
||||
- A domain pointed to your Arcline server
|
||||
- SSL certificate installed (Let's Encrypt via cPanel or Certbot)
|
||||
- PHP memory limit of at least 256 MB (512 MB recommended for VPS)
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Install WooCommerce
|
||||
|
||||
### Via the WordPress admin
|
||||
|
||||
1. Log in to your WordPress admin dashboard at `https://yourdomain.com/wp-admin`
|
||||
2. Go to **Plugins → Add New**
|
||||
3. Search for "WooCommerce"
|
||||
4. Click **Install Now** → **Activate**
|
||||
|
||||
WooCommerce will launch the setup wizard on activation.
|
||||
|
||||
### Via WP-CLI (faster, especially on a VPS)
|
||||
|
||||
```bash
|
||||
# Install and activate WooCommerce
|
||||
wp plugin install woocommerce --activate
|
||||
|
||||
# Install a recommended theme (e.g., Storefront)
|
||||
# wp theme install storefront --activate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Run the setup wizard
|
||||
|
||||
The WooCommerce setup wizard will walk you through:
|
||||
|
||||
1. **Store location**: Set your business address, currency (USD), and selling location
|
||||
2. **Industry**: What types of products you sell (physical, digital, membership, etc.)
|
||||
3. **Product types**: Simple products, variable products, external/affiliate products
|
||||
4. **Business details**: Whether you're already selling elsewhere
|
||||
5. **Payment methods**: WooPayments, PayPal, Stripe, or offline payments
|
||||
6. **Shipping**: Set up shipping zones and rates
|
||||
7. **Tax**: Configure basic tax settings
|
||||
8. **Personalize**: Choose a theme and install free extensions
|
||||
|
||||
You can skip any step and configure it later.
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Choose payment methods
|
||||
|
||||
### WooPayments (built-in, recommended)
|
||||
|
||||
WooPayments is Stripe-based and included with WooCommerce. It accepts credit cards, Apple Pay, and Google Pay. No additional plugin is needed.
|
||||
|
||||
To set it up:
|
||||
1. Go to **WooCommerce → Settings → Payments**
|
||||
2. Click **Set up** next to WooPayments
|
||||
3. Follow the prompts to connect your Stripe account
|
||||
|
||||
### PayPal
|
||||
|
||||
1. Go to **WooCommerce → Settings → Payments**
|
||||
2. Toggle **PayPal** on
|
||||
3. Click **Set up** and enter your PayPal email address
|
||||
|
||||
### Stripe (standalone plugin)
|
||||
|
||||
If you prefer the standalone Stripe plugin instead of WooPayments:
|
||||
|
||||
```bash
|
||||
wp plugin install woocommerce-gateway-stripe --activate
|
||||
```
|
||||
|
||||
Then configure it in **WooCommerce → Settings → Payments → Stripe**.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Configure shipping
|
||||
|
||||
1. Go to **WooCommerce → Settings → Shipping**
|
||||
2. Click **Add shipping zone**
|
||||
3. Name the zone (e.g., "United States")
|
||||
4. Select the zone regions (countries, states, or postcode ranges)
|
||||
5. Click **Add shipping method**:
|
||||
- **Flat rate** — Single rate per order (e.g., $5.99)
|
||||
- **Free shipping** — Free shipping with a minimum order amount
|
||||
- **Local pickup** — Customer picks up at your location
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Performance optimization for WooCommerce
|
||||
|
||||
WooCommerce adds database queries and page weight. Optimize it carefully:
|
||||
|
||||
### Essential caching
|
||||
|
||||
1. Install a caching plugin. See [W3 Total Cache Configuration](/wordpress/w3-total-cache/) for detailed setup.
|
||||
2. **Important**: In W3 Total Cache, do NOT enable page caching for the cart, checkout, and my-account pages. Add these to the **Never cache the following pages** list: `/cart/*`, `/checkout/*`, `/my-account/*`, `/wc-api/*`
|
||||
|
||||
### Disable unused features
|
||||
|
||||
Go to **WooCommerce → Settings → Advanced → Features** and disable:
|
||||
- Coupons (if you don't use them)
|
||||
- If digital only, disable shipping and tax
|
||||
|
||||
### Enable native cart fragments (if needed)
|
||||
|
||||
Cart fragments (the little cart icon that updates via AJAX) are expensive on shared hosting. If your theme doesn't need real-time cart updates, disable it:
|
||||
|
||||
```bash
|
||||
wp option set woocommerce_cart_fragments_enabled no
|
||||
```
|
||||
|
||||
Customers will see a non-JS fallback link to the cart page.
|
||||
|
||||
### Image optimization
|
||||
|
||||
- Product images should be no larger than 1200px on the longest side
|
||||
- Use WebP format for product images (convert with `cwebp`)
|
||||
- Install a plugin like **Smush** or **Imagify** for automatic compression
|
||||
- Set WooCommerce image sizes appropriately: **WooCommerce → Settings → Products → Display**
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — Essential WooCommerce plugins
|
||||
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| [WooCommerce](https://wordpress.org/plugins/woocommerce/) | Core e-commerce platform |
|
||||
| [Akismet Anti-Spam](https://wordpress.org/plugins/akismet/) | Block spam product reviews |
|
||||
| [W3 Total Cache](https://wordpress.org/plugins/w3-total-cache/) | Page cache, DB cache, object cache |
|
||||
| [UpdraftPlus](https://wordpress.org/plugins/updraftplus/) | Scheduled backups of your store |
|
||||
| [WooCommerce Stripe](https://wordpress.org/plugins/woocommerce-gateway-stripe/) | Stripe credit card payments |
|
||||
|
||||
---
|
||||
|
||||
## Step 7 — SSL and security
|
||||
|
||||
- **WooCommerce forces SSL on checkout** automatically. Ensure your SSL certificate is valid.
|
||||
- **Force HTTPS for the entire site** in W3 Total Cache → General Settings → Page Cache → Enable HTTP(S) support
|
||||
- **Disable file editing** in WordPress admin by adding to `wp-config.php`:
|
||||
```php
|
||||
define('DISALLOW_FILE_EDIT', true);
|
||||
```
|
||||
- **Set up fail2ban**: See [Set Up Fail2ban](/vps/fail2ban/) for SSH brute-force protection
|
||||
- **Regular backups**: Use UpdraftPlus or [Automated Backups with Restic](/vps/automated-backups/) to back up your database and uploads
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Cart and checkout pages not working with caching**: Make sure cart, checkout, and my-account URLs are excluded from the page cache.
|
||||
|
||||
**500 error after installing WooCommerce**: Increase PHP memory limit to 512 MB. WooCommerce is memory-intensive.
|
||||
|
||||
**SSL not working on checkout**: Go to **WooCommerce → Settings → Advanced → Pages** and verify all pages are set. Then **Settings → General → WordPress Address URL and Site Address URL** must start with `https://`.
|
||||
|
||||
**PayPal IPN not working**: In PayPal, set the IPN URL to `https://yourdomain.com/wc-api/ipn-handler/`.
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
- [WordPress security hardening](/wordpress/security/)
|
||||
- [W3 Total Cache configuration](/wordpress/w3-total-cache/)
|
||||
- [Self-hosting without a CDN: performance tips](/privacy/self-hosting-performance/)
|
||||
|
||||
Reference in New Issue
Block a user