A lightweight, native Docker Desktop replacement for Linux built with Tauri. Connects directly to the local Docker Engine via the Unix socket for high-performance container management.
Prebuilt packages are available on the Releases page:
| Format | Install |
|---|---|
| AppImage (any distro) | chmod +x DockerLite_*.AppImage && ./DockerLite_*.AppImage |
| .deb (Debian/Ubuntu) | sudo apt install ./DockerLite_*_amd64.deb |
| .rpm (Fedora/openSUSE) | sudo dnf install DockerLite-*.x86_64.rpm |
Requires a running Docker Engine and your user in the docker group (see Prerequisites).
Prefer the .deb or .rpm when your distro offers one. Those packages use your system's WebKitGTK, which receives security updates through your package manager. The AppImage bundles its own copy of WebKitGTK frozen at build time, so it only picks up browser-engine fixes when a new DockerLite release is published. DockerLite renders data produced by your containers (log output, environment variables, labels), so an up-to-date engine matters.
Releases published after October 2026 sign the AppImage with the project's release key. The public key is
committed at dockerlite-release-signing.pub.asc and attached
to every release. Its fingerprint is:
5396 D542 D9A6 08DD 5D27 4BE2 0D85 CE52 C3B5 9577
Tools such as AppImageUpdate check the signature automatically. To look at it yourself:
./DockerLite_*.AppImage --appimage-signature # prints the embedded PGP signature- Container Dashboard with compose project grouping, bulk actions, and real-time status
- Real-time Log Streaming with auto-scroll, timestamps, ANSI stripping, and auto-reconnect on restart
- Interactive Terminal (exec) via xterm.js with bidirectional I/O
- Live Stats Charts for CPU, memory, and network usage (Recharts)
- Container Inspect with collapsible JSON tree viewer and environment variables table
- Image Management with multi-select, dangling filter, and bulk delete
- Volume Management with orphan detection and delete
- Network Management showing connected containers with IPs
- System Cleanup with granular prune (containers, images, volumes, networks, build cache) and disk usage breakdown
- Settings for socket path, refresh intervals, dark/light theme, and log buffer size
- Dark Mode by default with a light theme toggle
| Logs | Terminal |
|---|---|
![]() |
![]() |
| Stats | Inspect | Environment |
|---|---|---|
![]() |
![]() |
![]() |
| Images | Volumes |
|---|---|
![]() |
![]() |
| Networks | Cleanup |
|---|---|
![]() |
![]() |
| Layer | Technology |
|---|---|
| Backend | Rust + Tauri v2 |
| Frontend | React 19 + TypeScript |
| Styling | Tailwind CSS v4 + Radix UI |
| Docker API | Bollard (Rust crate) |
| Terminal | xterm.js + @xterm/addon-fit |
| Charts | Recharts |
| Persistence | tauri-plugin-store |
| Packaging | AppImage, .deb, .rpm |
- Linux (x86_64). Tested on Arch Linux.
- Docker Engine installed and running (
sudo systemctl start docker) - Your user must be in the
dockergroup:sudo usermod -aG docker $USER # Log out and back in for the change to take effect
-
Rust (stable, via rustup):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Node.js >= 18 and npm
-
Tauri system dependencies:
Arch Linux:
sudo pacman -S webkit2gtk-4.1 gtk3 libappindicator-gtk3 librsvg
Ubuntu/Debian:
sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
For other distros, see the Tauri prerequisites guide.
-
Tauri CLI:
cargo install tauri-cli --version "^2"
# Install frontend dependencies
npm install
# Start dev server (hot-reload frontend + Rust rebuild)
cargo tauri devThe app opens at 1280x800 and connects to /var/run/docker.sock by default. Change the socket path in Settings if needed.
The project uses lefthook to run quality checks as git hooks automatically on every commit and push.
Run this once after npm install:
npx lefthook installTwo hooks are registered:
| Hook | Checks |
|---|---|
| pre-commit | rustfmt, ESLint, Prettier, TypeScript type check |
| pre-push | Clippy (Rust linter), Vitest (frontend tests) |
Rust:
# Auto-format all Rust files
cargo fmt --manifest-path src-tauri/Cargo.toml
# Check formatting without changing files (what the hook runs)
cargo fmt --manifest-path src-tauri/Cargo.toml --check
# Lint (fails on any warning)
cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
# Run integration tests (requires Docker running)
cargo test --manifest-path src-tauri/Cargo.tomlFrontend:
# Type check
npm run typecheck
# Lint (ESLint)
npm run lint
# Auto-format with Prettier
npm run format
# Check formatting without changing files (what the hook runs)
npm run format:check
# Run all frontend checks at once
npm run checkFrontend tests:
# Run tests once
npm run test
# Watch mode (re-runs on file changes)
npm run test:watch
# With coverage report
npm run test:coveragerustfmt and clippy ship with the Rust toolchain. If they are missing:
rustup component add rustfmt clippyESLint, Prettier, and lefthook are npm devDependencies — npm install is all that is needed.
No extra system packages are required beyond the ones listed in Prerequisites.
# Build all bundle formats (AppImage, .deb, .rpm)
cargo tauri build
# Or build a specific format
cargo tauri build --bundles deb
cargo tauri build --bundles appimage
cargo tauri build --bundles rpmAppImage requires FUSE. If the build fails with failed to run linuxdeploy, install FUSE:
# Arch Linux
sudo pacman -S fuse2
# Debian/Ubuntu
sudo apt install libfuse2Output binaries are in src-tauri/target/release/bundle/:
| Format | Path |
|---|---|
| AppImage | appimage/DockerLite_*.AppImage |
| .deb | deb/DockerLite_*.deb |
| .rpm | rpm/DockerLite-*.rpm |
The raw binary is also available at src-tauri/target/release/dockerlite and can be run directly.
Releases are built automatically by GitHub Actions when a version tag is pushed. The workflow produces AppImage, .deb, and .rpm artifacts and creates a draft GitHub Release for review.
-
Bump the version in both files (they must match):
src-tauri/tauri.conf.json—"version"fieldsrc-tauri/Cargo.toml—versionfield
-
Commit the version bump:
git add src-tauri/tauri.conf.json src-tauri/Cargo.toml git commit -m "chore(release): bump version to X.Y.Z" -
Merge to
mainvia PR as normal. -
Tag the merge commit and push the tag:
git tag vX.Y.Z git push origin vX.Y.Z
-
GitHub Actions builds the binaries and creates a draft release automatically. Open the Releases page, add release notes, and publish when ready.
No tokens or secrets need to be configured — GITHUB_TOKEN is provided automatically.
If the repository has an APPIMAGE_SIGNING_KEY secret, the release workflow signs the AppImage
and embeds the public key in it, so AppImageUpdate and users can verify that a download really
came from this project. Without the secret the AppImage is published unsigned.
To set it up once, generate a dedicated signing key without a passphrase (CI cannot answer a passphrase prompt) and store the ASCII-armored private key as the secret:
gpg --batch --passphrase '' --quick-generate-key 'DockerLite Release Signing' ed25519 sign never
gpg --armor --export-secret-keys 'DockerLite Release Signing' | gh secret set APPIMAGE_SIGNING_KEY
gpg --armor --export 'DockerLite Release Signing' > dockerlite-release-signing.pub.ascThe exported public key is committed as dockerlite-release-signing.pub.asc and the workflow
attaches it to every release, so users can compare it against the key embedded in the AppImage.
If you ever rotate the key, replace that file and the fingerprint in the Download section in the
same change as the secret.
The workflow downloads a specific tagged release of
appimagetool and refuses to run it unless
its SHA-256 matches the value in release.yml. The tool rewrites the AppImage we ship, so it must
never be fetched from a mutable URL. To upgrade it, update both the URL and the sha256: digest
shown on the GitHub release asset.
Frontend (React) Backend (Rust/Tauri)
invoke() ───────────────────────> #[tauri::command] handlers
Channel<T> <──────────────────── StreamRegistry (logs, stats)
onData() ───────────────────────> ExecRegistry (terminal stdin)
One-shot commands (list, inspect, lifecycle actions) use Tauri's invoke() pattern: the frontend calls a named command, the backend queries Docker via Bollard, and returns the serialized result.
Streaming commands (logs, stats, terminal output) use Tauri's Channel<T> for backend-to-frontend data flow. Each stream is tracked in a StreamRegistry so it can be cancelled when the user navigates away or the container restarts. The stream auto-reconnects after container restarts.
Terminal I/O uses a hybrid: output flows via Channel<Vec<u8>> (high throughput), input flows via individual invoke("write_exec_input") calls per keystroke batch (low frequency). The exec session's stdin handle is stored in an ExecRegistry.
Settings are persisted to ~/.config/dockerlite/settings.json via tauri-plugin-store.
src/ # React frontend
lib/ # Types, API wrappers, hooks, settings
components/
layout/ # Sidebar, AppLayout
containers/ # ContainerTable, actions, compose groups
container-detail/ # LogsTab, TerminalTab, StatsTab, InspectTab, EnvTab
system/ # SystemSummary cards
ui/ # StatusBadge, ConfirmDialog, Toast, ErrorBoundary
pages/ # Route-level page components
src-tauri/src/ # Rust backend
docker/ # Pure Docker operations (containers, images, volumes, networks, system)
commands/ # Tauri command handlers (mirrors docker/ structure + exec)
state.rs # DockerState, StreamRegistry, ExecRegistry
error.rs # Typed error enum with actionable messages
lib.rs # App entry point, plugin/state/command registration
MIT










