Files
2026-05-25 03:01:46 +03:00

6.2 KiB

dockernecontainer (dnc)

Containerized per-project development environments with TUI and GPU support.

Dependencies

Required:

  • Linux with rootful Docker (≥20.10). Rootless Docker is detected and rejected.
  • Project directory you want to containerize

GPU (choose what applies):

  • NVIDIA: nvidia-smi on PATH + nvidia-container-toolkit installed
  • Intel/AMD DRI: /dev/dri present on host (auto-detected)
  • AMD compute (KFD): /dev/kfd present on host (auto-detected)

Usage

# Create container from an image with your tools
dnc setup --image ghcr.io/lstmnemodel/dnc-test-arch:latest

# Launch bundled kitty terminal (all tabs/splits exec into container)
dnc

# Non-graphical fallback (useful for SSH sessions without display)
dnc -- /bin/bash

# Run a command in container (non-interactive or interactive)
dnc -- pacman -Syu

# Show container details
dnc info

# List all containers
dnc list

# Remove container
dnc rm

Each project directory gets its own container. A .dnc file in the project root tracks the container name. dnc walks up the directory tree to find it.

How It Works

When you run dnc with no arguments:

  1. Finds your project: Walks up from $PWD to find .dnc file
  2. Extracts kitty config: Copies ~/.config/kitty/ from INSIDE your project container
  3. Launches kitty: Bundled kitty terminal with config from container
  4. Every new tab/window: Automatically calls docker exec -it into your container

Kitty runs on your host (for GPU rendering and display), but every shell you open in it runs inside your project container via docker exec.

What gets forwarded

Category What
Network --network=host, --pid=host, --ipc=host
GPU --gpus all (NVIDIA), /dev/dri bind-mount (Intel/AMD DRI), /dev/kfd (AMD compute)
Runtime dirs /tmp, /run/user/$UID (for clipboard, temp files)
Git / SSH SSH agent socket forwarded; ~/.ssh/, ~/.gitconfig, ~/.git-credentials mounted at /run/host/ssh, /run/host/gitconfig, /run/host/git-credentials
User config ~/.config/dnc/ mounted read-write at /run/host/config/ — images can read dnc.toml for colors, keybinds, IDE settings
Shell history Per-container history persists across rebuilds (HISTFILE set for bash/zsh, fish)
nvim state Per-container swap/undo persists across rebuilds (~/.local/state/nvim)
Home Fresh container home (not host bind-mount). Host home mounted read-only at /run/host/home
Host env All host environment variables dumped to /run/host/env (shell-sourceable)
Project dir Bind-mounted read-write at its host path
Sudo Installed automatically via pacman/dnf/apt/etc., NOPASSWD for the container user

Kitty Configuration

Kitty config lives inside your project container, not on the host:

Inside container: ~/.config/kitty/kitty.conf

This way:

  • Different projects can have different kitty configs
  • Config travels with your container image
  • New tabs automatically exec into your container (dnc overrides the shell directive)

If no config is found in the container, kitty runs with defaults plus the dnc exec wrapper.

Extensibility via /run/host

dnc provides host data at well-known paths inside the container for optional integration:

Path Description
/run/host/home Read-only bind-mount of host $HOME
/run/host/env Shell-sourceable dump of all host environment variables
/run/host/config Read-write bind-mount of ~/.config/dnc/ — user IDE config
/run/host/ssh Read-only bind-mount of ~/.ssh/
/run/host/gitconfig Read-only bind-mount of ~/.gitconfig (if present)
/run/host/git-credentials Read-only bind-mount of ~/.git-credentials (if present)
/run/host/kitty Read-only mount of bundled kitty bundle — provides kitten binary, terminfo, and kitten run-shell for shell integration
/run/host/state/history Per-container shell history (persists across rebuilds)
/run/host/state/nvim Per-container nvim swap/undo files (persists across rebuilds)

Config convention

Images are expected to read /run/host/config/dnc.toml (if present) to generate native config files for the IDE. This lets you swap images while keeping your colors, keybinds, and preferences — write once in TOML, use across any compliant image.

Git / SSH

SSH agent socket is forwarded automatically via $SSH_AUTH_SOCK. Git operations (clone, push, pull) work inside the container without additional setup if your host has SSH keys loaded and gitconfig configured.

Kitty shell integration

When TERM=xterm-kitty and the bundled kitty bundle is available, entry.sh automatically delegates to kitten run-shell. This gives you:

  • Correct terminfo (xterm-kitty) — neovim and TUIs get true color, italics, styled underlines, cursor shapes
  • Shell integration — directory tracking in window title, clickable file paths, scroll marks
  • Clean shutdown — processes exit properly on window close (no warning dialog)

No image-side configuration needed. The fallback (when TERM is not xterm-kitty or the bundle is absent) launches the user's login shell directly.

Limitations

  • Rootful Docker only: Rootless lacks the --pid=host capabilities dnc relies on.
  • Container user = host uid: UID 1:1 mapping (required for rootful Docker). The container user gets NOPASSWD sudo so package installs still work.
  • No --init or systemd: PID 1 is init.sh, not init/systemd. systemctl won't work.

Commands

dnc                          Launch kitty (bundled) with container context
dnc --                       Non-graphical interactive shell (docker exec)
dnc -- <cmd>                 Run command in container
dnc setup [--image IMG]      Create container for this project
dnc rm                       Remove container + .dnc
dnc list                     List all dnc containers
dnc info                     Show container details
dnc web                      Show web IDE URL (if web_port set in .dnc)
dnc agent [--opencode] [--cursor]  Create DNC.md + agent rules
dnc version                  Show version
dnc help                     Show this help