0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
JPPINTO
  • Home
  • Blog
  • Certifications
  • About
  • Contact
  • Shop
  • Gallery
  • Current Setup
Contact

Search

July 3, 2026 / Linux, Servers, Ubuntu

Install and Configure MySQL on Ubuntu for WordPress

Tags: database, linux, mysql, server setup, ubuntu, wordpress
Featured image for Install and Configure MySQL on Ubuntu for WordPress

MySQL is a common database choice for WordPress and many PHP applications. On Ubuntu, you can install it from the default package repositories and then apply a small performance configuration for local web hosting.

This guide uses generic placeholders for usernames and passwords. Do not hard-code real production passwords in public scripts, documentation, Git repositories, or screenshots.

What the Script Does

The deployment script this article is based on:

  • Installs mysql-server.
  • Enables and starts the MySQL service.
  • Creates an admin user for local socket access.
  • Backs up the MySQL configuration.
  • Writes a custom performance config file.
  • Validates the MySQL configuration.
  • Restarts MySQL and tests login again.

Install MySQL

Run:

sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt install -y mysql-server
sudo systemctl enable mysql
sudo systemctl start mysql
sudo systemctl is-active --quiet mysql

You can open the MySQL shell as root with:

sudo mysql

Create an Admin User

Use your own username and a strong password:

MYSQL_ADMIN_USER="dbadmin"
MYSQL_ADMIN_PASSWORD="<REPLACE_WITH_STRONG_PASSWORD>"

Create the user:

sudo mysql <<MYSQL_SCRIPT
CREATE USER IF NOT EXISTS '${MYSQL_ADMIN_USER}'@'localhost' IDENTIFIED BY '${MYSQL_ADMIN_PASSWORD}';
GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_ADMIN_USER}'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
MYSQL_SCRIPT

Test the user:

mysql --protocol=socket -u "${MYSQL_ADMIN_USER}" -p -e "SELECT VERSION();"

Type the password when prompted.

Avoid putting the real password directly on the command line, because command-line arguments may be visible in shell history or process listings.

Back Up the MySQL Config

Create a backup folder:

sudo mkdir -p /opt/server-backups/mysql
timestamp="$(date +%Y%m%d%H%M%S)"

Back up the main MySQL config if it exists:

if [ -f /etc/mysql/mysql.conf.d/mysqld.cnf ]; then
    sudo cp /etc/mysql/mysql.conf.d/mysqld.cnf "/opt/server-backups/mysql/mysqld.cnf.before.${timestamp}.bak"
fi

Write a Custom Performance Config

Create a custom config file:

sudo tee /etc/mysql/mysql.conf.d/99-custom-performance.cnf >/dev/null <<EOF
[mysqld]
port = 3306
bind-address = 127.0.0.1

innodb_buffer_pool_size = 4G
max_connections = 200
tmp_table_size = 256M
max_heap_table_size = 256M

innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
skip_name_resolve = ON
EOF

The bind-address = 127.0.0.1 setting keeps MySQL listening locally. That is a good default when web applications connect from the same server.

For remote administration, use an SSH tunnel instead of exposing MySQL directly to the internet.

Validate and Restart MySQL

Validate the config:

sudo mysqld --validate-config

If validation succeeds, restart MySQL:

sudo systemctl restart mysql
sudo systemctl is-active --quiet mysql

Test login again:

mysql --protocol=socket -u "${MYSQL_ADMIN_USER}" -p -e "SELECT VERSION();"

Back up the custom config:

sudo cp /etc/mysql/mysql.conf.d/99-custom-performance.cnf "/opt/server-backups/mysql/99-custom-performance.cnf.after.${timestamp}.bak"

Full Script

Here is the full Bash script used for this MySQL install workflow. The password value is intentionally shown as a placeholder; replace it before running the script:

#!/usr/bin/env bash

__show_script_usage() {
  cat <<'__SCRIPT_USAGE__'
# Install-MySQL.sh

Installs and configures MySQL for the Linux WordPress hosting stack.

## Example Usage

```bash
cd /opt/DevOps/Scripts
sudo bash ./Install-MySQL.sh
```

## Notes

This changes MySQL server configuration and restarts MySQL. It also writes backups under `/opt/DevOps/Backups/MySQL`.
__SCRIPT_USAGE__
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  case "${1:-}" in
    -h|--help|--usage)
      __show_script_usage
      exit 0
      ;;
  esac
fi

# ============================================================
# Variables
# ============================================================

MYSQL_ADMIN_USER="mysqladmin"
MYSQL_ADMIN_PASSWORD='<REPLACE_WITH_STRONG_PASSWORD>'

MYSQL_PORT="3306"
MYSQL_BIND_ADDRESS="127.0.0.1"

MYSQL_INNODB_BUFFER_POOL_SIZE="4G"
MYSQL_MAX_CONNECTIONS="200"
MYSQL_TMP_TABLE_SIZE="256M"
MYSQL_MAX_HEAP_TABLE_SIZE="256M"

DEVOPS_BACKUP_DIR="/opt/DevOps/Backups/MySQL"

# ============================================================
# Safety
# ============================================================

set -euo pipefail

echo "Installing and configuring MySQL..."

if [ "$EUID" -ne 0 ]; then
    echo "ERROR: Run with sudo."
    exit 1
fi

# ============================================================
# Install MySQL
# ============================================================

echo "Updating package lists..."
apt update

echo "Installing MySQL Server..."
DEBIAN_FRONTEND=noninteractive apt install -y mysql-server

echo "Enabling and starting MySQL..."
systemctl enable mysql
systemctl start mysql

echo "Checking MySQL service..."
systemctl is-active --quiet mysql

# ============================================================
# Create MySQL Admin User
# ============================================================

echo "Creating MySQL admin user for HeidiSQL..."

sudo mysql <<MYSQL_SCRIPT
CREATE USER IF NOT EXISTS '${MYSQL_ADMIN_USER}'@'localhost' IDENTIFIED BY '${MYSQL_ADMIN_PASSWORD}';
GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_ADMIN_USER}'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
MYSQL_SCRIPT

echo "Testing MySQL admin user..."

mysql --protocol=socket -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "SELECT VERSION();" >/dev/null

# ============================================================
# Backup Config
# ============================================================

echo "Creating MySQL backup directory..."
mkdir -p "${DEVOPS_BACKUP_DIR}"

TIMESTAMP="$(date +%Y%m%d%H%M%S)"

if [ -f /etc/mysql/mysql.conf.d/mysqld.cnf ]; then
    echo "Backing up original mysqld.cnf..."
    cp /etc/mysql/mysql.conf.d/mysqld.cnf "${DEVOPS_BACKUP_DIR}/mysqld.cnf.before.${TIMESTAMP}.bak"
fi

# ============================================================
# Configure MySQL
# ============================================================

echo "Writing MySQL performance configuration..."

cat > /etc/mysql/mysql.conf.d/99-custom-performance.cnf <<EOF
[mysqld]
port = ${MYSQL_PORT}
bind-address = ${MYSQL_BIND_ADDRESS}

innodb_buffer_pool_size = ${MYSQL_INNODB_BUFFER_POOL_SIZE}
max_connections = ${MYSQL_MAX_CONNECTIONS}
tmp_table_size = ${MYSQL_TMP_TABLE_SIZE}
max_heap_table_size = ${MYSQL_MAX_HEAP_TABLE_SIZE}

innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
skip_name_resolve = ON
EOF

cp /etc/mysql/mysql.conf.d/99-custom-performance.cnf "${DEVOPS_BACKUP_DIR}/99-custom-performance.cnf.after.${TIMESTAMP}.bak"

# ============================================================
# Validate Config
# ============================================================

echo "Validating MySQL configuration..."
mysqld --validate-config

# ============================================================
# Restart MySQL
# ============================================================

echo "Restarting MySQL..."
systemctl restart mysql

echo "Checking MySQL status..."
systemctl is-active --quiet mysql

echo "Testing MySQL admin user after restart..."

mysql --protocol=socket -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "SELECT VERSION();" >/dev/null

# ============================================================
# Complete
# ============================================================

echo "MySQL install and configuration complete."
echo "MySQL root access: sudo mysql"
echo "MySQL admin user: ${MYSQL_ADMIN_USER}"
echo "MySQL bind address: ${MYSQL_BIND_ADDRESS}"
echo "MySQL port: ${MYSQL_PORT}"
echo "Use HeidiSQL through SSH tunnel with host localhost and user ${MYSQL_ADMIN_USER}."

Troubleshooting

If MySQL does not restart, check:

sudo journalctl -u mysql -xe
sudo mysqld --validate-config

If login fails, confirm the user exists:

sudo mysql -e "SELECT user, host FROM mysql.user;"

Quick Reference

sudo apt install -y mysql-server
sudo systemctl enable mysql
sudo mysqld --validate-config
sudo systemctl restart mysql
sudo mysql

Keep database credentials private. Use placeholders in documentation, prompt for passwords when possible, and never publish real passwords in scripts.

Post Views: 106
<- Install PHP-FPM and Common PHP Extensions on Ubuntu
Install and Configure Redis on Ubuntu for Local Object Cache ->

Categories

  • Active Directory (5)
  • AI (3)
  • Amazon Cloud Services (1)
  • AWS (2)
  • Blazor (1)
  • C# (C-Sharp) (3)
  • CI/CD Pipelines (1)
  • Cloud (1)
  • Cloudflare (2)
  • Codex (1)
  • Containers (4)
  • Deployment (2)
  • Development (5)
  • DNS (1)
  • Docker (3)
  • Email (1)
  • Family (1)
  • General (5)
  • IIS 6.0 (4)
  • IIS 7.0 (10)
  • IIS 8.0 (1)
  • Infrastructure as Code (IaC) (1)
  • Kubernetes (3)
  • Linux (9)
  • Microsoft 365 (2)
  • MySQL (1)
  • Office 2010 (1)
  • PHP (1)
  • PowerShell (11)
  • Productivity (1)
  • Security (1)
  • Servers (9)
  • SharePoint 2007 (8)
  • SharePoint 2010 (19)
  • SharePoint 2013 (2)
  • SharePoint Online (1)
  • SMTP (4)
  • SQL Server 2008 (1)
  • SQL Server 2008 R2 (1)
  • SQL Server 2012 (2)
  • SQL Server 2019 (1)
  • SSL (1)
  • Travel (1)
  • Troubleshooting (1)
  • Ubuntu (9)
  • Uncategorized (1)
  • URL Rewrite (2)
  • Visual Studio 2019 (1)
  • Visual Studio Code (1)
  • Windows 10 (7)
  • Windows 2003 (9)
  • Windows 2008 (18)
  • Windows 2012 (6)
  • Windows 7 (3)
  • Windows Firewall (1)
  • Windows Vista (1)
  • WordPress (3)
  • WP-CLI (3)

Recent Posts

  • GPT-5.6 Sol Changes How We Prompt—and How We Write AGENTS.md
  • Protect a Domain That Does Not Send Email with SPF, DMARC, and Null MX
  • Turning Our Atlanta Vacation Photos into a Video with PowerShell
  • Bulk Create Cloudflare Origin CA Certificates with PowerShell
  • Test a Cloudflare Global API Key Connection with PowerShell

Advertisement

Tags

agents.md ai coding agents aws bash cloudflare cloud storage codex context engineering developer workflow dev to production dns externalize blob externalize sharepoint data full installation http redirect https IIS IIS installation index server configuration installing cumulative updates linux load balance central administration microsoft 365 nginx powerpoint powershell redirect http to https s3 server setup sharepoint 2010 cumulative updates sharepoint 2010 farm build sharepoint 2010 farm configuration sharepoint 2010 farm installation sharepoint data externalization SMTP ssl storagepoint ubuntu web server windows Windows 7 windows server 2008 wordpress wp-cli x86
© 2026 JPPinto.com. All rights reserved.