Restricting where MySQL or MariaDB listens reduces accidental exposure of the database service while still allowing controlled access from a private network, VPN, or SSH-tunneled workflow.

The mysqld server binds a TCP socket (commonly port 3306) based on values loaded from its configuration files. The bind-address directive under the [mysqld] section determines whether the daemon accepts TCP connections only from localhost, only from a specific host IP, or (when explicitly configured) from broader network scopes.

The bind-address value must be an IP address assigned to the host (IPv4 or IPv6), not an interface name like eth0. Moving beyond localhost affects exposure and routing, but does not grant access by itself; firewall policy and database account host permissions must also allow the connection, and the service must be restarted to apply the listener change.

Setting bind-address to 0.0.0.0 exposes the database on all IPv4 interfaces. Use this only when host firewall rules and database account restrictions are already in place, or the service may become internet-facing.

Steps to change the listen address for MySQL or MariaDB:

  1. Identify the IP address for the interface that should accept connections.
    $ sudo docker exec sg-mysql ip --brief address show scope global | rg '^eth0'
    eth0             UP             192.0.2.40/24
  2. Confirm the current listening address for TCP port 3306.
    $ sudo docker exec sg-mysql ss --listening --numeric --tcp --processes | rg ':3306 '
    LISTEN 0      151       192.0.2.40:3306       0.0.0.0:*          

    No output usually means the service is stopped, TCP listening is disabled via skip-networking, or the port is different.

  3. Locate the active configuration line that sets bind-address.
    $ sudo docker exec sg-mysql grep --recursive --line-number --extended-regexp '^[[:space:]]*bind-address' /etc/mysql
    /etc/mysql/conf.d/bind-address.cnf:2:bind-address = 192.0.2.40

    MariaDB commonly uses /etc/mysql/mariadb.conf.d/50-server.cnf for server settings on Debian/Ubuntu-style systems.

  4. Open the server configuration file that contains the active bind-address setting.
    $ sudoedit /etc/mysql/conf.d/bind-address.cnf
  5. Set bind-address under the [mysqld] section to the desired IP address.
    [mysqld]
    bind-address = 192.0.2.40

    Use 127.0.0.1 to accept local-only connections, or set a specific private IP for controlled remote access.

  6. Confirm the new bind-address setting is the only active definition in the loaded config files.
    $ sudo docker exec sg-mysql grep --recursive --line-number --extended-regexp '^[[:space:]]*bind-address' /etc/mysql
    /etc/mysql/conf.d/bind-address.cnf:2:bind-address = 192.0.2.40

    If multiple lines appear, the last-loaded file can override earlier values; comment out duplicates to keep the effective listener unambiguous.

  7. Restart the database service to apply the new listener.
    $ sudo docker restart sg-mysql
    sg-mysql

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

  8. Confirm mysqld is listening on the expected address.
    $ sudo docker exec sg-mysql ss --listening --numeric --tcp --processes | rg ':3306 '
    LISTEN 0      151       192.0.2.40:3306       0.0.0.0:*          
  9. Test a real connection to the new listener from an allowed client.
    $ mysql --host=192.0.2.40 --port=3306 --user=appuser --password --protocol=TCP --execute 'SELECT 1;'
    1
    1

    If the TCP connection opens but authentication fails, review user host permissions (for example, 'appuser'@'192.0.2.%').