Changing the TCP port for MySQL or MariaDB reduces exposure to default-port scans, avoids conflicts when multiple database instances share a host, and can satisfy network policies that prohibit listening on well-known ports.

The database daemon mysqld listens for TCP connections on the port defined by the port option under the [mysqld] section of its configuration. On Ubuntu and Debian systems, that configuration is typically assembled from multiple files under /etc/mysql, and the running listener reflects the effective merged settings at service start.

Changing the port affects every TCP client, load balancer, firewall rule, and health check that assumes 3306. A restart is required to bind the new port, and security layers may still block access (host firewall rules, cloud security groups, and SELinux port labeling on RHEL-family systems); avoid privileged ports below 1024 unless extra capabilities are intentionally configured.

Steps to change MySQL or MariaDB port:

  1. Choose an unused TCP port for mysqld, such as 3307.

    The default port is 3306, and MySQL X Protocol commonly uses 33060 via mysqlx_port.

  2. Confirm the current listening socket for mysqld.
    $ sudo docker exec sg-mysql ss -lntp | rg ':3306 '
    LISTEN 0      151       192.0.2.40:3306       0.0.0.0:*          

    No output usually means the service is stopped, TCP is disabled via skip-networking, or the listener is bound under a different name.

  3. Open the server configuration file that contains the [mysqld] section.
    $ sudoedit /etc/mysql/conf.d/port.cnf

    MariaDB commonly uses /etc/mysql/mariadb.conf.d/50-server.cnf on Ubuntu and Debian.

  4. Set the port option under [mysqld] to the new port.
    [mysqld]
    port = 3307

    Any client still targeting 3306 will fail to connect until connection settings are updated.

  5. Set the bind-address option under [mysqld] to the interface address that should accept TCP connections.
    [mysqld]
    bind-address = 192.0.2.40

    Setting bind-address to 0.0.0.0 exposes the port on all interfaces, which can unintentionally publish the database to untrusted networks.

  6. Restart the database service.
    $ sudo docker restart sg-mysql
    sg-mysql

    On non-container hosts, restart the systemd unit for MySQL or MariaDB.

  7. Check the service status for startup errors.
    $ sudo docker ps --filter name=sg-mysql --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
    NAMES      IMAGE       STATUS
    sg-mysql   mysql:8.0   Up 11 seconds
  8. Confirm mysqld is listening on the new port.
    $ sudo docker exec sg-mysql ss -lntp | rg ':3307 '
    LISTEN 0      151       192.0.2.40:3307       0.0.0.0:*          

  9. Allow inbound TCP traffic to the new port in UFW when remote clients must connect.
    $ sudo ufw allow 3307/tcp
    Rules updated
    Rules updated (v6)

    firewalld environments commonly use

    $ sudo firewall-cmd --permanent --add-port=3307/tcp

    followed by

    $ sudo firewall-cmd --reload

    .

  10. Remove any firewall rule that exposes the old port when it is no longer needed.
    $ sudo ufw delete allow 3306/tcp
    Could not delete non-existent rule
    Could not delete non-existent rule (v6)

    Removing the rule breaks any remaining legacy client still using 3306.

  11. Verify the configured port from inside the server.
    $ sudo mysql -e "SHOW VARIABLES LIKE 'port';"
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | port          | 3307  |
    +---------------+-------+

    The client binary may be mysql or mariadb, and local administrative logins may default to the Unix socket even after a TCP port change.

  12. Update application connection settings to use the new port.
    mysql -h db.example.net -P 3307 -u app -p
    
    JDBC: jdbc:mysql://db.example.net:3307/appdb
    PDO:  mysql:host=db.example.net;port=3307;dbname=appdb
  13. Test a TCP login using the new port.
    $ mysql -h 192.0.2.40 -P 3307 -u appuser -p --execute 'SELECT 1;'
    1
    1

    SELinux systems may require labeling the new port for mysqld (for example via semanage port) before remote TCP access succeeds.