DEV Community

Daniel Ioni
Daniel Ioni

Posted on

From HTTP 201 to Persistent Docker Data: Nicola’s MyZubster Pilot Works Locally

From HTTP 201 to Persistent Docker Data

Today, Nicola’s independent MyZubster MVP reached another concrete milestone.

The goal was simple to describe:

Clone the repository, start it with Docker, create an observation and prove that the data survives a complete container shutdown and recreation.

We completed that cycle on Nicola’s Windows computer.

This was not only a CI test.

It was a real local installation, performed step by step and supported by visible evidence.

Where we started

The project already had a verified API workflow:

Create observation → HTTP 201 → JSON persistence → API retrieval → automated test

That work was reviewed and merged through a public pull request:

PR #1 — Verify observation creation, persistence and retrieval

The next challenge was reproducibility.

Could Nicola clone the repository on his own computer and run the application without manually configuring Python and its dependencies?

Adding Docker

We created a second development branch and added:

  • a Python slim Docker image;
  • a non-root application user;
  • Docker Compose configuration;
  • a persistent volume for observations;
  • an API health check;
  • configurable host, port and data-file location;
  • Windows-friendly setup documentation;
  • an automated Docker test in GitHub Actions.

The Docker configuration was proposed in:

PR #2 — Add reproducible Docker setup for local development

The CI workflow built the image, started the container, created an observation and retrieved it successfully.

After the CI passed, the pull request was merged into main.

The first local obstacle

Nicola cloned the repository successfully:

git clone https://github.com/nicolaususnicola-lgtm/myzubster-mvp.git
cd myzubster-mvp
Enter fullscreen mode Exit fullscreen mode

But the first Docker command failed:

failed to connect to the docker API at
npipe:////./pipe/dockerDesktopLinuxEngine
Enter fullscreen mode Exit fullscreen mode

This error was not caused by MyZubster.

The Docker command-line tools were installed, but the Docker Desktop Linux engine was not running.

We verified WSL:

wsl --version
wsl --status
wsl --update
wsl --shutdown
Enter fullscreen mode Exit fullscreen mode

The machine had:

  • WSL 2;
  • an updated Linux kernel;
  • eight CPUs;
  • approximately 15.5 GB of memory;
  • the desktop-linux Docker context.

After starting Docker Desktop, both the Docker client and server became available.

Building the application locally

Nicola then ran:

docker compose up --build -d
docker compose ps
Enter fullscreen mode Exit fullscreen mode

The image was built and the API container started successfully.

We verified the initial state:

Invoke-RestMethod http://localhost:5000/api/observations
Enter fullscreen mode Exit fullscreen mode

Then we created the first local observation:

$body = @{
  description = "Prima osservazione Docker di Nicola"
  latitude = 44.0678
  longitude = 12.5695
} | ConvertTo-Json

Invoke-RestMethod `
  -Method Post `
  -Uri http://localhost:5000/api/observation `
  -ContentType "application/json" `
  -Body $body
Enter fullscreen mode Exit fullscreen mode

The API returned a new observation with:

  • a generated ID;
  • the submitted description;
  • latitude and longitude;
  • an empty optional media hash;
  • a UTC timestamp.

The generated observation ID was:

b8e8d66b9bf5bd16
Enter fullscreen mode Exit fullscreen mode

Verifying the saved data

We retrieved the observations through the API:

Invoke-RestMethod http://localhost:5000/api/observations |
  ConvertTo-Json -Depth 5
Enter fullscreen mode Exit fullscreen mode

The result contained:

{
  "count": 1,
  "observations": [
    {
      "coordinates": {
        "lat": 44.0678,
        "lng": 12.5695
      },
      "description": "Prima osservazione Docker di Nicola",
      "id": "b8e8d66b9bf5bd16",
      "media_hash": "",
      "timestamp": "2026-09-02T08:51:57.067451+00:00"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

At this point, creation and retrieval worked.

But that alone did not prove persistence.

Test one: container restart

We restarted only the API service:

docker compose restart api
Enter fullscreen mode Exit fullscreen mode

After the container returned, we queried the API again.

The response still contained:

count: 1
id: b8e8d66b9bf5bd16
Enter fullscreen mode Exit fullscreen mode

The observation survived the container restart.

Test two: complete Compose shutdown

The more important test was a complete Compose shutdown.

We ran:

docker compose down
Enter fullscreen mode Exit fullscreen mode

The first stop required Docker to terminate the development server after its timeout. The container exited with code 137.

That behavior is not ideal, and it revealed the next technical improvement: replace Flask’s development server with a production-oriented WSGI server such as Gunicorn.

However, the container was stopped and the persistent volume remained available:

docker volume ls | Select-String "observations"
Enter fullscreen mode Exit fullscreen mode

Result:

local     myzubster-mvp_observations-data
Enter fullscreen mode Exit fullscreen mode

No -v option was used, so Docker did not delete the data volume.

Test three: recreate the environment

We recreated the network and container:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Then we queried the API once more:

Invoke-RestMethod http://localhost:5000/api/observations |
  ConvertTo-Json -Depth 5
Enter fullscreen mode Exit fullscreen mode

The same observation was still present:

count: 1
id: b8e8d66b9bf5bd16
Enter fullscreen mode Exit fullscreen mode

This completed the full persistence test:

Create → Save → Restart → Read → Down → Recreate → Read again

What we can now verify

Nicola’s MVP now has evidence for the following claims:

  • the repository can be cloned on Windows;
  • the application can be built with Docker;
  • Docker Compose starts the API;
  • the health check confirms availability;
  • a valid observation returns HTTP 201;
  • the observation is persisted;
  • the API retrieves the saved observation;
  • the data survives a service restart;
  • the data survives container and network recreation;
  • the process does not require sharing passwords or tokens.

This does not make the application production-ready.

It makes one capability reproducible and verifiable.

That distinction is central to the MyZubster experiment.

One human, one AI, public evidence

The collaboration model is:

one human + one AI

Nicola controls his project and performs the local actions.

Zorgax assists with:

  • repository inspection;
  • implementation planning;
  • code changes;
  • validation;
  • troubleshooting;
  • documentation;
  • evidence collection.

GitHub, automated tests and local execution provide independent signals that the workflow actually works.

The AI does not replace human approval, and passing tests do not automatically turn an MVP into a production system.

The next improvement

The logs clearly warned us:

WARNING: This is a development server.
Do not use it in a production deployment.
Enter fullscreen mode Exit fullscreen mode

The next technical step is therefore to:

  1. introduce Gunicorn inside the Linux container;
  2. verify graceful shutdown;
  3. repeat the down → up persistence test;
  4. add the result to GitHub Actions;
  5. document the difference between development and deployment configurations.

The broader experiment

MyZubster is exploring whether an ecosystem can expand through independent, verified projects instead of only accumulating registered users.

Nicola’s MVP is a small example of that model.

It began as an independent repository.

It now provides a working observation capability with public code, automated tests, Docker packaging and locally reproduced evidence.

The development loop remains:

Build → Validate → Connect → Measure → Verify → Replicate → Expand

Today, Nicola completed the first five steps for one capability.

That is a small result.

But it is real, repeatable and public.


MyZubster — Open-source ecosystem
Zorgax — AI intelligence and coordination layer
Principle — Human-controlled, evidence-driven development

Nicola’s repository:
github.com/nicolaususnicola-lgtm/myzubster-mvp

Main ecosystem:
github.com/MyZubster-Ecosystem/myzubster

Website:
myzubster.com

What is the smallest capability in your project that you could make independently reproducible and verifiable today?

Top comments (0)