Docker · MySQL · Laravel

Connect a MySQL GUI to Docker (and Laravel Herd)

pimvdmolen.nl · · ~9 min read

Local MySQL in Docker (or Laravel Herd’s database services) is perfect until your GUI cannot connect and the terminal somehow can. This walkthrough shows how to connect a MySQL GUI to Docker cleanly: host, port, user, socket traps, and the differences between containers and tools like Herd.

The 30-second mental model

Your GUI does not talk to “the container.” It talks to a host + port (or a Unix socket) on your machine that Docker published.

Typical Compose snippet:

services:
  mysql:
    image: mysql:8.4
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: app

Inside the container MySQL listens on 3306. On your Mac/PC you connect to 127.0.0.1:3307.

That host-port remapping is the number one source of “GUI failed, CLI worked” confusion.

Connection settings that usually work

Field Docker example Notes
Host 127.0.0.1 Prefer this over localhost on Mac/Linux
Port 3307 (example) The left side of 3307:3306
User root or app user Must match container env/init
Password from Compose/MYSQL_ROOT_PASSWORD Quotes/spaces in .env cause silent mismatches
Database app or empty Empty lets you see all schemas you may access

Why 127.0.0.1 beats localhost

On many Mac/Linux setups, localhost can mean “try a Unix socket first.” Your Docker MySQL is on TCP. GUIs that follow socket semantics then fail in ways that look like auth bugs. Use 127.0.0.1 unless you intentionally configured a socket.

Step-by-step in a desktop client

  1. Start the stack (docker compose up -d)
  2. Confirm the published port: docker compose ps or docker port ...
  3. Create a new connection in your MySQL GUI
  4. Set host 127.0.0.1, the published port, user, password
  5. Click Test connection before saving
  6. Open a table or run SELECT VERSION();

TabulaSQL follows that flow: save encrypted connections, test first, then browse schemas like any remote server.

Laravel Herd / local PHP stacks

Herd users often run MySQL via Herd’s services or a project container. Rules of thumb:

  • Herd’s MySQL is usually on 127.0.0.1:3306 unless you changed it
  • a project Compose file may still publish 3307 or another port; do not assume 3306
  • create separate GUI connections named Herd MySQL and Project Docker so you never edit the wrong server

If you also clone GUI tools into Herd for browser use, keep database connections pointed at the DB service, not at the site vhost.

Auth plugin surprises (MySQL 8+)

MySQL 8 defaults can produce “plugin” or auth errors with older clients. Fixes that work in practice:

  • upgrade the GUI/client
  • create a user with an auth plugin your toolchain expects
  • connect with a dedicated app user instead of root when possible
CREATE USER 'app'@'%' IDENTIFIED BY 'secret';
GRANT ALL ON app.* TO 'app'@'%';
FLUSH PRIVILEGES;

Lock % down for anything beyond local Docker.

Troubleshooting matrix

Connection refused

  • container not running
  • wrong published port
  • binding only on an internal Docker network without ports:

Access denied

  • wrong password (check .env vs Compose)
  • user not allowed from your client host (user@% vs [email protected])
  • connecting to Herd’s MySQL while using Docker credentials (or the reverse)

Empty schema list

  • connected to the wrong port/instance
  • user lacks privileges
  • you restricted the connection to a database name that does not exist yet

Works in TablePlus/CLI, fails in another GUI

Compare host (localhost vs 127.0.0.1), port, SSL off for local, and SSH accidentally enabled for a local container.

Soft habits that prevent pain

  • name connections after the environment (docker-app, herd-local, staging-ssh)
  • store passwords encrypted in the client
  • keep a read-only user for shared staging even if local root is fine
  • document the published port in the project README

Recommendation

Treat Docker MySQL like any TCP server: 127.0.0.1, published port, explicit user. Once that clicks, every GUI behaves. If you want a free MySQL/MariaDB desktop client for that daily local loop, try TabulaSQL.

Related

Frequently asked questions

Use 127.0.0.1 and the published host port from Docker Compose (the left side of ports: "3307:3306"). Inside the container MySQL still listens on 3306.

On many Mac/Linux setups localhost may try a Unix socket first. Docker MySQL is reached over TCP, so 127.0.0.1 avoids the socket path.

Better to save two named connections. Herd and project containers often use different ports or credentials, and mixing them causes confusing access-denied errors.