# TongFlow self-hosting assembles a Python venv inside its own data volume

> tong-io/tongflow is an open-source, AGPL-3.0 canvas where text, image, audio, video and 3D are treated as materials and every step separates what it does from which plugin runs it. The interesting mechanics are all in the packaging: the runner image ships Python because the first plugin run creates a virtual environment under /data and pip-installs the SDK there, the compose file runs a floating latest tag on port 3000, and the desktop app has not been signed by Apple.

**tong-io/tongflow** — TongFlow — Multimodal GenAI Studio

- Repository: https://github.com/tong-io/tongflow
- Website: https://app.tongflow.com
- Stars: 1,032 · Forks: 135
- Language: TypeScript
- License: AGPL-3.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/tong-io-tongflow

## The first plugin run creates a Python venv inside the data volume

The runner stage of the Dockerfile installs Python onto a slim Node image, and the comment above the line gives the reason:

```dockerfile
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        python3 python3-venv python3-pip ca-certificates \
    && rm -rf /var/lib/apt/lists/*
```

The stated reason is that python3-venv and python3-pip are required because the first plugin run creates a venv under /data and pip-installs the SDK and each plugin's requirements. So a self-hosted TongFlow is not a sealed application image. The plugin runtime is a Python environment assembled inside the data volume the first time a plugin runs, resolving the SDK and every plugin's declared requirements from the package index at that moment, and the result persists in the volume across restarts. The same SDK is published by a repository script, bash scripts/publish-tongflow-pypi.sh. Two things follow: anything that runs a plugin can execute code the image never saw, and the volume holding your data is the same one accumulating the virtual environments.

## Three ways in, and the desktop app is a 10 MB shell

The page offers TongFlow Cloud, either as a desktop app or at app.tongflow.com in a browser, self-hosting from source or with Docker, and building with an agent through the tongflow npm package or TongFlow inside Claude Code, any MCP client or dsh. All three sit on the same open-source core. The desktop app is described as a lightweight shell of roughly 10 MB around the cloud studio: install it, sign in with Google or WeChat, and the cloud studio manages plugins and execution for you. The cloud studio also runs in any modern browser, so the shell adds a window and little else.

The tree backs the third route more than the first. Alongside the application source there are packages/, sdk/, plugins/ and scripts/ directories, and two root directories whose names differ only by a leading dot: .claude-plugin/ and claude-plugin/. The compose file, meanwhile, defines exactly one service, the web app itself, so an agent client is not served by anything the repository ships as a container.

## The macOS build is not notarized, so the first launch needs a flag cleared

The page states that the builds are not yet notarized with Apple, so Gatekeeper blocks the first launch with the message that TongFlow is damaged and can't be opened. The remedy is to move the app to Applications and clear the quarantine flag once:

```bash
xattr -cr /Applications/TongFlow.app
```

The same note tells you to download from the project page directly, because installers passed through chat apps such as WeChat may be renamed or re-flagged. Two builds are offered, a Universal macOS disk image covering Apple Silicon and Intel, and a Windows installer, both fetched from the releases page. That is an unusual amount of ceremony for what the page calls a lightweight shell, and all of it concerns the wrapper rather than the studio, including the instruction to talk a reader past a macOS security warning before they have seen a single node.

## The account-free local runtime stopped shipping after v0.1.13

The page carries a note for readers who want a fully local, account-free TongFlow, and it points at self-hosting for that. What it also says is that the desktop app up to v0.1.13 bundled this local runtime, and that those installers remain on the releases page. The current release line is 0.3.x, so the account-free local desktop build is an artifact two minor generations back, kept only as an old download, while the current app signs in with Google or WeChat.

The tag dates show an uneven edge. v0.3.3 and v0.3.4 were both published on 2026-08-19, nine hours apart, and v0.3.5 followed three weeks later on 2026-09-10. That matters more than it looks, because the compose file pulls the image tag latest rather than a version, while the root package metadata pins 0.3.5. A self-hoster tracking the tag therefore follows that edge without being told when it moves.

## The compose file publishes port 3000 on every interface with five optional keys

The whole self-host service is one block:

```yaml
services:
  tongflow:
    image: ghcr.io/tong-io/tongflow:latest
    ports:
      - "3000:3000"
    volumes:
      - tongflow-data:/data
      - tongflow-plugins:/plugins
    environment:
      MODAL_TOKEN_ID: ${MODAL_TOKEN_ID:-}
      MODAL_TOKEN_SECRET: ${MODAL_TOKEN_SECRET:-}
      OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
      GEMINI_API_KEY: ${GEMINI_API_KEY:-}
      OPENAI_API_KEY: ${OPENAI_API_KEY:-}
    restart: unless-stopped
```

The port mapping has no host side, so 3000 is bound on every interface rather than on loopback, and the only configuration passed in is five provider credentials, each defaulting to empty. The comment at the top of the file says all API keys are optional and can instead be set in-app under Settings, persisted to /data/settings.json, which puts the remaining secrets in a file inside the data volume rather than only in the environment. Nothing in the file fronts the service with a proxy, a certificate or an authentication variable; the sign-in described on the page belongs to the cloud studio. The prebuilt registry image is the default and the local build line is commented out.

## Configuration is keyed by handler, and the default text route is a free one

The env example is organised by node handler id rather than by vendor, which is the clearest statement of how the plugin system names things. Text generation lists gen_text as the default route and describes it as the OpenRouter free router, taking OPENROUTER_API_KEY with optional overrides for the free model id, an HTTP referer and an app title. Google Gemini appears as gen_text_gemini and as the default path for combine_text, with a note that the handler accepts either GEMINI_API_KEY or GOOGLE_API_KEY. OpenAI appears as gen_text_openai, with OPENAI_CHAT_MODEL offered as the fallback when a node does not pick one. DeepSeek is scoped narrowly to batch arrange and group logic in the arrange-texts handler.

Two further entries have nothing to do with model providers: TASK_WEBHOOK_TOKEN for a secure task webhook with auto-save callbacks from external runners, and NEXT_PUBLIC_FILE_BASE_URL for the app's own file base URL. Modal has its own variable pair, labelled for GPU and CPU workers, which is the only compute backend the compose file mentions at all.

## The root package is marked private and the publish script is a shell script

The root package metadata names the project tongflow-app at version 0.3.5, licenses it AGPL-3.0-only and marks it private, which is why publishing belongs to packages/ rather than to the root. The publish target is bash scripts/publish-tongflow-pypi.sh, so releasing the SDK needs a POSIX shell even on Windows, and the env example supplies the Twine pair it reads, with the username required to be exactly the token placeholder and a separate switch for TestPyPI. The page meanwhile points at an npm package and a PyPI badge, so the same SDK is reachable two ways and only one of them has a release script in the tree.

Two smaller details sit beside it. Two scripts generate types from the same ABI, one through tsx and one through node, and only the first is wired into predev and prebuild, so the other runs by hand or not at all. And the root carries COMMERCIAL-LICENSE.md next to LICENSE, so AGPL terms and a commercial licence both apply to one tree without the page saying which covers what.

## The sponsor table sits above the demos with referral parameters attached

The first content block after the language switcher is a sponsor table with two rows, and both rows read as offers rather than as documentation. One runs a MiniMax H3 video generation API priced per second, with separate figures for 768P and for 2K, and tells the reader to sign up through the TongFlow link to claim bonus credits and a partner discount. The other is an OpenAI-compatible gateway sold as one key and one balance covering the canvas, with per-image pricing and a trial credit, reached through a separate plugin repository, and its sign-up address carries an affiliate parameter inside the query string.

The gateway row doubles as a catalogue, since it names the text, image and video models it serves, which makes the sponsor block the only place on the page giving you a concrete model list. Read as engineering documentation it is noise between the header and the demo table. Read as a page disclosing how it pays for itself, at least the placement is the first thing a reader passes.

## Conclusion

TongFlow is a real application with a real product surface, and its packaging is the part to read before anything else. A self-hosted install is not a sealed image: the first plugin run builds a Python environment inside the data volume and fetches the SDK plus each plugin's requirements from the package index, which means the code that executes inside your container is code the image never contained. Bind the port to loopback or put a proxy in front of it, because the compose file publishes 3000 on every interface and passes in nothing but five optional provider keys, with the rest of the secrets ending up in a settings file inside the same volume. Pin the image tag rather than tracking latest, and remember that the account-free local desktop build only exists up to v0.1.13 while the current line is 0.3.x. For licensing questions, note that AGPL terms and a separate commercial licence file sit in the same tree.

## FAQ

### What is tong-io/tongflow?

An open-source modality-first GenAI platform. Text, image, audio, video and 3D are treated as materials, and each step is three separate decisions: what you have, what it could become, and which plugin and model should run it. Four operations cover the work, add, transform, combine, and split and batch. The core is AGPL-3.0-only and self-hostable.

### How do I self-host TongFlow?

With Docker Compose: one service pulled from the prebuilt registry image, a mapping for port 3000, and two named volumes for data and plugins, reachable at http://localhost:3000. Building locally instead means uncommenting the build line in the compose file. The image is a Next.js standalone build produced by a two-stage Dockerfile.

### Does TongFlow need provider API keys to run?

No. The compose file states that all API keys are optional and can be set in-app under Settings, with the values persisted to /data/settings.json. The env example still lists five credentials: a Modal token id and secret for GPU and CPU workers, plus OpenRouter, Gemini and OpenAI keys.

### Why does the TongFlow Docker image install Python?

Because the first plugin run creates a Python virtual environment under /data and pip-installs the SDK together with each plugin's requirements. The runner stage therefore adds python3, python3-venv and python3-pip to a slim Node base, and publishing that SDK to PyPI is handled by a repository script, bash scripts/publish-tongflow-pypi.sh.

### Can I use TongFlow without signing in to an account?

Not through the current desktop app, which is a shell of about 10 MB around the cloud studio and signs in with Google or WeChat. The page notes that the desktop app up to v0.1.13 bundled a local runtime instead, and that those older installers remain on the releases page, while the current release line is 0.3.x.

## Sources

- [License: AGPL-3.0](https://github.com/tong-io/tongflow/blob/main/LICENSE)
- [Project website](https://app.tongflow.com)
- [README](https://github.com/tong-io/tongflow/blob/main/README.md)
- [Releases](https://github.com/tong-io/tongflow/releases)
- [tong-io/tongflow on GitHub](https://github.com/tong-io/tongflow)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tong-io-tongflow
