I asked Claude and Gemini to build a Docker app—one was smoother, the other smarter

I've been vibe-coding small apps for a while now, and the biggest problem with them is that they live and die on the machine they were built on. Ideally, you'd want to self-host these apps so they're accessible across all your devices. So, this time, I'm testing Claude vs. Gemini to see which model does a better job of building a Dockerized app and making the self-hosting process as simple as possible.
A test to see which AI model builds better self-hosted apps
Which model is better at building Docker apps?

Lucas Gouveia/How-To Geek | pixalane/Aozorastock
Building small apps to streamline (or automate) your work is honestly one of the best uses of an LLM . Instead of burning tokens asking it to do the same repetitive thing over and over, you can have it build a tool once and use that tool instead. But these vibe-coded apps have a portability problem. They sit on one system as a couple of files—and while they might feel portable, they often aren't.
Whether a vibe-coded app will run on another system often depends on how the LLM built it. For example, maybe it noticed that your system already had some necessary dependencies installed, so it didn't bundle them with the app files. Now, if you copy the app to another system, it might not work.
The best way to solve this problem, in my opinion, is to simply containerize it with Docker and self-host it. This way, it'll run on your system while also becoming instantly available across all your other devices. You can even share it beyond your local network using a private VPN service like Tailscale .
However, turning a vibe-coded app into a self-hosted Docker app can be tricky. In my experience, the more layers you add to a vibe-coding project, the more likely things are to go wrong. As such, I wanted to see which model is currently the best at creating Dockerized apps and making the deployment as simple and effortless as possible.
I primarily tested two LLMs for this test— Claude and Gemini . Both models were instructed to create a simple to-do app, but the focus was on making it self-hosted using Docker and making the self-hosting process as plug-and-play as possible. I also instructed them to check my available ports and build an app targeting a port that was already in use. Other than this, the prompting was very minimal. I wanted to see which one did a better one-shot job.
Here's how it went.
I shared the exact prompt at the bottom of the article.
Claude's attempt at building the Docker app
It was near perfect—only held back by a mistake I made

Claude took around 3–4 minutes to build everything. I was using the Opus 5 model with thinking set to low, running inside the Claude desktop app in Cowork mode . It's important to use Cowork for this because it gives Claude direct access to my file system. This way, Claude can create all the necessary files on its own instead of me having to copy-paste code and save the files myself.
One hiccup I faced during the building process was that Claude couldn't check which ports were already in use. However, it made an educated guess, assigned the app to port 8420, and luckily, it was free. I believe that since it already knew about all the different Docker containers I run on my system, it knew the default ports they used and therefore didn't choose one of those.
It also couldn't run the docker composecommand, which I had to do manually. However, I did get a detailed README file covering everything I needed to know about the app and how to deploy it in plain English. So, it wasn't particularly difficult—even if I wasn't already familiar with how Docker works.
As for the app itself, it was minimal, as requested, but it had some welcome touches I didn't explicitly ask for. Apart from adding tasks, I could also filter between Active and Done tasks. There were also light and dark themes. And, of course, the tasks persisted across sessions. The tooling choices were also sensible for a project of this size. Claude used Node's built-in HTTP module for the backend, a plain JSON file for data storage, and exposed everything through a REST API.
Gemini's attempt at building the Docker app
A smoother journey to a not-so-impressive result

For Gemini, I used Antigravity , Google's own agentic development app. Similar to Cowork, you point it at a folder, and it works inside it. I used Gemini 3.1 Pro on High thinking, gave it the exact same prompt, and it built the application just as fast as Claude did.
The key advantage here was the harness. Antigravity has terminal access, so after building the app, it ran the Docker deployment itself. It also checked port availability, assigned a free one, and by the end, I could just punch the localhost URL into my browser. As such, the overall app deployment was smoother with Gemini.
As I mentioned above, Claude can also run terminal commands, but I had to use Claude Code for that. For this experiment, I used Cowork, which doesn't have terminal access to my system.
Now, coming to the app, Gemini really adhered to my instructions and built a very minimal to-do app. You can add tasks, mark them as done, delete them, and that's it—no fancy dark mode or filtering options. Granted, I didn't ask for those, so you could argue Gemini was simply following instructions more strictly than Claude did.
My one real complaint is that the minimalism only applied to the interface. Under the hood, things were a bit more complicated than they needed to be—it used Express for the backend and SQLite for the database . To be fair, both are standard choices and reasonable options for a production-grade app. However, for a personal to-do list, they're just extra weight. I actually preferred Claude's approach here.
Vibe-coding a Docker deployment layer is no longer a big deal
To answer the core question, both Claude and Gemini are excellent at vibe-coding Dockerized apps. Both one-shotted it with no special prompting, and with the right harness, the deployment step can be automated too. This is a solved problem.
My approach and advice moving forward is that if you're vibe-coding an application, just ask for a Docker layer on top. It'll turn a pile of files on one machine into something you can run anywhere and hand to anyone.
Here's the prompt I used:
