Session manager for Docker — run, attach to, and exec into named Docker containers.
- Go 1.25+ (to install or build)
- Docker
go install github.com/fruh/tdocker/cmd/t@latestThis installs the t binary into $(go env GOPATH)/bin (usually ~/go/bin); make sure that
directory is on your PATH.
# Pick a config, name the session, run it (first run creates ~/.tconfig)
t
# Run a temporary session (auto-cleans up)
t -t
# Attach to an existing session
t -a
# Exec a command in a session
t -e "ls -la"
# List all containers, not only tdocker sessions
t -l -AThe config file path is resolved from:
TDOCKER_CONFIGenvironment variable~/.tconfig(default)
If the config file does not exist, tdocker creates a sample one on first run with python
(python:3-slim), golang (golang:latest) and ubuntu (ubuntu:latest) sessions, each
mounting the current directory at /work. Edit it to add your own images. An existing file is
never overwritten.
The same sample is in config/example.json. To keep your config in a
different place, point to it with a symlink or the environment variable:
ln -s /path/to/my-tdocker.json ~/.tconfig
# or
export TDOCKER_CONFIG=/path/to/my-tdocker.jsonExample entry:
{
"entries": [
{
"name": "python",
"command": "docker run --name \"$_CONTAINER_NAME\" -v \"$(pwd):/work\" -w /work -it python:3-slim bash",
"description": "Python 3 development"
}
]
}Supported variable substitutions:
$_CONTAINER_NAME— the auto-generated or user-supplied session name$(pwd)— current working directory${TOOLS_HOME_DIR}— value of theTOOLS_HOME_DIRenvironment variable
Every container started by tdocker is named with the session_ prefix (e.g. session_foo, or
session_<timestamp>_<pid> for -t), so tdocker sessions can be told apart from other
containers. If a command has neither $_CONTAINER_NAME nor its own --name,
--name "<session name>" is inserted after docker run automatically.
Session names may contain only letters, digits, _, . and -; typing the session_ prefix
yourself is optional.
| Flag | Description |
|---|---|
| (none) | Prompt for config, prompt for session name, persistent run |
-t |
Auto-generate name, temporary run (adds --rm) |
-c <name> |
Run config by name |
-i <index> |
Run config by number |
-t combines with -c / -i, e.g. t -t -c python.
| Flag | Description |
|---|---|
-a |
List sessions, pick one, attach (starts container if stopped) |
-e |
List sessions, pick one, exec bash (starts container if stopped) |
-e <cmd> |
List sessions, pick one, exec <cmd> (must be the last option) |
| Flag | Description |
|---|---|
-l |
List tdocker sessions (session_*) |
-k |
List and stop running sessions |
-r |
List and remove sessions (running ones must be stopped first with -k) |
-A |
With -l, -a, -e: include all containers, not only session_* ones |
t -l # list sessions
t -l -A # list all containers
t -k # stop running sessions (with confirmation)
t -r # remove sessions (with confirmation)
t -a # attach to a session
t -a -A # attach to any container
t -e "go test" # exec a command in a sessiongo build -o t ./cmd/t
./t -htdocker is written in Go, so cross-compilation is a matter of setting GOOS and GOARCH:
| Target | Command |
|---|---|
| macOS Apple Silicon (M1/M2/M3/M4) | GOOS=darwin GOARCH=arm64 go build -o t-darwin-arm64 ./cmd/t |
| macOS Intel | GOOS=darwin GOARCH=amd64 go build -o t-darwin-amd64 ./cmd/t |
| Linux x86_64 | GOOS=linux GOARCH=amd64 go build -o t-linux-amd64 ./cmd/t |
| Linux ARM64 | GOOS=linux GOARCH=arm64 go build -o t-linux-arm64 ./cmd/t |
| Windows x86_64 | GOOS=windows GOARCH=amd64 go build -o t-windows-amd64.exe ./cmd/t |
| Linux x86_64 (static) | GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o t-linux-amd64 ./cmd/t |
for target in linux/amd64 linux/arm64 darwin/arm64 darwin/amd64 windows/amd64; do
os="${target%/*}"
arch="${target#*/}"
ext=""
[[ "$os" == "windows" ]] && ext=".exe"
GOOS=$os GOARCH=$arch go build -o "t-${os}-${arch}${ext}" ./cmd/t
done