Skip to content

Docker containers

Joinery watches Docker for containers running one of the three engines it speaks, and gives you a panel to start, stop, connect to and create them. Docker is entirely optional — nothing else in the app depends on it.

The status bar carries a container glyph. Its colour is the whole state, and its tooltip is the sentence:

State Tooltip
Still asking Checking Docker…
Docker cannot be reached Docker is not available
Docker is installed but down Docker’s own reason, or Docker is not running
Running, no containers Docker is running — no database containers
Running, with containers Docker: 1 of 2 database containers running

A count sits beside the glyph only when at least one container is up — a grey glyph with a 0 next to it says nothing the glyph did not.

Clicking the pip opens the panel; so does ⌘K ▸ Docker containers, which opens it rather than toggling it. Escape closes it.

Joinery re-reads Docker every 30 seconds, and the pip, the panel and the welcome tab’s Docker line all read the same answer — they cannot disagree with each other.

The engine is decided from the image name, not from anything Docker says about the container:

Engine Image contains Port inside the container
SQL Server mssql, sqlserver, azure-sql-edge 1433
PostgreSQL postgres, postgis 5432
MySQL mysql, mariadb 3306

Anything else is not listed. All three engines count equally — the panel is not SQL Server-only.

Database containers, with a Refresh button that re-reads Docker immediately.

Each row carries the container’s name, its engine, :<host port> → <container port> (or no published port), and Docker’s own status line verbatim — Up 3 hours, Exited (0) 2 days ago. A filled pip marks a running container. Running containers are listed first, then alphabetically.

Any bind mounts the container has are listed under it as host path → container path, with (read-only) where that applies.

Under the list, a Volumes section names the named Docker volumes those database containers mount — the ones docker volume ls shows. Only those: a volume mounted by some other container, or by nothing at all, is not listed, and the section is absent entirely when the database containers only bind-mount.

A stopped container gets a Start button. A running one gets Stop and Connect.

Connect opens the connection editor with localhost and the container’s published port already filled in — you still choose the engine, the credentials and the name. It is disabled on a container that publishes no port, and says so: This container publishes no port, so nothing can connect to it.

If Docker refuses either action, the toast names the container and carries Docker’s own reason rather than a generic failure. A container that had already stopped by the time you pressed Stop is not a failure and is not reported as one. Either way the container list is re-read afterwards, so the row shows what actually happened, and ⌘J opens the output panel where the same error is logged with its full detail.

New container opens a short form, and it is SQL Server only. The panel says so above the button. Joinery’s create path sets ACCEPT_EULA=Y and MSSQL_SA_PASSWORD and publishes container port 1433 whatever image it is handed, so there is no image picker — one would produce containers that do not work.

Three fields:

Field Rule
Container name Letters, numbers, dots, dashes and underscores, starting with a letter or number, and not a name already in use. Defaults to joinery-mssql.
SA password At least 8 characters, and three of: an upper-case letter, a lower-case letter, a digit, a symbol.
Host port 1024–65535, and not a port another container already publishes. Defaults to 1433.

The password rule is SQL Server’s own, and it is checked before the round trip on purpose: docker create succeeds on a password SQL Server rejects, and the container then exits immediately — so the honest place to catch it is the form.

Above the button, in words: creating the container accepts the Microsoft SQL Server EULA and pulls mcr.microsoft.com/mssql/server:2022-latest if it is not already present.

The password is cleared from the form as soon as it has been sent — on success and on failure alike. A refused create leaves the form open so you can fix the name, but not the secret you typed into it.

The panel shows Meaning
Docker is not available Joinery could not reach the Docker socket. Install Docker Desktop, or start it.
Docker is not running Docker’s own reason, or Start Docker Desktop and press Refresh.
No database containers Docker is running, but nothing it holds looks like one of the three engines.

In either of the first two states the New container footer is hidden — there is nothing to create it with.

If Docker is running for you and Joinery says otherwise, Docker is not detected explains what the app asks Docker and why the answer can differ from your terminal’s.

Where this page's facts come from
Claim Source
The pip lives in the status bar and anchors the panel packages/renderer/src/shell/status-bar.tsx:410-414, features/docker/docker-pip.tsx:57-102
The five pip states and their exact tooltips packages/renderer/src/features/docker/docker-model.ts:114-175
The colour per state, with no brand colours packages/renderer/src/features/docker/docker-pip.tsx:34-41
The count renders only above zero packages/renderer/src/features/docker/docker-pip.tsx:67-73
⌘K ▸ “Docker containers” opens rather than toggles packages/renderer/src/commands/catalogue.ts:657-665, docker-pip.tsx:53-55
Escape closes the popover packages/renderer/src/ui/popover.tsx:12-50, 127-134
Docker is polled every 30 seconds packages/renderer/src/features/docker/use-docker.ts:26, 51-82
The pip, panel and welcome tab share one query packages/renderer/src/features/docker/use-docker.ts:1-16, features/welcome/welcome-panel.tsx:282-295
The engine is derived from the image name, per engine packages/renderer/src/features/docker/docker-model.ts:60-68
The port inside the container is derived from the engine, not believed packages/renderer/src/features/docker/docker-model.ts:16-20, 41-46
All three engines are listed, not SQL Server only packages/renderer/src/features/docker/docker-panel.tsx:6-9, 151-161
The panel’s heading and its Refresh packages/renderer/src/features/docker/docker-panel.tsx:50-66
A row’s name, engine, port pair and Docker status line packages/renderer/src/features/docker/docker-panel.tsx:222-234
The status string is shown verbatim and never matched on packages/renderer/src/features/docker/docker-model.ts:77-79, 97-98
Running containers sort first, then alphabetically packages/renderer/src/features/docker/docker-model.ts:106-112
Bind mounts are listed, with a read-only marker packages/renderer/src/features/docker/docker-panel.tsx:235-251
Named volumes are listed, filtered to the database containers’ mounts packages/main/src/services/docker/detector.ts (listVolumes), docker-panel.tsx:177-190
Start, Stop and Connect, and which appears when packages/renderer/src/features/docker/docker-panel.tsx:253-312
Connect pre-fills the connection editor with localhost and the port packages/renderer/src/features/docker/docker-panel.tsx:266-296, features/connections/connection-dialogs.tsx:94-96
It is disabled with a stated reason when no port is published packages/renderer/src/features/docker/docker-panel.tsx:272-291
A refused start or stop carries Docker’s own reason packages/main/src/ipc/docker.ipc.ts:40-60, packages/renderer/src/features/docker/use-docker.ts:128-156
A container that had already stopped is not reported as a failure packages/main/src/services/docker/detector.ts:170-203, 343-351
The container list is re-read after either action packages/renderer/src/features/docker/use-docker.ts:137, 152
The create call sets ACCEPT_EULA, MSSQL_SA_PASSWORD and binds 1433 packages/main/src/services/docker/detector.ts:233-248
The create form is SQL Server only, and the panel says so packages/renderer/src/features/docker/docker-panel.tsx:90-99, 318-325
The three fields, their defaults and their rules packages/renderer/src/features/docker/docker-panel.tsx:41, 342-344, docker-model.ts:187-220
Why the password is checked before the round trip packages/renderer/src/features/docker/docker-model.ts:177-186
The EULA sentence and the image it pulls packages/renderer/src/features/docker/docker-panel.tsx:420-424
The password is cleared on success and on failure alike packages/renderer/src/features/docker/docker-panel.tsx:363-368
The three empty states and their copy packages/renderer/src/features/docker/docker-panel.tsx:117-160
The New container footer is hidden when Docker is absent or stopped packages/renderer/src/features/docker/docker-panel.tsx:74-103