Someone was wrong on the internet, so I built a Temporal Docker extension

AUTHORS
Shy Ruparel
DATE
Jun 11, 2026
DURATION
10 MIN
  • Self-Hosted
  • Code Samples
  • Durable Execution

Naturally, I took that personally, remembered I used to teach Docker Extensions to devs, forgot just enough of the rules to make the first version wrong, and eventually built the thing properly.

A funny thing happened during a Temporal community session a few months back.

Someone said that building a Temporal Docker Desktop extension probably was not possible.

This was offered in a perfectly reasonable, community-minded way. Nobody was being dramatic. Nobody was throwing down a gauntlet. It was just one of those "yeah, I am not sure the platform can do that" comments that usually pass peacefully through a conversation and disappear.

Unfortunately, I heard it.

And my brain did the deeply healthy thing where it whispered: someone is wrong on the internet.

This is not always my most productive mode. Sometimes it leads to unnecessary tabs. Sometimes it leads to me reading specifications at hours when no one should be reading specifications. Occasionally, though, it leads to something useful.

In this case, it led to the Temporal Docker Desktop extension (https://github.com/temporal-community/docker-extension).

I had some history here#

The comment landed extra funny for me because I was the sole Developer Advocate at Docker when Docker Extensions launched. I helped teach the feature. I wrote some of the original tutorials for building them: Build Your First Docker Extension.

So when someone said a Temporal extension might not be possible, my reaction was not exactly neutral.

Selfie of Shy Ruparel with a co-MC Kat Speer for Dockercon 2022

Selfie of Shy Ruparel with a co-MC Kat Speer for Dockercon 2022

It was more like: wait, I know this system.

Getting started with Docker

Or at least, I knew this system four years ago, which is a very different flavor of knowing.

Four years is plenty of time for APIs to shift, design rules to get sharper, product expectations to become more real, and for me to forget the part of the docs that would have saved me from my first idea.

DockerCon 2022 stream still of the Shy Ruparel teaching Getting Started with Docker workshop

DockerCon 2022 stream still of Shy Ruparel teaching Getting Started with Docker workshop

Naturally, my first idea was an iframe.

The first version was too clever#

The earliest version of the extension embedded the Temporal UI directly inside Docker Desktop.

You can see why this was tempting. Temporal already has a good UI. Docker Desktop extensions can render UI. My brain connected those two dots with the confidence of a person who had not yet reread the current extension design guidance.

It worked.

And honestly, I was ready to ship it.

This is not one of those stories where I had a sudden, elegant product realization while staring thoughtfully out a window. The iframe version did the thing I wanted it to do, and part of me was delighted by how direct it was.

Then I got to the part where I needed to think about actually submitting it.

That is when I went back to the Docker docs, reread the extension design guidelines, and realized the clever version was probably going to get rejected. The Docker guidance is pretty clear about making extensions feel native to Docker Desktop, using the Docker theme, respecting the surrounding UI, and giving users clear actions instead of dumping an entire product surface into a panel.

Annoyingly, the docs were right.

Docs love doing that.

So I rebuilt it.

The better shape was not "Temporal UI, but trapped inside Docker Desktop." It was much smaller and more useful:

Start Temporal locally.

  • Know that it is running.
  • See the important endpoints.
  • Confirm the server is ready.
  • Get a quick glance at recent workflow activity.
  • Jump into the real Temporal UI when it is time to inspect anything seriously.

That last point matters.

The Temporal UI is already the right place to understand workflow history, event details, retries, task queues, and all the other machinery that makes Temporal useful. Rebuilding a miniature version of that inside Docker Desktop would have been worse for everyone, including me, and especially future me.

What the extension actually does#

The final extension is intentionally boring in the best way.

It does the same thing as the temporal server start-dev command we know and love, but it turns that terminal prompt into a button.

You open Docker Desktop, click Temporal, and click Start Server.

That is it.

You get a local Temporal server running from temporalio/temporal:latest, using server start-dev under the hood. The extension starts a temporal-dev container, exposes gRPC on localhost:7233, exposes Temporal Web on localhost:8233, and persists data in a Docker volume called temporal-dev-data.

The server uses SQLite at /data/temporal.db, because local development should not require a distributed systems ceremony just to learn a distributed systems tool.

There is a readiness panel that checks the pieces people actually care about:

  • Is the server running?
  • Is the gRPC endpoint ready?
  • Is the Web UI ready?
  • Is persistent data mounted?

There is also a worker status section, because once you start running workflows, the next natural question is: "Is anything polling this task queue, or am I just confidently yelling into the void?"

The extension lists recent workflows, but deliberately does not pretend to be the full workflow inspection experience. Each workflow row deep-links into Temporal UI. The header has quick links for running workflows and failed workflows. The big button says Open Temporal UI, because the real product decision here is not "hide Temporal UI inside Docker Desktop."

It is "make getting to Temporal UI feel immediate."

The extension is the front door. Temporal UI is the house.

The reset button exists because local dev is local dev#

There is also a Clear History button.

This is one of those features that sounds scary until you remember what local development is like.

Eventually you will start workflows with names like test-thing-final-2-for-real, point a worker at the wrong queue, restart something halfway through, or create enough experimental history that the most merciful thing you can do is throw the local database into the sea.

The extension lets you reset the local SQLite-backed Temporal data volume and restart cleanly. It asks you to type RESET, because deleting workflow history should involve at least one tiny moment of reflection.

Not a big one. We are not writing a novel about it.

Just enough friction to avoid "oops."

The UI became a real UI eventually#

I should also admit something: I am not a frontend engineer.

Early extension UI screenshot

Early extension UI screenshot

My original Docker extension tutorial UI looked exactly like what happens when a backend person is handed a component library and told, "Just make it usable." It was usable. It had buttons. Some of them were even in places.

Polished extension UI screenshot

Polished extension UI screenshot

This one looks better because I had Codex helping with the frontend pass, and because I have grown as a person.

Mostly the first thing.

The UI pass ended up being less about making it pretty and more about making it honest.

At one point, the troubleshooting logs lived as a footer below the workflow list. This seemed fine until the workflow list had actual workflows in it, at which point the footer was just stealing useful vertical space like a tiny real-estate speculator. So the logs moved into a Troubleshoot Startup dialog. They are there when you need them, out of the way when you do not.

The source code link started in the header, where it looked much more important than it was. That moved under Clear History, where it belongs: available, visible, but not shouting over the primary job of the extension.

The server status and server readiness panels started as separate boxes. They were redundant, so they became one Server panel. This is the kind of UI cleanup that feels obvious after you do it and somehow invisible before that.

There was also a surprisingly fussy screenshot pass, because the Marketplace screenshot should show the extension doing something real. I spun up a local Temporal server, created a bunch of running workflows, checked that the UI resized properly inside Docker Desktop, and captured the extension under actual load.

This is how you end up caring deeply about whether a scroll bar belongs to the page or the panel.

A glamorous life.

Why this matters#

Temporal already has a great local development path with temporal server start-dev. What this extension does is put that same familiar starting point somewhere developers are already used to being: Docker Desktop.

That matters because the first minute of trying a tool has a weird amount of power. If the first step is easy, people are more likely to keep going. With the extension, you click a button, get a local Temporal server with persistent SQLite storage, see enough health and workflow activity to know it is alive, and then jump into the actual Temporal UI when you want to do real work.

It is not trying to replace the CLI. It is not trying to replace the Temporal Web UI. It is just another front door. Temporal is fun quickly once you are actually running workflows. This just gives people one more familiar place to start.

The community part#

My favorite part of this whole thing is still the beginning.

Someone in the community wondered whether this was impossible, and instead of that being the end of the conversation, it became the start of a small, useful artifact.

That is the best version of community work to me. Not polished announcements. Not perfectly scoped roadmaps. Just people saying things out loud, someone getting curious, and a mildly unreasonable idea becoming real because enough of the pieces were already sitting nearby.

I had old Docker Extensions context. Temporal had a great local dev server and UI. Docker Desktop had the extension surface. Codex helped me sand down my frontend instincts. The community provided the spark.

The result is a small extension that does not try to be more than it is.

Honestly, I like that about it.

It starts Temporal. It tells you what is happening. It gets you into Temporal UI. It gets out of the way.

That is a pretty good shape for a tool.

Try it#

The source code is here:

github.com/temporal-community/docker-extension

You can search and install the extension directly from Docker Desktop. Once installed in Docker Desktop, open the Temporal extension, click Start Server, and you will have local Temporal running with:

  • gRPC at localhost:7233
  • Temporal Web at localhost:8233
  • persisted local state in temporal-dev-data
  • quick links into Temporal UI for workflow inspection

And if you ever make a mess locally, there is a Clear History button.

Use it with care.

Or, realistically, use it with the exact amount of confidence that got you into the mess in the first place.

Temporal Cloud

Ready to see for yourself?

Sign up for Temporal Cloud today and get $1,000 in free credits.

Build invincible applications

It sounds like magic, we promise it's not.