Databases Azure

MySQL 9.7 LTS Community Server on Ubuntu 24.04 on Azure User Guide

| Product: MySQL 9.7 LTS on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of MySQL 9.7 LTS Community Server on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. MySQL is the world's most widely deployed open source relational database. It is fully ACID compliant, supports stored procedures, triggers, views, window functions, CTEs, JSON columns, full text search, and multi source replication. MySQL 9.7 is the first long term support release in the 9.x Innovation series, which introduced atomic DDL, invisible indexes, role based access control, hash join execution, and improvements to the query optimiser. LTS releases receive community patches and security fixes for five years, making 9.7 the right choice for production workloads where stability matters more than bleeding edge feature additions.

The image ships MySQL 9.7.0 installed from the official MySQL APT repository at repo.mysql.com. The GPG key is fingerprint verified at build time so the chain of trust is unambiguous. The MySQL data directory is intentionally empty in the shipped image. On every fresh customer virtual machine, a systemd drop in fires mysqld --initialize-insecure before the server starts, initialises the data directory with no embedded password, and then mysql-firstboot.service generates a strong random root password unique to that virtual machine, creates the default cloudimg database, and writes the credentials to /stage/scripts/mysql-credentials.log. This pattern means no two virtual machines ever share a root password and no password is baked into the image at any point.

What is included:

  • MySQL 9.7.0 Community Server, installed from the official MySQL APT repository

  • Listener on TCP port 3306 and X Protocol on TCP port 33060

  • mysql command line client and standard MySQL utilities (mysqldump, mysqladmin, mysqlcheck, mysqlimport) at /usr/bin/

  • Per VM root password generated on first boot, written to /stage/scripts/mysql-credentials.log

  • Default cloudimg database created on first boot with utf8mb4 character set and utf8mb4_unicode_ci collation

  • Systemd service mysql.service for automatic startup on boot

  • Idempotent data directory initialisation via mysql.service drop in, safe across reboots and snapshots

  • Helper scripts at /usr/local/sbin/mysql-start.sh and /usr/local/sbin/mysql-stop.sh

  • 24/7 cloudimg support with guaranteed 24 hour response SLA

Prerequisites

Before deploying this image, ensure you have:

  • An active Azure subscription

  • A subscription to the MySQL 9.7 LTS Community Server on Ubuntu 24.04 listing on Azure Marketplace

  • An SSH public key for virtual machine authentication

  • Familiarity with Azure virtual machine management and SSH

  • A virtual network and subnet in the target region (or be willing to create one in the deploy wizard)

Recommended virtual machine size: Standard_D2s_v3 (2 vCPU, 8 GB RAM). MySQL benefits from available RAM for the InnoDB buffer pool. The D series provides a consistent baseline that is suitable for small to medium production workloads. For very small development or staging environments, Standard_B2s (2 vCPU, 4 GB RAM) is also sufficient.

Step 1: Deploy the Virtual Machine from the Azure Portal

Navigate to Marketplace in the Azure Portal, search for MySQL 9.7 LTS, and select the cloudimg publisher entry. Click Create to begin the wizard.

On the Basics tab choose your subscription, target resource group, and region. Set the virtual machine name. Choose SSH public key as the authentication type, set the username to a name of your choice (the examples below use azureuser), and paste your SSH public key. Standard_D2s_v3 is the recommended starting size.

On the Disks tab set the OS disk type to Standard SSD. MySQL data lives at /var/lib/mysql on the root disk by default. If your database working set is larger than a few gigabytes, attach a separate data disk and bind mount it over /var/lib/mysql before starting the service.

On the Networking tab select your existing virtual network and subnet. Attach a network security group that allows inbound TCP 22 from your management IP range and inbound TCP 3306 only from application server subnets or the virtual network CIDR. Do not expose port 3306 to the public internet. The root password is written in plain text on the virtual machine by design so you can read it without a second trip; an internet exposed MySQL port would make brute force attacks trivial.

On the Management, Monitoring, and Advanced tabs the defaults are appropriate. Click Review + create, wait for validation to pass, then click Create. Deployment takes around two minutes.

Step 2: Deploy the Virtual Machine from the Azure CLI

If you prefer the command line, use the gallery image resource identifier as the source. The exact resource identifier is published on your Partner Center plan. A representative invocation:

RG="mysql-prod"
LOCATION="eastus"
VM_NAME="mysql-01"
ADMIN_USER="azureuser"
GALLERY_IMAGE_ID="/subscriptions//resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/mysql-9-7-lts-ubuntu-24-04/versions/"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"

az group create --name "$RG" --location "$LOCATION"

az network vnet create \
  --resource-group "$RG" \
  --name mysql-vnet \
  --address-prefix 10.70.0.0/16 \
  --subnet-name mysql-subnet \
  --subnet-prefix 10.70.1.0/24

az network nsg create --resource-group "$RG" --name mysql-nsg

az network nsg rule create \
  --resource-group "$RG" --nsg-name mysql-nsg \
  --name allow-ssh-mgmt --priority 100 \
  --source-address-prefixes "" \
  --destination-port-ranges 22 --access Allow --protocol Tcp

az network nsg rule create \
  --resource-group "$RG" --nsg-name mysql-nsg \
  --name allow-mysql-vnet --priority 110 \
  --source-address-prefixes 10.70.0.0/16 \
  --destination-port-ranges 3306 --access Allow --protocol Tcp

az vm create \
  --resource-group "$RG" \
  --name "$VM_NAME" \
  --image "$GALLERY_IMAGE_ID" \
  --size Standard_D2s_v3 \
  --storage-sku StandardSSD_LRS \
  --admin-username "$ADMIN_USER" \
  --ssh-key-values "$SSH_KEY" \
  --vnet-name mysql-vnet --subnet mysql-subnet \
  --nsg mysql-nsg \
  --public-ip-address "" \
  --os-disk-size-gb 32

The --public-ip-address "" flag keeps the database off the public internet. Use a bastion host or your existing private connectivity to reach it.

Step 3: Connect via SSH

After deployment, find the private IP of the new virtual machine. From a host inside the same virtual network:

ssh azureuser@```

The first login may take a few seconds while cloud init finalises. Once you have a shell, `mysql.service` will have already started and `mysql-firstboot.service` will have already run, generating the per VM root password and creating the `cloudimg` database. Both services are one time operations gated by a sentinel file so they do not repeat on subsequent reboots.

## Step 4: Retrieve the Root Password

The root password has been randomly generated on this specific virtual machine and written to a root only file. Read it with:

```bash
sudo cat /stage/scripts/mysql-credentials.log

You will see lines similar to:

port=3306
socket=/var/run/mysqld/mysqld.sock
default_database=cloudimg
root_password=
connect_command=mysql -u root -p'' -h 127.0.0.1 -P 3306

Store the value of root_password= in your secret store. You can shred the credentials file once the password is saved, but keeping it root protected at mode 0600 is a reasonable default for the life of the virtual machine.

Step 5: Connect Locally with the mysql Client

Export the root password and socket path as shell variables so you do not need to type them repeatedly:

export MYSQL_ROOT_PW="$(sudo awk -F= '/^root_password=/{print $2}' /stage/scripts/mysql-credentials.log)"
export MYSQL_SOCKET="/var/run/mysqld/mysqld.sock"

Connect to the server via the Unix socket:

mysql -u root -p"${MYSQL_ROOT_PW}" --socket="${MYSQL_SOCKET}"

You should see a prompt of the form:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 9.7.0 MySQL Community Server - GPL

mysql>

Run SELECT VERSION(); to confirm the server version, then \q to exit.

Step 6: Create a Table, Insert a Row, and Query

The default cloudimg database is ready to use from first boot. Run the canonical SQL round-trip to verify the full stack:

mysql -u root -p"${MYSQL_ROOT_PW}" --socket="${MYSQL_SOCKET}" cloudimg ' -h  -P 3306 cloudimg

If the application server is in the same virtual network the TCP connection will succeed with the default caching_sha2_password plugin using TLS negotiated automatically by the MySQL protocol. If you see Authentication plugin 'caching_sha2_password' cannot be loaded, upgrade the client to MySQL Connector 8.0.3 or later.

Step 8: Server Components

Component Path

MySQL server daemon /usr/sbin/mysqld

mysql CLI client /usr/bin/mysql

mysqldump backup utility /usr/bin/mysqldump

mysqladmin admin utility /usr/bin/mysqladmin

MySQL data directory /var/lib/mysql/

MySQL socket /var/run/mysqld/mysqld.sock

MySQL error log /var/log/mysql/error.log

Systemd unit /usr/lib/systemd/system/mysql.service

cloudimg init drop in /etc/systemd/system/mysql.service.d/cloudimg-init.conf

Firstboot systemd unit /etc/systemd/system/mysql-firstboot.service

Firstboot script /usr/local/sbin/mysql-firstboot.sh

Start helper /usr/local/sbin/mysql-start.sh

Stop helper /usr/local/sbin/mysql-stop.sh

Credentials file /stage/scripts/mysql-credentials.log

Firstboot sentinel /var/lib/mysql/.firstboot-done

Build version record /stage/scripts/BUILD_VERSIONS

The exact installed version is recorded in /stage/scripts/BUILD_VERSIONS. Inspect it with:

cat /stage/scripts/BUILD_VERSIONS

Expected output:

mysql-server=9.7.0-1ubuntu24.04

Step 9: Filesystem Layout

Mount point Size Description

/ 32 GB Root filesystem (includes /var/lib/mysql)

/boot 1 GB Operating system kernel files

/var/lib/mysql (on root) MySQL data directory

For production workloads attach a separate Premium SSD data disk, format it with ext4 or xfs, and bind mount it over /var/lib/mysql before starting the service. This keeps database I/O off the OS disk, improves IOPS, and allows independent resize and snapshot of the data volume.

Step 10: Managing the MySQL Service

MySQL is started and stopped by systemd via the mysql.service unit.

Check service status:**

systemctl status mysql.service

Stop MySQL:

sudo /usr/local/sbin/mysql-stop.sh

Start MySQL:

sudo /usr/local/sbin/mysql-start.sh

Restart MySQL:

sudo systemctl restart mysql.service

View the MySQL error log:

sudo tail -n 50 /var/log/mysql/error.log

Step 11: Troubleshooting

Cannot connect to MySQL on port 3306

  • Verify the service is running: systemctl status mysql.service

  • Verify the listener is bound: ss -tln | grep 3306

  • Check the error log: sudo tail -n 50 /var/log/mysql/error.log

  • Confirm the network security group allows TCP 3306 from your client source IP

  • Confirm the virtual machine's NIC is in the expected subnet with the NSG attached

Authentication errors after connecting

  • Re read the password from the credentials file: sudo awk -F= '/^root_password=/{print $2}' /stage/scripts/mysql-credentials.log

  • Ensure the shell variable was not truncated (the password is 32 characters)

  • Verify the firstboot sentinel exists: ls -la /var/lib/mysql/.firstboot-done. If it is absent, mysql-firstboot.service did not complete; check its journal: journalctl -u mysql-firstboot.service --no-pager

Firstboot service did not run

  • Check the firstboot service status: systemctl status mysql-firstboot.service

  • Review the journal: journalctl -u mysql-firstboot.service --no-pager -n 50

  • Verify MySQL started first: systemctl status mysql.service

  • If MySQL failed to start, check whether the data directory was initialised: ls /var/lib/mysql/mysql/

  • If the data directory is empty, trigger initialisation manually: sudo mysqld --initialize-insecure --user=mysql

Remote clients cannot authenticate with caching_sha2_password

  • The client library must be MySQL Connector 8.0.3 or later, or the official MySQL C connector 8.0.3 or later

  • For legacy applications, create the account with the older plugin: CREATE USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY '';

  • The mysql_native_password plugin is available in 9.7 but is deprecated upstream; plan a migration to caching_sha2_password or authentication_fido for long lived accounts

Service fails to start

  • Check systemd journal: journalctl -u mysql.service --no-pager -n 50

  • Check the MySQL error log: sudo tail -n 50 /var/log/mysql/error.log

  • Check filesystem space: df -h /var/lib/mysql

  • Verify data directory ownership: ls -la /var/lib/mysql; files should be owned mysql:mysql

Step 12: Security Recommendations

  • Rotate the root password immediately after reading it from the credentials file:
mysql -u root -p"${MYSQL_ROOT_PW}" --socket="${MYSQL_SOCKET}" ';
FLUSH PRIVILEGES;
SQL
  • Create application specific users with minimal privileges, never connect application code as root

  • Restrict port 3306 to trusted application server subnets only in your NSG

  • Remove anonymous users: DELETE FROM mysql.user WHERE User=''; FLUSH PRIVILEGES;

  • Disable remote root login: DELETE FROM mysql.user WHERE User='root' AND Host != 'localhost'; FLUSH PRIVILEGES;

  • Enable the error log and monitor it for connection failures and authentication errors: /var/log/mysql/error.log

  • Back up regularly with mysqldump: mysqldump -u root -p"${MYSQL_ROOT_PW}" --socket="${MYSQL_SOCKET}" --all-databases > backup.sql

  • Keep MySQL updated by running sudo apt-get update && sudo apt-get upgrade mysql-server periodically; the official MySQL APT repository is already configured on this image

  • Shred the credentials file once the password is stored in your secret store: sudo shred -u /stage/scripts/mysql-credentials.log

Step 13: Support and Licensing

MySQL Community Server is released under the GNU General Public License version 2. There is no per core, per seat, or per server fee for the Community edition. MySQL is a registered trademark of Oracle Corporation.

cloudimg provides commercial support for this image separately from the upstream project. Contact us at any time for support questions, architectural advice, capacity planning, or migration help.

  • Email: support@cloudimg.co.uk

  • Website: www.cloudimg.co.uk

  • Support hours: 24/7 with guaranteed 24 hour response SLA

Deploy on Azure

Launch MySQL 9.7 LTS Community Server on Ubuntu 24.04 with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7.

support@cloudimg.co.uk