DEV Community

Ai2th
Ai2th

Posted on

Linxr | Part 7 — Merging Docker Engine & Container Dashboard into Flutter

In Part 6, we explored how Virtio-9P and Android SAF enable seamless host-to-guest file sharing. Today in Part 7, we dive into how we merged Pockr into Linxr to create a unified Docker container management dashboard running on non-rooted Android devices.


The Vision: One App for VMs and Containers

Initially, Pockr was built as a standalone Android app for running Docker containers. However, managing two separate QEMU VM instances consumed double the RAM and disk space on mobile devices.

For Linxr v3.0.0, we unified both projects:

  • Single Guest VM: Alpine Linux 3.20 host running both the root shell and the Docker daemon (dockerd).
  • Containers Tab: A Flutter UI tab for deploying, monitoring, and streaming logs from Docker containers.

Architecture: Talking to dockerd Inside QEMU

To manage Docker containers from Flutter without SSH overhead for every action, we created a lightweight Python API daemon (api_server.py) running inside Alpine Linux:

  1. Docker Unix Socket Access: api_server.py communicates directly with /var/run/docker.sock.
  2. REST API Endpoints: Exposes endpoints for listing containers (GET /containers), starting/stopping containers (POST /containers/:id/start), and streaming logs (GET /containers/:id/logs).
  3. Flutter Platform Client: Flutter calls local VM API endpoints over port 8080.
[ Flutter Containers UI ] ──( HTTP / port 8080 )──> [ api_server.py ] ──( Unix Socket )──> [ Docker Daemon ]
Enter fullscreen mode Exit fullscreen mode

Container Log Streaming in Flutter

Streaming real-time container stdout/stderr logs required a non-blocking chunked response handler in Flutter:

Stream<String> streamContainerLogs(String containerId) async* {
  final request = await httpClient.getUrl(Uri.parse('http://127.0.0.1:8080/containers//logs'));
  final response = await request.close();

  await for (final chunk in response.transform(utf8.decoder)) {
    yield chunk;
  }
}
Enter fullscreen mode Exit fullscreen mode

This stream feeds directly into a reactive Flutter log viewer with auto-scroll and line filtering.


Results & Benchmark

By merging Pockr into Linxr:

  • RAM Savings: Memory usage dropped by 45% compared to running separate VM instances.
  • Unified Controls: Developers can spin up an nginx container in the Containers tab and immediately inspect its configuration files via the built-in Terminal tab (linxr:~#).

Download Linxr v3.0.0

Top comments (0)