Skip to content

About

RouterOS /app container for T3 Code (x86_64 + ARM64, GHCR, CHR-tested)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

app-t3code

RouterOS /app container for T3 Code — the agentic coding tool that runs as a server with a web UI. This repo builds multi-arch (linux/amd64 + linux/arm64) OCI images to ghcr.io/tikoci/app-t3code, ships the /app YAML to install them, and proves the whole path on real CHR VMs (x86_64 + ARM64) with Bun tests.

Target device: MikroTik RDS2216 (ARM64, ROSE edition — container-ready out of the box). Anything here that says CHR also applies to RDS, except the CHR-only workarounds are marked.

Install

Prerequisites on the router (one time):

  1. RouterOS 7.24.6 or newer (the minimum supported version).
  2. The container extra package installed.
  3. Device-mode with container=yes (RDS ships rose mode with it on; other hardware needs one physical confirm).
  4. A formatted disk for apps (see Storage).

Then install the app for production (HTTPS via /ip/cloud or your own domain):

/app/add yaml=([/tool/fetch url="https://tikoci.dev/app-t3code/app/t3code.tikapp.yaml" check-certificate=yes output=user as-value]->"data") use-https=yes
/app/set [find where name="t3code"] disabled=no

Note

When using CHR, such as with tikoci/quickchr, change use-https=yes to use-https=no. Free-license CHR has no /ip/cloud for certificate provisioning. CI and the test commands below use this setting.

Once the container is running, follow Pairing with the web UI to get its browser URL and a one-time pairing token. Storage persists on the app disk, so logins, the T3 database, and ~/projects survive reboots.

Preview or edit the YAML

See in /app YAML Editor to inspect, validate, or customize the single-app definition in our sister project, tikoci/restraml. The share link embeds the YAML as a snapshot; the downloads below track the current published files. Both YAML files include schema comments for editor validation.

YAML downloads and app store

GitHub Pages mirrors the repository paths for Markdown and the two app YAML formats, serving the original files without rendering or rewriting them:

The install command above fetches the app YAML into memory and passes its contents to /app/add yaml= for a one-time installation.

Tip

Alternatively, add our app store to the router's catalog. This appends to app-store-urls, preserving existing stores. Before you install the app, the catalog can pick up changes to our template so installation uses the latest YAML we publish.

/app/settings/set app-store-urls=([get app-store-urls],"https://tikoci.dev/app-t3code/app/t3code.tikappstore.yaml")

The store requires a YAML array, so use .tikappstore.yaml for app-store-urls, and .tikapp.yaml for a single app installation. See MikroTik's custom app store documentation.

Storage

Use a separate disk for apps; the RouterOS root volume cannot be used. Format the app disk as ext4 or btrfs, then set its mount point in /app/settings. /app refuses to enable anything until this is configured:

/disk/print            # find the extra disk, e.g. *1
/disk/format *1 file-system=ext4
/app/settings/set disk=<mount-point>

The disk can be any supported storage type with enough space for the image and persistent data. On CHR, attach a second virtual disk. The app then lives under <disk>/apps/t3code/.

Using T3 Code

The container serves plain HTTP on 3773 (T3CODE_HOST=0.0.0.0, T3CODE_PORT=3773). Put HTTPS in front for anything beyond localhost — the hosted web/mobile T3 apps require it.

Pairing with the web UI

The browser needs a one-time token to connect to this container. Once the app is running, run this command in the RouterOS terminal to print both the app's browser URL and a fresh token from t3-pairing-link inside the app-t3code container:

:put "** Using T3Code **\r\n\r\nIn your browser go to: $[/app/get t3code ui-url]\r\n\r\nThen, use the Token below in your browser to connect it with this container:\r\n$[/container/shell app-t3code cmd="t3-pairing-link" as-value]"

For example (illustrative token):

** Using T3Code **

In your browser go to: http://10.0.2.15:3773/

Then, use the Token below in your browser to connect it with this container:
Issued client pairing token 00000000-0000-4000-8000-000000000000.
Token: EXAMPLEONLY
Expires at: 2026-11-03T14:07:30.038Z

Open the printed URL and enter the value on the Token: line in the browser's pairing prompt. Tokens expire after about five minutes; run the command again if you need a fresh one.

Note

ui-url reflects the app's use-https setting. With use-https=yes, it reports the HTTPS URL (including the MikroTik hostname when using /ip/cloud). With use-https=no, it reports an HTTP URL like the CHR example above.

If PUBLIC_URL is set in the container, t3-pairing-link can print a full pairing URL instead of a raw token.

Environment and providers

Env Default Notes
T3CODE_HOST / T3CODE_PORT 0.0.0.0 / 3773 server bind
T3CODE_TELEMETRY_ENABLED false in our YAML set true/unset to opt back in
PUBLIC_URL unset base URL baked into pairing links
ANTHROPIC_API_KEY, OPENAI_API_KEY, … inherited agents see container env
T3CODE_* passthrough e.g. T3CODE_SERVER_BROWSER_SANDBOX=0

Codex and opencode ship in the image; Claude Code installs itself to the persistent volume on first boot (its license forbids redistributing it, so it cannot be baked in).

Good upstream navigators (pingdotgg/t3code docs):

  • install / requirements (t3 serve, providers) — install.md
  • remote access (t3 up, --lan, T3 Connect relay, pairing) — remote-access.md
  • background service (memory/OOM guidance, t3 service) — background-service.md
  • telemetry opt-out — telemetry.md
  • project settings / storage cleanup — project-settings.md
  • FAQ (disk usage is worktree cleanup) — faq.md

The image only documents one requirement: an installed, authenticated provider. There are no published CPU/RAM minimums; size from your workload (agents + browser), not from a datasheet.

Tags

Images track upstream stable T3 Code releases only — no nightlies (CI still accepts any T3CODE_VER input for one-off builds):

  • ghcr.io/tikoci/app-t3code:0.1.6 — exact release
  • ghcr.io/tikoci/app-t3code:0.1, :0, :latest — stability aliases

The /app YAML references the :0.1-style stability tag, and test/app-yaml.test.ts fails the build if it drifts from package.json's major.minor. Bumping T3 versions = bump T3CODE_VER (default in Dockerfile + Makefile), package.json, and the YAML tag together.

Developing

bun install
bun run check          # biome + tsc --noEmit
bun run test           # offline /app YAML contract (always runs)
APP_T3CODE_INTEGRATION=1 bun test test/integration/

The integration test boots a real CHR per arch with @tikoci/quickchr@next, drives it with @tikoci/centrs@next, and asserts the web UI answers with the expected serverVersion:

APP_T3CODE_ROS=stable APP_T3CODE_ARCH=arm64 APP_T3CODE_INTEGRATION=1 \
  bun test test/integration/

Both helpers float on next on purpose: if a helper breaks, report it to centrs / quickchr instead of working around it silently. CI (ci.yml) lints, tests, and builds both arches to GHCR; integration.yml runs the CHR matrix weekly, post-push on app/ + test/integration/, and on demand.

The pages.yml workflow publishes only tracked *.md, *.tikapp.yaml, and *.tikappstore.yaml files, preserving their paths and contents. Automatic deployments run only when those files change on main; manual dispatch is also available. Pages must use GitHub Actions as its publishing source in the repository's Settings → Pages. No site generator is used.

Verified install flow on CHR 7.25 (x86, free license):

  1. first-boot deviceMode: { enable: ["container"] } → rose mode (the guest-side /system/device-mode/update never completes);
  2. installPackage("container") (/app 404s without the package);
  3. /disk/format <id> file-system=ext4 (7.25 has ext4, no ext3)
    • /app/settings/set disk=<mount-point>;
  4. api … app -X PUT -f yaml=… -f use-https=no --yes (colon-style 3773:3773:web:tcp ports parse as firewall-redirects);
  5. /app/set … disabled=no (PUT leaves the app disabled:true);
  6. poll /app + /container (.running is the string "true") + GET /.well-known/t3/environment → serverVersion.

routeros-app-yaml, routeros-container, routeros-centrs, routeros-quickchr-cli, and tikoci-crossref skills govern this repo; AGENTS.md has the working notes.

License

MIT — see LICENSE.

About

RouterOS /app container for T3 Code (x86_64 + ARM64, GHCR, CHR-tested)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages