Web UI for MRTKLIB — GNSS post-processing, real-time positioning, QZSS CLAS/MADOCA, in Docker
1.4K
A modern web-based user interface for MRTKLIB,
running entirely in a Docker container. MRTKLIB is a modernized C11
implementation of RTKLIB with MADOCA-PPP, CLAS PPP-RTK, and advanced
GNSS positioning capabilities. No compilation required — just
docker compose up and start processing GNSS data from your browser.
Status: v0.4.2-alpha — core features are functional. Known limitations are listed in Known Issues.

mrtk post)/workspace/presets/).gz, .Z, single-file .zip, .tar) and
Hatanaka-compressed RINEX (.crx, .??d, e.g. .crx.gz) are
decompressed by mrtk (the image bundles crx2rnx / rnx2crx)mrtk run)/workspace/rtlog/rtkrcv/), with search in the Trace viewmrtk run after a page reload or a closed tab/workspace/rtlog/%Y/%n/ (e.g. rovr_%n%H.sbf),
optional time tag (.tag) for real-time replay_2, _3, … instead of overwriting itmrtk relay)mrtk relay + mrtk cssr2rtcm3)mrtk convert, rnx2crx / crx2rnx)/data or /workspace, output to
/workspacemrtk run/workspace/logs//workspace (read-write) and
/data (read-only host data directory)docker compose, which ships with Docker Desktop)The fastest way to try MRTKLIB Web UI. No cloning or building required.
Images are published for both linux/amd64 and linux/arm64
(Apple Silicon native).
Pull the image
# Docker Hub
docker pull hatognss/mrtklib-docker-ui:0.4.2-alpha
# or GitHub Container Registry
docker pull ghcr.io/h-shiono/mrtklib-docker-ui:0.4.2-alpha
Prepare host directories
mkdir -p ./workspace ./data
# Place your GNSS data files under ./data (read-only in container)
Run the container
docker run -d --name mrtklib-web-ui \
-p 8080:8000 \
-v "$(pwd)/workspace:/workspace:rw" \
-v "$(pwd)/data:/data:ro" \
-e PUID="$(id -u)" -e PGID="$(id -g)" \
hatognss/mrtklib-docker-ui:0.4.2-alpha
Open the UI at http://localhost:8080
Published images:
| Registry | Repository |
|---|---|
| Docker Hub | hatognss/mrtklib-docker-ui |
| GHCR | ghcr.io/h-shiono/mrtklib-docker-ui |
Both repositories carry the same multi-arch manifest. See the repository pages above for the list of available tags.
Use this flow if you need to customise the MRTKLIB version, build against a local MRTKLIB checkout, or develop the Web UI itself.
Clone the repository
git clone https://github.com/h-shiono/mrtklib-docker-ui.git
cd mrtklib-docker-ui
Configure directories
mkdir -p ./workspace ./data
cp .env.example .env
# Edit .env to set DATA_DIR to your GNSS data directory
Build and run
docker compose up --build
Open the UI at http://localhost:8080
| Mount | Default | Purpose | Access |
|---|---|---|---|
/workspace | ./workspace | Output files, presets, logs | Read-write |
/data | ./data | Input GNSS data files | Read-only |
# .env
DATA_DIR=/path/to/your/gnss-data
The app runs as PUID:PGID (default 1000:1000), not root, so files
it writes to /workspace belong to that host user. Set them to your
own IDs (id -u / id -g) in .env. On start, existing files under
/workspace owned by someone else (for example root, from versions
that ran as root) are chowned to PUID:PGID. PUID=0 restores the
old run-as-root behaviour.
To connect to a GNSS receiver via serial port, add the device
to docker-compose.yml:
services:
mrtklib-web-ui:
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
volumes:
# Optional: mount /dev/serial so the UI can list ports by descriptor
# name (e.g. "usb-Septentrio_Mosaic-G5_..." instead of "ttyUSB0").
- /dev/serial:/dev/serial:ro
The CLAS Pipeline tab uses one bidirectional serial device: the
receiver streams SBF (with L6 frames) out of the port and accepts the
generated RTCM3 back on the same port. Configure the receiver port to
do both (output SBF/L6, input RTCM3). Set CLAS_INPUT_DEVICE in
.env to that port, then uncomment the matching devices: line in
docker-compose.yml.
Docker Desktop on macOS runs Linux containers in a hidden VM, so
USB-serial devices on the Mac (/dev/cu.usbmodem*) are not
visible to the container by default. Use one of:
socat, ser2net) and pick TCP in the UI instead of
serial.The Data Downloader supports three credential sources
(priority order: .netrc mount > environment variables > UI).
Mount a .netrc at /home/mrtk/.netrc (see docker-compose.yml);
an existing /root/.netrc mount is copied there on start.
# .env
EARTHDATA_USER=your_username # NASA Earthdata (IGS products)
EARTHDATA_PASSWORD=your_password
GSI_USER=your_username # GSI CORS FTP
GSI_PASSWORD=your_password
QZSS L6D/L6E files require no authentication.
mrtk unified binary)/workspace (read-write), /data (read-only)uv sync
uv run uvicorn mrtklib_web_ui.main:app --reload --host 0.0.0.0 --port 8000
Note: QC Preview is temporarily disabled (the button is greyed out and
/api/obs-qc/analyzereturns 503) until it is integrated with MRTKLIB QC. The previous cssrlib-based implementation and itsqcextra were removed.
Run the backend tests (pytest is in the dev dependency group):
uv run pytest
cd frontend
npm install
npm run dev # http://localhost:5173
The frontend dev server runs on http://localhost:5173 and proxies
API requests to the backend at http://localhost:8000.
The publish-docker.yml workflow is the only thing that pushes
to GHCR / Docker Hub. It runs on two events:
| Trigger | Resulting tags (per registry) |
|---|---|
git push origin vX.Y.Z[-suffix] | X.Y.Z[-suffix], sha-<7-char>. For non-prerelease tags also X.Y, X, latest. |
gh workflow run publish-docker.yml --ref <branch> | dev-<branch> only. Repeated runs overwrite the same tag in place — no accumulation. |
So the recommended dev cycle is gh workflow run --ref my-branch →
docker pull ...:dev-my-branch. Cutting an actual release is
the only way to mint a new long-lived tag.
Do not bulk-delete "untagged" entries in the GHCR Versions
view. Multi-arch images (linux/amd64 + linux/arm64) live as
a tagged manifest list that references per-architecture
manifests appearing as untagged digests. Deleting those breaks
docker pull for the matching platform with manifest unknown.
Safe order if the registry needs a tidy-up:
dev-* or stale sha-* entries that have a tag —
their referenced platform manifests then drop to true orphans.git push --delete origin vX.Y.Z
followed by git push origin vX.Y.Z re-runs the workflow and
restores the manifest list. The GitHub Release object
re-attaches automatically.The same rule applies to Docker Hub, which is just slower to surface orphan state in its UI.
| Version | Description |
|---|---|
| v0.1.x-alpha | Core UI for all mrtk subcommands, presets, TOML I/O, Monitor tab |
| v0.2.x-alpha | Template presets, GNSS time converter, Monitor Sky+SNR, IGS/GSI downloader, GHCR/Docker Hub publish |
| v0.3.0-alpha | MRTKLIB 0.7.6 config migration, console redesign, CLAS pipeline, RINEX Converter overhaul, unified dark consoles, XYZ-ECEF / NMEA-0183 result views, live basemap map |
| v0.3.1-alpha | MRTKLIB 0.7.11, Real-Time raw input logging, restart-safe file outputs |
| v0.3.2-alpha | Security hardening, non-root container (PUID:PGID), Real-Time input stream status + live trace, reload-safe Real-Time / Stream Server sessions, PR CI |
| v0.4.0-alpha | Audit follow-ups (#39, #40): PPP-AR systems / max sol std controls, broader log masking, bounded file previews, NMEA and time-system fixes in the Result Viewer, slimmer image (QC Preview paused), reproducible builds (uv.lock) |
| v0.4.1-alpha | Bug fixes: Hatanaka (crx2rnx) inputs in the image, Real-Time log views hold while scrolled up, Post Processing Trace shows the file's end, Data Downloader (Earthdata login, non-blocking GSI, past default dates), Galileo HAS label, CLAS single-port docs |
| v0.4.2-alpha (current) | Small improvements: Trace search (Real-Time / Post Processing), Hatanaka compress / decompress in Conversion, readable ENU chart axes, sky plot hover details and larger markers, Real-Time satellite count matches the solution |
This is an alpha release. Many features have been implemented but not yet thoroughly tested in real-world conditions. Bug reports and feedback are very welcome — please open an issue.
mrtk run): basic operation confirmed;
edge cases (stream reconnection, dual-channel CLAS, long runs)
not yet validatedAll bug reports are appreciated, including partial or unclear ones.
Contributions of all kinds are welcome — bug reports, feature requests, documentation improvements, and pull requests.
The most helpful thing right now is real-world testing. If you try MRTKLIB Web UI with your own receiver or dataset and something does not work as expected, please open an issue. You do not need to have a fix ready — a clear description of what happened is enough.
When reporting a bug, please include:
For feature requests, a brief description of the use case is more useful than a specific implementation proposal.
For small fixes (typos, obvious bugs), a PR is welcome directly. For larger changes, please open an issue first to discuss the approach — this avoids duplicated effort.
feat:, fix:, docs:)The Docker image includes correction files from MRTKLIB for quick-start CLAS PPP-RTK and MADOCA PPP processing:
| File | Purpose |
|---|---|
clas_grid.def | CLAS grid definition |
clas_grid.blq | Ocean tide loading coefficients |
igu00p01.erp | Earth rotation parameters |
igs14_L5copy.atx | Satellite/receiver antenna PCV |
isb.tbl | Inter-system bias table |
l2csft.tbl | L2C signal phase correction |
| File | Purpose |
|---|---|
igs20.atx | IGS antenna model (satellite + receiver PCO/PCV) |
These files are available at /opt/mrtklib/corrections/ inside
the container and can be selected directly from the UI's
Files configuration panel. Use the "Apply CLAS PPP-RTK profile"
or "Apply MADOCA PPP profile" buttons to set all paths at once.
To use a newer version of any file, place it in your /data
directory and select it manually via the file browser.
MIT License. See LICENSE.
MRTKLIB is distributed under the BSD 2-Clause License. This project provides a web interface only and does not modify MRTKLIB source code.
The Docker image includes crx2rnx / rnx2crx built from the
RNXCMP software (Copyright (c) 2007 Geospatial Information Authority
of Japan), unmodified, under its license
(/usr/share/doc/rnxcmp/LICENSE.txt in the image;
source). Reference:
Hatanaka, Y. (2008), A Compression Format and Tools for GNSS
Observation Data, Bulletin of the Geospatial Information Authority of
Japan, 55, 21-30 (https://www.gsi.go.jp/ENGLISH/Bulletin55.html).
Built on MRTKLIB by Hayato Shiono, which is a modernized fork of RTKLIB by Tomoji Takasu.
Developed with assistance from Claude (Anthropic) and Gemini (Google).
Key dependencies: FastAPI · React · Mantine · Vite · Chart.js · uv
Content type
Image
Digest
sha256:13475a0d2…
Size
99.7 MB
Last updated
4 days ago
docker pull hatognss/mrtklib-docker-ui:sha-8d53d8c