> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Vanilla WordPress on Upsun Cloud

> Complete the last required steps to successfully deploy Vanilla WordPress on Upsun Cloud.


> [!NOTE]
>
> Before you start, check out the [Upsun Cloud demo app](https://console.upsun.com/projects/create-project)
> and the main [Getting started guide](https://developer.upsun.com/docs/get-started/here).
> They provide all the core concepts and common commands you need to know before using the following materials.

For WordPress to successfully deploy and operate, **after completing the [Getting started guide](https://developer.upsun.com/docs/get-started/here)**,
you still need to add some required files and make a few changes to your Upsun Cloud configuration.

## Before you begin

You need:

<ul><li>[Git](https://git-scm.com/downloads).
Git is the primary tool to manage everything your app needs to run.
Push commits to deploy changes and control configuration through YAML files.
These files describe your infrastructure, making it transparent and version-controlled.</li>
<li>An Upsun account.
If you don't already have one, [register for a trial account](https://auth.upsun.com/register).
You can sign up with an email address or an existing GitHub, Bitbucket, or Google account.
If you choose one of these accounts, you can set a password for your Upsun account later.</li>
<li>The [Upsun CLI](https://developer.upsun.com/cli.md).
This lets you interact with your project from the command line.
You can also do most things through the [Web Console](https://developer.upsun.com/docs/administration/web).</li></ul>

> [!NOTE]
>
> Assumptions
> There are many ways you can set up a WordPress site or Upsun Cloud project.
> The instructions on this page were designed based on the following assumptions:
>
> * You selected **PHP** as your runtime, and **MariaDB** as a service during the Getting Started guide. It's also assumed that
>   while using the Getting Started guide you named the project `<APP_NAME>`, which you will notice is the top-level key in all
>   configuration below.
> * You are currently in the same directory where you created your project during the Getting Started guide.

## 1. Add required files

To ensure you have all the required files and directories in your project, follow these steps:

1. If you haven't already, you will need to retrieve the [WordPress](https://wordpress.org/) core files. You can either
   download a zip archive from WordPress.org, or use `curl` to download a tarball:

   ```shell theme={null}
   curl https://wordpress.org/latest -o wordpress.tar.gz
   ```

2. Extract the contents of the archive. If you used `curl` in step 1, you can extract the contents using `tar`:

   ```shell theme={null}
   tar -xvf wordpress.tar.gz
   ```

3. After extracting the files from the archive, delete the archive as it is no longer needed (e.g. `rm wordpress.tar.gz`)

4. Whether you downloaded the zip or the tarball, after extraction the extracted files should be contained in a
   directory named `wordpress`. This directory will become your public directory later. If you decide to rename this
   directory, make note of it for later steps.

5. Create a `wp-config.php` file inside the directory from step 4 and copy and paste the contents from
   [this example file](https://github.com/upsun/snippets/blob/main/examples/wordpress-vanilla/wordpress/wp-config.php).

6. To make using [wp-cli](https://wp-cli.org/) easier, add a `wp-cli.yml` file in the directory where you intend to run wp-cli commands regularly — typically the project root, since that's where the `deploy` and `post_deploy` hooks run `wp` commands — and add the following contents to it:

   ```yaml theme={null}
    path: /app/wordpress/
    color: true
   ```

   > [!NOTE]
   >
   > If you changed the name of the directory at step 4 you'll need to update the `path` property above to match.

   > [!TIP]
   >
   > To call wp-cli from any directory instead of only the project root, set `WP_CLI_CONFIG_PATH` in your [`.environment`](https://developer.upsun.com/docs/development/variables/set-variables#set-variables-in-your-app) file to the absolute path of `wp-cli.yml`, for example `export WP_CLI_CONFIG_PATH=/app/wp-cli.yml`.

7. Add all the files from the steps above to your repository
   ```bash location="Terminal" theme={null}
    git add .
    git commit -m "adds wordpress core files"
   ```

## 2. Update configuration files

1. Open the `.upsun/config.yaml` file created during the [Getting started guide](https://developer.upsun.com/docs/get-started/here)

2. Locate the `web:locations` section and update the root (`/`) location as follows:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       web:
&#x20;         locations:
&#x20;           "/":
&#x20;             passthru: "/index.php"
&#x20;             root: "wordpress"
&#x20;             index:
&#x20;               \- "index.php"
&#x20;             expires: 600
&#x20;             scripts: true
&#x20;             allow: true
&#x20;             rules:
&#x20;               ^/license\\.text\$:
&#x20;                 allow: false
&#x20;               ^/readme\\.html\$:
&#x20;                 allow: false
&#x20;           "/wp-content/uploads":
&#x20;             root: "wordpress/wp-content/uploads"
&#x20;             scripts: false
&#x20;             allow: false
&#x20;             rules:
&#x20;               '(?\<!\\-lock)\\.(?i:jpe?g|gif|png|svg|bmp|ico|css|js(?:on)?|eot|ttf|woff|woff2|pdf|docx?|xlsx?|pp\[st]x?|psd|odt|key|mp\[2-5g]|m4\[av]|og\[gv]|wav|mov|wm\[av]|avi|3g\[p2])\$':
&#x20;                 allow: true
&#x20;                 expires: 1w

> [!NOTE]
>
> If you changed the name of the directory at step 1.4 you'll need to update the `root` property to match for both locations.

3. Application containers are read-only by default; WordPress needs a writable location to store uploaded media.
   To make the location writable, set up [a mount](https://developer.upsun.com/docs/configure-apps/image-properties/mounts.md). To do so,
   locate the `mounts:` section that is commented out, and update it as follows:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       mounts:
&#x20;         "wordpress/wp-content/uploads":
&#x20;           source: storage
&#x20;           source\_path: "uploads"

> [!NOTE]
>
> When uncommenting, pay attention to the indentation and that the `mounts` key aligns with other sibling keys (e.g. `relationships`, `web`, etc.)

4. Once the images for our application have been built, there are a few key tasks that must be completed before our
   newly-built application can receive requests. These tasks include:

   * Flushing the object cache, which might have changed between current production and newly deployed changes
   * Running the WordPress database update procedure, in case core is being updated with the newly deployed changes
   * Running any due cron jobs

   To perform these tasks, we'll utilize  the [`deploy`](https://developer.upsun.com/docs/core-concepts/build-deploy#deploy-steps) and
   [`post_deploy`](https://developer.upsun.com/docs/configure-apps/hooks/hooks-comparison#post-deploy-hook) hooks. Locate the `deploy:` section
   (below the `build:` section). Update the `deploy:` and `post_deploy:` section as follows:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       \<snip>
&#x20;       hooks:
&#x20;         deploy: |
&#x20;           set -eu
&#x20;           \# Flushes the object cache
&#x20;           wp cache flush
&#x20;           \# Runs the WordPress database update procedure
&#x20;           wp core update-db
&#x20;         post\_deploy: |
&#x20;           set -eu

&#x20;           \# Runs all due cron events
&#x20;           wp cron event run --due-now

5. Add your crons

Under your application configuration you can now add a cron.


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       ...
&#x20;       crons:
&#x20;         wp-cron:
&#x20;           spec: '\*/10 \* \* \* \*'
&#x20;           commands:
&#x20;             start: wp cron event run --due-now
&#x20;           shutdown\_timeout: 600
&#x20;&#x20;

6. Locate the `routes:` section, and beneath it, the `"https://{default}/":` route. Update the route as follows:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       ...

&#x20;   routes:
&#x20;     "https\://\{default}/":
&#x20;       type: upstream
&#x20;       upstream: "\<APP\_NAME>:http"
&#x20;       cache:
&#x20;         enabled: true
&#x20;         cookies:
&#x20;           \- '/^wordpress\_\*/'
&#x20;           \- '/^wp-\*/'

7. To ensure we are able to perform tasks later in the deployment stage (e.g. updating the database, flushing cache, etc.)
   we need to make sure the [wp-cli](https://wp-cli.org/) utility is a dependency of the application container. While still
   in the `.upsun/config.yaml` file, locate the `dependencies.php` section, and add the following:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       dependencies:
&#x20;         php:
&#x20;           wp-cli/wp-cli-bundle: "^2.4"

> [!NOTE]
>
> It is possible the `dependencies` section is commented out. When uncommenting, pay attention to the indentation and that
> the `dependencies` key aligns with other sibling keys (e.g. `build`, `hooks`, etc.)

8. Add and commit your changes.

   ```bash Terminal theme={null}
   git add .upsun/config.yaml
   git commit -m "Updates Upsun Cloud configuration file"
   ```

## 3. Update `.environment`

The CLI generated a `.environment` file during the Getting started guide. Notice it has already created some environment
variables for you to connect to your database service.

```bash .environment theme={null}
# Set database environment variables
export DB_HOST="$MARIADB_HOST"
export DB_PORT="$MARIADB_PORT"
export DB_PATH="$MARIADB_PATH"
export DB_DATABASE="$DB_PATH"
export DB_USERNAME="$MARIADB_USERNAME"
export DB_PASSWORD="$MARIADB_PASSWORD"
export DB_SCHEME="$MARIADB_SCHEME"
export DATABASE_URL="${DB_SCHEME}://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_PATH}"
```

To configure the remaining environment variables WordPress needs to run smoothly, open the `.environment` file. Just
after the other database-related variables, add a blank line or two and add the following:

```bash .environment theme={null}
# Routes, URLS, and primary domain
export SITE_ROUTES="$(echo "$PLATFORM_ROUTES" | base64 --decode)"; \
export UPSTREAM_URLS="$(echo "$SITE_ROUTES" | jq -r --arg app "$PLATFORM_APPLICATION_NAME" 'map_values(select(.type == "upstream" and .upstream == $app)) | keys')"; \
export DOMAIN_CURRENT_SITE="$(echo "$SITE_ROUTES" | jq -r --arg app "$PLATFORM_APPLICATION_NAME" 'map_values(select(.primary == true and .type == "upstream" and .upstream == $app)) | keys | .[0] | if (.[-1:] == "/") then (.[0:-1]) else . end')"
```

Save, add, and commit those changes:

```bash Terminal theme={null}
git add .environment
git commit -m "adds remaining environment variables to .environment"
```

## 4. Push and deploy

Now that we've added the required files, you're ready to push your changes and deploy your WordPress site:

```bash Terminal theme={null}
upsun push -y
```

## 5. Routinely run WP Cron (optional)

If your site does not receive enough traffic to ensure [WP Cron jobs](https://developer.wordpress.org/plugins/cron/) run
in a timely manner, or your site uses caching heavily such that WP Cron isn't being triggered, you might consider adding
a [cron job](https://developer.upsun.com/docs/configure-apps/image-properties/crons.md) to your project's configuration to have WP CLI
run those scheduled tasks on a routine basis. To do so, locate the `crons:` section that is commented out, and update it
as follows:


&#x20;   applications:
&#x20;     \<APP\_NAME>:
&#x20;       source:
&#x20;         root: "/"
&#x20;       type: 'php:\{\{version:php:latest}}'
&#x20;       crons:
&#x20;         wp-cron:
&#x20;           spec: '\*/15 \* \* \* \*'
&#x20;           commands:
&#x20;             start: wp cron event run --due-now
&#x20;           shutdown\_timeout: 600
&#x20;&#x20;

The above example will trigger the wp-cli every 15th minute to run WP Cron tasks that are due. Feel free to adjust based
on your individual requirements.

> [!NOTE]
>
> When uncommenting, pay attention to the indentation and that the `crons` key aligns with other sibling keys (e.g. `hooks`, `dependencies`, etc.)

## Further resources

* [All files (Upsun configuration, `.environment`, `wp-cli.yml`, `wp-config.php`)](https://github.com/upsun/snippets/tree/main/examples/wordpress-vanilla)

### Documentation

* [PHP documentation](https://developer.upsun.com/docs/languages/php)

* [Extensions](https://developer.upsun.com/docs/languages/php/extensions.md)

* [Performance tuning](https://developer.upsun.com/docs/languages/php/tuning.md)

* [PHP-FPM sizing](https://developer.upsun.com/docs/languages/php/fpm.md)

### Community content

* [PHP topics](https://support.platform.sh/hc/en-us/search?utf8=%E2%9C%93\&query=php)
* [WordPress topics](https://support.platform.sh/hc/en-us/search?utf8=%E2%9C%93\&query=wordpress)

### Blogs

* [To Upsun, a WordPress migration story](https://upsun.com/blog/to-upsun-a-wordpress-migration-story/)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.