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

# MySQL

> Deploy MySQL on Control Plane using the Template Catalog. Covers configuration, volumes, scaling, and single-replica setup with optional phpMyAdmin and S3/GCS backups.

## Overview

MySQL is a widely used open-source relational database management system. This template deploys a single-replica MySQL instance with persistent storage, an optional phpMyAdmin web interface, and optional scheduled backups to AWS S3 or GCS.

<Note>
  MySQL on Control Plane operates as a single-replica deployment. Do not scale up the replica count, as this would result in multiple isolated instances rather than a replicated cluster.
</Note>

### What Gets Created

* **Stateful Workload** — A single-replica MySQL database container with configurable resources.
* **Volume Set** — Persistent storage for MySQL data, with optional autoscaling.
* **Secret** — A dictionary secret storing the database name, root password, and user credentials. When backup is enabled, the secret also includes backup storage configuration.
* **Identity & Policy** — An identity bound to the workload with `reveal` access to the database credentials secret. When backup is enabled, the identity also grants the backup cron job access to the configured cloud storage.
* **Backup Cron Job** (optional) — A scheduled job that dumps the MySQL database to an S3 or GCS bucket. Enabled when `backup.enabled: true`.
* **phpMyAdmin Workload** (optional) — A web-based database management interface. Enabled when `enablePhpMyAdmin: true`.

<Note>
  This template does not create a GVC. You must deploy it into an existing GVC.
</Note>

## Prerequisites

Prerequisites are only required if you plan to enable MySQL backups (`backup.enabled: true`). The backup feature requires MySQL 9+. Skip this section if backups are not needed.

### AWS S3

1. Create an S3 bucket. Set `backup.aws.bucket` and `backup.aws.region` in your values file.

2. If you do not have a Control Plane Cloud Account set up, follow the [Create a Cloud Account](https://docs.controlplane.com/guides/create-cloud-account) guide. Set `backup.aws.cloudAccountName` to the name of your Cloud Account.

3. Create an IAM policy with the following JSON, replacing `YOUR_BUCKET_NAME`:

```json theme={null}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket",
                "s3:GetObjectVersion",
                "s3:DeleteObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR_BUCKET_NAME",
                "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            ]
        }
    ]
}
```

4. Set `backup.aws.policyName` to the name of the policy created in step 3.

### GCS

1. Create a GCS bucket. Set `backup.gcp.bucket` in your values file.

2. If you do not have a Control Plane Cloud Account set up, follow the [Create a Cloud Account](https://docs.controlplane.com/guides/create-cloud-account) guide. Set `backup.gcp.cloudAccountName` to the name of your Cloud Account.

3. Add the **Storage Admin** role to the GCP service account associated with the Cloud Account.

## Installation

To install, follow the instructions for your preferred method:

<CardGroup cols={2}>
  <Card title="UI" href="/template-catalog/install-manage/ui" icon="laptop">
    Browse, install, and manage templates visually
  </Card>

  <Card title="CLI" href="/template-catalog/install-manage/cli" icon="terminal">
    Manage templates from your terminal
  </Card>

  <Card title="Terraform" href="/template-catalog/install-manage/terraform" icon={<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><g fill-rule="evenodd"><path d="M77.941 44.5v36.836L46.324 62.918V26.082zm0 0" fill="#5c4ee5"/><path d="M81.41 81.336l31.633-18.418V26.082L81.41 44.5zm0 0" fill="#4040b2"/><path d="M11.242 42.36L42.86 60.776V23.941L11.242 5.523zm0 0M77.941 85.375L46.324 66.957v36.82l31.617 18.418zm0 0" fill="#5c4ee5"/></g></svg>}>
    Declare templates in your Terraform configurations
  </Card>

  <Card
    title="Pulumi"
    href="/template-catalog/install-manage/pulumi"
    icon={<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="Pulumi-Icon--Streamline-Svg-Logos" height="24" width="24">
    <desc>
        Pulumi Icon Streamline Icon: https://streamlinehq.com
    </desc>
    <path fill="#f26e7e" d="M4.683025 13.3318c0.869125 -0.5018 0.870575 -2.1264 0.003225 -3.62865s-2.27504 -2.313275 -3.1441725 -1.811475C0.672945 8.3935 0.6715 10.0181 1.53885 11.52035c0.86735 1.502275 2.27505 2.313275 3.144175 1.81145Zm0.0052 3.2167c0.86735 1.502275 0.865925 3.126875 -0.003225 3.628675 -0.86915 0.5018 -2.2768275 -0.309225 -3.144175 -1.81145 -0.8673525 -1.50225 -0.8659075 -3.126875 0.003225 -3.628675 0.8691325 -0.5018 2.276825 0.309225 3.144175 1.81145Zm5.922875 3.4243c0.86735 1.50225 0.8659 3.126775 -0.003225 3.62875 -0.869125 0.501775 -2.27685 -0.309325 -3.1442 -1.81155 -0.867325 -1.50225 -0.865875 -3.12685 0.00325 -3.628675 0.869125 -0.5018 2.276825 0.309225 3.144175 1.811475Zm-0.001925 -6.845275c0.86735 1.50225 0.8659 3.12685 -0.003225 3.628675 -0.869125 0.5018 -2.276825 -0.309225 -3.144175 -1.811475 -0.86735 -1.50225 -0.8659 -3.12685 0.003225 -3.62865 0.869125 -0.501825 2.276825 0.3092 3.144175 1.81145Z" stroke-width="0.25"></path>
    <path fill="#8a3391" d="M22.45775 11.524125c0.86725 -1.502225 0.865925 -3.12685 -0.003225 -3.62865 -0.869125 -0.501825 -2.276825 0.3092 -3.144175 1.811475 -0.86735 1.50225 -0.8659 3.126825 0.003225 3.62865 0.869125 0.501825 2.276825 -0.3092 3.144175 -1.811475Zm0.000175 3.2151c0.869075 0.5018 0.870625 2.1264 0.003225 3.62865 -0.86735 1.50225 -2.27505 2.313275 -3.144175 1.81145 -0.869125 -0.5018 -0.870575 -2.126425 -0.003225 -3.62865 0.86735 -1.50225 2.27505 -2.313275 3.144175 -1.81145ZM16.536225 18.157875c0.86915 0.501825 0.8706 2.126425 0.00325 3.628675 -0.86735 1.502125 -2.275075 2.313225 -3.1442 1.81145 -0.869125 -0.50175 -0.870575 -2.126425 -0.003225 -3.62865 0.867375 -1.502275 2.27505 -2.3133 3.144175 -1.811475Zm-0.003325 -6.843775c0.869125 0.5018 0.870575 2.126425 0.003225 3.628675s-2.27505 2.313275 -3.1442 1.811475c-0.869125 -0.501825 -0.870575 -2.126425 -0.003225 -3.628675 0.86735 -1.502275 2.27505 -2.313275 3.1442 -1.811475Z" stroke-width="0.25"></path>
    <path fill="#f7bf2a" d="M15.138225 2.06721c0 1.003615 -1.40625 1.817215 -3.14095 1.817215 -1.7347 0 -3.14095 -0.8136 -3.14095 -1.817215C8.856325 1.06359 10.262575 0.25 11.997275 0.25c1.7347 0 3.14095 0.81359 3.14095 1.81721ZM9.2166 5.482375c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172s1.40625 -1.817225 3.14095 -1.817225c1.7347 0 3.14095 0.8136 3.14095 1.817225Zm8.71005 1.8172c1.7347 0 3.14095 -0.813575 3.14095 -1.8172s-1.40625 -1.817225 -3.14095 -1.817225c-1.7347 0 -3.14095 0.8136 -3.14095 1.817225s1.40625 1.8172 3.14095 1.8172Zm-2.788425 1.605625c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172 0 -1.0036 1.40625 -1.8172 3.14095 -1.8172 1.7347 0 3.14095 0.8136 3.14095 1.8172Z" stroke-width="0.25"></path>
    </svg>}
  >
    Declare templates in your Pulumi programs
  </Card>
</CardGroup>

## Configuration

The default `values.yaml` for this template:

```yaml theme={null}
image: mysql:9 # versions before mysql:9 are compatible but do not support backup feature

resources:
  minCpu: 100m
  maxCpu: 400m
  minMemory: 128Mi
  maxMemory: 512Mi

timeoutSeconds: 15

config:
  db: test
  rootPassword: root-password
  user: username
  password: password

internalAccess:
  type: same-gvc # options: none, same-gvc, same-org, workload-list
  workloads: # Note: can only be used if type is same-gvc or workload-list
    #- //gvc/GVC_NAME/workload/WORKLOAD_NAME

volumeset:
  capacity: 10 # initial capacity in GiB (minimum is 10)
  autoscaling:
    enabled: false
    maxCapacity: 100 # Maximum capacity in GiB
    minFreePercentage: 10 # Trigger scaling when free space drops below this percentage
    scalingFactor: 1.2 # Multiply current capacity by this factor when scaling up

enablePhpMyAdmin: false

backup: # compatible with MySQL 9+
  enabled: true
  image: controlplanecorporation/mysql-backup:9.1 # tag 9.1 = MySQL 9 compatible
  schedule: "0 2 * * *" # daily at 2am UTC

  resources:
    cpu: 100m
    memory: 128Mi

  provider: aws # Options: aws or gcp

  aws:
    bucket: mysql-backup-bucket
    region: us-east-1
    cloudAccountName: mysql-backup-cloudaccount
    policyName: mysql-backup-policy
    prefix: mysql/backups # Folder path within the bucket

  gcp:
    bucket: mysql-backup-bucket
    cloudAccountName: mysql-backup-cloudaccount
    prefix: mysql/backups
```

### Credentials

* `config.db` — Name of the database created on startup.
* `config.rootPassword` — Password for the MySQL root user. **Change before deploying to production.**
* `config.user` — Name of the non-root database user created on startup.
* `config.password` — Password for the non-root user. **Change before deploying to production.**

<Note>
  These values are only applied on first startup when the data directory is empty. Updating them after the initial deployment will have no effect on the running database. To change credentials or the database name on an existing instance, use MySQL's native commands (e.g. `ALTER USER`, `RENAME DATABASE`).
</Note>

### Resources

* `resources.minCpu` / `resources.minMemory` — Minimum CPU and memory guaranteed to the workload.
* `resources.maxCpu` / `resources.maxMemory` — Maximum CPU and memory the workload can use.
* `timeoutSeconds` — Workload timeout in seconds.

### Storage

* `volumeset.capacity` — Initial volume size in GiB (minimum 10).
* `volumeset.autoscaling.enabled` — Automatically expand the volume as it fills. When enabled:
  * `maxCapacity` — Maximum volume size in GiB.
  * `minFreePercentage` — Trigger a scale-up when free space drops below this percentage.
  * `scalingFactor` — Multiply the current capacity by this factor when scaling up.

### Internal Access

* `internalAccess.type` — Controls which workloads can connect to MySQL on port `3306`:

| Type            | Description                                                     |
| --------------- | --------------------------------------------------------------- |
| `none`          | No internal access allowed                                      |
| `same-gvc`      | Allow access from all workloads in the same GVC                 |
| `same-org`      | Allow access from all workloads in the same organization        |
| `workload-list` | Allow access only from specific workloads listed in `workloads` |

### phpMyAdmin

* `enablePhpMyAdmin` — When `true`, deploys a phpMyAdmin workload for browser-based database management.

### Backup

Set `backup.enabled: true` to enable scheduled database dumps to object storage. The backup feature requires MySQL 9+.

Set `backup.provider` to `aws` or `gcp` and fill in the corresponding section. The `prefix` field controls the folder path within the bucket where backups are stored.

### Restoring a Backup

To restore from a backup, run the following from a client with access to the bucket:

**AWS S3**

```bash theme={null}
export MYSQL_PWD="ROOT_PASSWORD"

aws s3 cp "s3://BUCKET_NAME/PREFIX/BACKUP_FILE.sql.gz" - \
  | gunzip \
  | mysql \
      --host=WORKLOAD_NAME \
      --port=3306 \
      --user=root \
      DATABASE_NAME

unset MYSQL_PWD
```

**GCS**

```bash theme={null}
export MYSQL_PWD="ROOT_PASSWORD"

gsutil cp "gs://BUCKET_NAME/PREFIX/BACKUP_FILE.sql.gz" - \
  | gunzip \
  | mysql \
      --host=WORKLOAD_NAME \
      --port=3306 \
      --user=root \
      DATABASE_NAME

unset MYSQL_PWD
```

### Connecting to MySQL

Once deployed, connect to the database from within the same GVC using:

```text theme={null}
RELEASE_NAME-mysql.GVC_NAME.cpln.local:3306
```

## External References

<CardGroup cols={2}>
  <Card title="MySQL Documentation" icon="book" href="https://dev.mysql.com/doc/">
    Official MySQL documentation
  </Card>

  <Card title="phpMyAdmin Documentation" icon="database" href="https://www.phpmyadmin.net/docs/">
    phpMyAdmin user documentation
  </Card>

  <Card title="Cloud Accounts" icon="cloud" href="https://docs.controlplane.com/guides/create-cloud-account">
    Create a Control Plane Cloud Account for backup storage access
  </Card>

  <Card title="Backup Image Source" icon="github" href="https://github.com/controlplane-com/backup-images/tree/main/mysql-backup">
    Source code for the MySQL backup container image
  </Card>

  <Card title="MySQL Template" icon="github" href="https://github.com/controlplane-com/templates/tree/main/mysql">
    View the source files, default values, and chart definition
  </Card>
</CardGroup>
