ProcessWire is a flexible, API-driven CMS built on PHP. This guide covers everything you need to deploy a ProcessWire site using DeployHQ, from server requirements and hosting setup through to zero-downtime deployments and cache management.

## Hosting Requirements

ProcessWire runs on a standard LAMP/LEMP stack. Your server needs:

- **PHP 7.2+** (PHP 8.1+ recommended) with extensions: `gd`, `mysqli` or `pdo_mysql`, `mbstring`, `curl`, `zip`
- **MySQL 5.7+** or **MariaDB 10.2+**
- **Apache with mod_rewrite** or **Nginx**
- At least **256MB PHP memory limit** (512MB recommended for sites with image manipulation)
- **SSH access** for DeployHQ to connect and run post-deploy commands

Most PHP hosting providers meet these requirements. If you need a VPS, providers like DigitalOcean, Linode, or Hetzner work well. Managed platforms like Laravel Forge or Ploi can handle server provisioning for you.

## Repository Setup

Start by adding ProcessWire to version control. If you are starting a new project, install via Composer:

```bash
composer create-project processwire/processwire your-site
cd your-site
git init
```

For an existing site, initialise a repository in the project root and add a `.gitignore`:

```
# ProcessWire .gitignore
site/assets/files/
site/assets/cache/
site/assets/logs/
site/assets/sessions/
site/assets/backups/
site/config.php
vendor/
node_modules/
.env
```

The key principle: **track code, not runtime data**. The `site/assets/files/` directory holds uploaded content and should live on the server, not in your repository. The `site/config.php` file contains database credentials and must be server-specific.

## Managing Modules

ProcessWire modules can be installed two ways, and your deployment strategy depends on which you use.

**Composer-managed modules** are listed in `composer.json` and installed during the build step. This is the cleanest approach for deployment:

```bash
composer require rockett/dumper
composer require wireframe-framework/wireframe
```

**Manually installed modules** live in `site/modules/` and should be committed to your repository. If a module is not available via Composer, download it into `site/modules/ModuleName/` and add it to Git.

A hybrid approach works well: use Composer for modules that support it, and commit the rest. Your build pipeline handles the Composer install, and Git handles the manually installed modules.

## Environment Configuration

ProcessWire reads its configuration from `site/config.php`. Since this file contains database credentials, keep it out of version control and create it directly on each server.

A useful pattern is to commit a default configuration template:

```php
// site/config-default.php (committed to repo)
$config->dbHost = 'localhost';
$config->dbName = 'processwire';
$config->dbUser = 'pw_user';
$config->dbPass = 'change_me';
$config->dbPort = '3306';
$config->dbEngine = 'InnoDB';

$config->debug = false;
$config->advanced = false;
$config->adminTheme = 'AdminThemeUikit';

$config->httpHosts = ['yourdomain.com', 'www.yourdomain.com'];
$config->chmodDir = '0755';
$config->chmodFile = '0644';
```

On the server, copy this to `site/config.php` and fill in the real credentials. DeployHQ's [config files feature](https://www.deployhq.com/support) lets you manage server-specific files that get placed during deployment without being stored in your repository.

## File Permissions and the Assets Directory

ProcessWire needs write access to `site/assets/` and its subdirectories. After your first deployment, set permissions on the server:

```bash
chmod -R 755 site/assets/
chown -R www-data:www-data site/assets/
```

The `site/assets/` directory contains:

| Directory | Purpose | In Git? |
|-----------|---------|---------|
| `files/` | Uploaded images and documents | No |
| `cache/` | Template and markup cache | No |
| `logs/` | Error and access logs | No |
| `sessions/` | PHP session files | No |
| `backups/` | Database backups | No |

All of these are runtime directories and must persist between deployments.

## DeployHQ Build Pipeline

Create a `.deploybuild.yaml` file in your repository root to run Composer during the build step:

```yaml
build:
  - composer install --no-dev --optimize-autoloader --no-interaction
  - npm ci
  - npm run build
```

Remove the `npm` lines if your project does not use a frontend build tool. The `--no-dev` flag excludes development dependencies, and `--optimize-autoloader` generates a class map for better performance.

See the [.deploybuild.yaml documentation](https://www.deployhq.com/support/build-pipelines/deploybuild-dot-yaml) for the full configuration reference.

## Zero-Downtime Deployments

For production sites, enable [zero-downtime deployments](https://www.deployhq.com/features/zero-downtime-deployments) in your DeployHQ project. This creates a new release directory for each deployment and switches a symlink when the deploy completes.

Configure these as **shared paths** so they persist across releases:

- `site/assets/files`
- `site/assets/logs`
- `site/assets/sessions`
- `site/assets/backups`

This ensures uploaded files and session data survive each deployment without being overwritten.

## Post-Deploy SSH Commands

Add an SSH command in DeployHQ to run after each deployment:

```bash
cd %deploy_path% && php site/modules/ProcessCacheControl/clear.php 2>/dev/null; echo "Deploy complete"
```

If you use ProCache or a custom cache-clearing module, adjust the command accordingly. The goal is to clear any cached templates or compiled assets so the new code takes effect immediately.

## Cache Management

ProcessWire has several caching layers you should be aware of during deployment:

- **Template cache**: Configured per-template in the admin under Setup > Templates > Cache. Cached markup is stored in `site/assets/cache/`. Clearing this after deploy ensures visitors see updated content.
- **WireCache API**: Application-level cache used by modules and custom code. Clear with `$cache->deleteAll()` in a post-deploy script if needed.
- **ProCache** (commercial module): Full-page static cache. If installed, clear it via the admin or a post-deploy command. ProCache files live in the site root or a configured cache directory.
- **Compiled files**: ProcessWire compiles template files to `site/assets/cache/FileCompiler/`. These regenerate automatically but can be cleared manually if you encounter stale code.

## Handling the Installer on First Deploy

When you deploy ProcessWire for the first time to a new server, the installer wizard runs automatically when you visit the site in a browser. Before that first visit:

1. Ensure `site/config.php` exists on the server with valid database credentials
2. Confirm the database exists and the user has full privileges
3. Verify `site/assets/` is writable by the web server
4. Visit your domain — the installer will walk you through admin account creation

After the installer completes, it writes a `site/assets/installed.php` file. Subsequent deployments skip the installer entirely.

## Nginx Configuration

If you are using Nginx instead of Apache, configure URL rewriting to pass requests through ProcessWire:

```nginx
server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/your-site/current;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?it=$uri&$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.(ht|git) {
        deny all;
    }

    location ~ /site/(assets/cache|assets/logs|assets/backups|assets/sessions|config\.php) {
        deny all;
    }
}
```

The last `location` block prevents direct access to sensitive ProcessWire directories — an important hardening step that Apache's `.htaccess` handles automatically.

## Troubleshooting Common Issues

**Blank page after deploy**: Check PHP error logs. Usually a missing PHP extension (`gd` and `mbstring` are the most common) or incorrect `site/config.php` database credentials.

**403 or 500 errors**: Verify `.htaccess` is deployed (it is often excluded by `.gitignore` on other projects — make sure it is tracked for ProcessWire). For Nginx, ensure your rewrite rules point to `index.php`.

**Assets not loading**: If images or files are missing after a zero-downtime deployment, confirm the shared paths are configured correctly. The symlinks for `site/assets/files` must point to the shared directory, not the release directory.

**"Unable to write" errors**: File permission issues. Run `chown -R www-data:www-data site/assets/` (replace `www-data` with your web server user).

**Modules not found after deploy**: If you added a Composer module but it is missing, check that `composer install` runs successfully in your build pipeline. Review the build log in DeployHQ for errors.

## Continuous Deployment

Once your first deployment succeeds, enable automatic deployments in DeployHQ by connecting your Git repository. Every push to your main branch triggers a build and deployment automatically. Use separate DeployHQ servers for staging and production, each with their own `site/config.php`.

For more deployment guides covering other frameworks and CMS platforms, see the [DeployHQ guides directory](https://www.deployhq.com/guides).

---

**Ready to automate your ProcessWire deployments?** [Sign up for DeployHQ](https://www.deployhq.com/signup) and connect your repository in minutes.

If you need help, contact us at [support@deployhq.com](mailto:support@deployhq.com) or on [Twitter/X](https://x.com/deployhq).