> For the complete documentation index, see [llms.txt](https://docs.release.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.release.com/guides-and-examples/common-setup-examples/wordpress-mysql.md).

# WordPress with MySQL

In this tutorial, you'll learn how to deploy WordPress and MySQL on Release.

## Docker Compose and Release for WordPress development

Using Docker Compose during WordPress theme or plugin development ensures that your development and build environments can be recreated easily on your team's workstations and staging servers.

By adding your WordPress repository to Release, you can create environments per branch, create staging environments, test contributors' pull requests, and share demo links with clients.

## WordPress and Docker Compose

For this tutorial, we'll start with the [WordPress with MySQL](https://github.com/docker/awesome-compose/tree/master/wordpress-mysql) example from [Awesome Compose](https://github.com/docker/awesome-compose/). To simplify getting started, we've created a repository with only the `wordpress-mysql` folder from the Awesome Compose repository: [wordpress-mysql](https://github.com/awesome-release/wordpress-mysql).

## Requirements

[Create a Release account](/getting-started/create-an-account.md) and [integrate your source control](/integrations/source-control-integrations.md) (GitHub, Bitbucket, or GitLab) account.

Besides a web browser, you won't need anything specific installed on your computer for this guide.

## Fork the `wordpress-mysql` example repository

Fork the [`wordpress-mysql`](https://github.com/awesome-release/wordpress-mysql) repository to a private or public repository in your version control hosting service.

## An overview of the example application

The `docker-compose.yaml` file lists two services for this application: `db` and `wordpress`.

The service called `db` runs a specific `mysql` Docker image, while the `wordpress` service runs the latest `wordpress` Docker image.

## Create a new application on Release

Release can import applications based on Docker Compose, so we won't need to change anything in the repository to add this application to Release.

Firstly, log into Release, and [create an application](https://github.com/releasehub-com/docs/blob/main/examples/broken-reference/README.md) by clicking on **Create new app**.

![Create an application](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-b7e0ab96d89a633193dfb37b6616dd8431dc8699%2Fwordpress-mysql-create-application.png?alt=media\&token=e6328b14-fdc0-4127-9eda-701ee4845bbf)

## Name your application and select your repository

Enter a unique name for your application, and pick the forked repository you created earlier, then click **Next step**.

![Enter a name and pick your repository](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-4fdf88eb4c5eae87377562f6a7a6b4230bdc03c4%2Fwordpress-mysql-create-app-settings.png?alt=media\&token=88cc3038-f36b-4b21-8327-d02b0c40ed20)

## Pick your services

1. Pick **Analyze the repository**, so Release can create services from `docker-compose.yaml`.
2. Select the branch from your repository you'd like to track in this application.
3. Select the `docker-compose.yaml` file.
4. Click **Start analysis**.

![Pick your services](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-56fddb23f5aec215a8d86a4411cd1644194cb387%2Fwordpress-mysql-pick-services.png?alt=media\&token=33672a38-1594-4eab-a6c0-15ecdab8c831)

Release will read your Docker Compose file, and list the services found.

![Pick your services showing analysis result](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-5833d6e788a9040c8a1d921f541b42a7e0669165%2Fwordpress-mysql-services-analyzed.png?alt=media\&token=282373b0-1cc9-4e00-86c2-ca6f6e15dc07)

Click **Next step**.

## Generate a template

Release will generate a template based on the services from your `docker-compose.yaml` file.

![Generate an application template](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-5668f9d3f94c59c1b3fd748d57658aeb8c7536f4%2Fwordpress-mysql-app-template.png?alt=media\&token=15a383e4-1693-4233-86dc-7d30a31806e8)

Release will use this template to create new environments later on, and the defaults should work as expected for most Docker Compose applications.

### Expose container ports for the database service

{% hint style="info" %}
Release does not currently convert `expose` directives when importing services from Docker Compose. Add a `container_port` for each port in your Docker Compose file. Read more about [ports](/reference-documentation/application-settings/application-template/schema-definition.md#ports) in our template schema.
{% endhint %}

For this example application, we'll make one important change to the template to make sure the `db` service exposes two ports for MySQL.

Find the `db` service in the application template YAML, and add two container ports by making the following changes:

```diff
  services:
  - name: db
+   ports:
+   - type: container_port
+     port: '3306'
+   - type: container_port
+     port: '33060'
# ...
```

Release supports two different port types: `node_port` and `container_port`. We're adding a container port to the `db` service because this port should only be accessible on your application's private network. This enables the `wordpress` service to connect to the `db` service without exposing your MySQL database to the internet.

After editing the template, click **Next step**.

## Environment variables

The `docker-compose.yaml` file from our repo lists the environment variables for each service.

To see how each service's container will use these environment variables, we can consult the Docker images documentation.

### [`mysql`](https://hub.docker.com/_/mysql) Docker image variables

#### `MYSQL_ROOT_PASSWORD`

Specifies the `root` MySQL user's password. On a production server, this should be treated as secret.

#### `MYSQL_DATABASE`

If this variable is set, MySQL will create a database with this variable's value as a name. For our example, we'll set this to `wordpress`.

We can expect the MySQL server to create a database called `wordpress` on startup.

#### `MYSQL_USER` and `MYSQL_PASSWORD`

MySQL uses these two variables together to set a username and password for a new MySQL user on startup. This user will be granted superuser privileges (`GRANT ALL`) on the database specified by `MYSQL_DATABASE`.

For the example application, we'll set both to `wordpress`.

On startup, we can expect MySQL to create a new user called `wordpress` with the password `wordpress`, and grant the user all privileges on the `wordpress` database.

### [`wordpress`](https://hub.docker.com/_/wordpress) Docker image variables

WordPress uses a `wp-config.php` file to set database access strings and other settings. Usually, you would edit `wp-config.php` manually and set the database hostname, username, and password as PHP variables.

In Docker, we do this differently. The WordPress Docker image uses a [custom `wp-config.php` file](https://github.com/docker-library/wordpress/blob/master/wp-config-docker.php) that enables you to configure WordPress through environment variables.

For more information about the benefits of using environment variables for configuration (not just in Docker), we recommend reading [The Twelve-Factor App III: Config](https://12factor.net/config).

Let's take a look at the four environment variables in our example application.

#### `WORDPRESS_DB_HOST`

The WordPress Docker image uses this variable to set the database hostname. For our example, we'll set this to `db`.

Release creates a private network for your application, and by default, any service in your application can discover any other service in the application by querying a service's name.

This means the `wordpress` service can reach the `db` service's container on the private network by querying the `db` hostname.

#### `WORDPRESS_DB_USER`, `WORDPRESS_DB_PASSWORD`, and `WORDPRESS_DB_NAME`

The WordPress Docker image uses these three variables to know which database to use and to authenticate with the MySQL database server.

For this example, we'll set all three to `wordpress` so that they match the equivalent variables set for the `db` service.

### Set your environment variables

![Set your environment variables](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-e81a318849451118e0c2d8386e17becb45f8a745%2Fwordpress-mysql-env-vars.png?alt=media\&token=c497805a-1e94-42c3-9b64-f37b16909840)

Edit the YAML environment variables in Release to look like this:

```yaml
---
defaults: []
services:
  db:
  - key: MYSQL_ROOT_PASSWORD
    value: somewordpress
    secret: true
  - key: MYSQL_DATABASE
    value: wordpress
  - key: MYSQL_USER
    value: wordpress
  - key: MYSQL_PASSWORD
    value: wordpress
    secret: true
  wordpress:
  - key: WORDPRESS_DB_HOST
    value: db
  - key: WORDPRESS_DB_USER
    value: wordpress
  - key: WORDPRESS_DB_PASSWORD
    value: wordpress
    secret: true
  - key: WORDPRESS_DB_NAME
    value: wordpress
```

### Secret environment variables

You'll notice that we marked the `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD`, and `WORDPRESS_DB_PASSWORD` variables as secret by setting the `secret` flag to true for each of them.

Release saves [secret variables](/reference-documentation/environment-settings/environment-specific-environment-variables/managing-secrets.md) in an encrypted vault, and exposes these secrets to your running containers at startup.

Click **Next step** to save your environment variables.

## Build arguments

This application does not use any build arguments, so we can click **Next step**.

## Save and deploy

Click **Deploy your app** to create your application.

![Deploy your app](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-a51b94c1e949d2e509fe8962cde748a3f7a1051a%2Fwordpress-mysql-deploy.png?alt=media\&token=195b529d-0d21-47ad-a923-6043638e021e)

Release will now pull two Docker images, `mysql` and `wordpress`, then start two services, `db` and `wordpress`.

Your browser should redirect to a deployment status page, showing the progress of the setup workflow.

After Release's set-up and deployment workflow completes, navigate to your new environment and click on the URL for the `wordpress` service.

![Service hosted URL](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-f8463a3f7cb1d2c1c782aae184cd5c25fd457052%2Fwordpress-mysql-detail.png?alt=media\&token=67de8800-eb86-4d6e-82e9-2f45ed0730ab)

## Install WordPress

You should now see the WordPress setup screen.

![WordPress' language selection screen](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-260c31827a63c67472aa085f03ea42266cf777ef%2Fwordpress-mysql-result.png?alt=media\&token=dd31c503-4dc5-4982-92c1-b5e2e19596a3)

Select your language and click **Continue**.

![Install WordPress](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-985d078a57e5d310eba3c3174c419940fc72b45c%2Fwordpress-mysql-wordpress-setup.png?alt=media\&token=813abf98-443e-4377-be80-d23a8557e414)

Create a user and install WordPress by following these steps:

1. Enter a site title.
2. Enter a username, which you'll use later to log into WordPress.
3. Copy and save the recommended password. You'll use this later to log into WordPress.
4. Enter your email address.
5. Tick the **search engine visibility** checkbox. We recommend this to discourage search engines from crawling websites in development.
6. Click **Install WordPress**.

Your WordPress service will now run WordPress's installation script, which connects to your MySQL database and adds the required tables and configuration. WordPress also creates an admin user based on the username and password you entered.

![WordPress installed successfully](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-dde0fe78b1c298babac0b36db1e9c74d5853455b%2Fwordpress-mysql-success.png?alt=media\&token=801fff4c-dec2-4392-bff9-30dc8ca4b094)

Click **log in**.

## Log into WordPress

Enter your username and password, then click **Log in**.

![Log into WordPress](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-4deedc8f6ca085135c98ac4bafd85abb22f5abe3%2Fwordpress-mysql-login.png?alt=media\&token=9734d520-cde1-47dc-8f96-69c025b6fcc9)

## View your WordPress site

On the WordPress dashboard, hover over your site's name and click **visit site**.

![View your WordPress site](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-f4b67379a3a7e437e3274e44805727d5c13c73ef%2Fwordpress-mysql-view-site.png?alt=media\&token=cb78bce8-29ec-4f75-bfe0-4afbd043ea88)

You should see a sample page on your WordPress site now.

![WordPress sample page](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-9218f377bb104fc75c2da1459bd55012623fcbbe%2Fwordpress-mysql-site.png?alt=media\&token=1b1ab692-8077-466b-9006-095e701d34ff)

## Troubleshooting

If you don't see the WordPress language selector after the deployment workflow above, you can view the logs for each service in your environment to see whether either service logged any errors.

To view a service's logs, navigate to your environment's details page, scroll down to the list of services, and click on **logs**.

### Debugging database connection errors

The most common problem when first installing WordPress is a database connection error.

![WordPress database error](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-3358d752e4e906d54cb8b49fb512e3d0856dae74%2Fwordpress-mysql-db-error.png?alt=media\&token=c03d7e58-332e-4be6-b7dc-583ab08054d5)

On Release, this error can be solved by working through the following steps:

1. Make sure the corresponding environment variables from both services match.

   Values for the variables in each row below should match:

   | `db` service     | `wordpress` service     |
   | ---------------- | ----------------------- |
   | `MYSQL_DATABASE` | `WORDPRESS_DB_NAME`     |
   | `MYSQL_USER`     | `WORDPRESS_DB_USER`     |
   | `MYSQL_PASSWORD` | `WORDPRESS_DB_PASSWORD` |
2. Make sure the `WORDPRESS_DB_HOST` environment variable matches the name of your database service.
3. Make sure your database service exposes the correct ports. MySQL on Docker uses ports `3306` and `33060`.

## Further reading

Docker is most useful when developing WordPress plugins and themes, rather than just configuring a *WordPress site*.

We recommend pre-installing your themes and plugins if you're using Docker for WordPress development.

### Pre-installed themes and plugins

To learn more about how you can pre-install WordPress plugins using Docker Compose, we recommend reading [Include pre-installed themes / plugins](https://github.com/docker-library/docs/tree/master/wordpress#include-pre-installed-themes--plugins) from the WordPress Docker image documentation.

### Persistent volumes for uploads

In the example above, only the database service mounts a persistent volume. This means that the database data for each environment will remain after the application restarts or re-deploys.

The WordPress service does not use a persistent volume.

Images and other files uploaded to your WordPress site will be deleted when you re-deploy your application.

To learn about how to mount a persistent volume for WordPress using Docker Compose, we recommend reading [Quickstart: Compose and WordPress](https://docs.docker.com/samples/wordpress/).

To learn how to mount a persistent volume on a Release service, see the [Volumes](/reference-documentation/application-settings/application-template/schema-definition.md#volumes-1) section in our template schema documentation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.release.com/guides-and-examples/common-setup-examples/wordpress-mysql.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
