Skip to content

totophe/devcon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

devcon — Dev Container Connect (VS Code-free)

Bring up a project's dev container and drop into its shell — from the command line, without VS Code. devcon is the CLI counterpart to opening a project in an IDE: it starts the stack if it's down, runs the one-time postCreateCommand that VS Code would normally run, then execs you into a shell inside the container.

It is the evolution of dcon for a fully remote, terminal-first workflow.

Quick start

# Install (downloads the right binary for your OS/arch into ~/.local/bin):
curl -fsSL https://raw.githubusercontent.com/totophe/devcon/main/install.sh | sh

# Then, from any project with a .devcontainer folder:
cd ~/your/project
devcon

devcon brings the stack up (asking first if it's down), runs the one-time postCreateCommand, and drops you into a shell inside the container.

Mental model

You log into a remote host over SSH/mosh and land in a tmux session (e.g. via tmosh). From there:

tmux  (host — owned by tmosh at login)
  └── docker exec        ← devcon: ensure the container is up + postCreate ran
        └── your shell   ← devcon execs you in (later: zellij workspace)

devcon deliberately does not touch the multiplexer. It never starts its own tmux session, so there's no tmux-in-tmux. It just guarantees the container is alive and gets you inside — then gets out of the way (exec, no lingering wrapper).

What it does

Run devcon at a project root:

  1. Finds .devcontainer/ by walking up from the current directory.
  2. Parses devcontainer.json (JSONC — comments and trailing commas welcome).
  3. Finds the running container (via the devcontainer.local_folder label).
  4. If the stack is down, asks Start it? [Y/n], then brings it up (docker compose up -d for compose stacks, docker run for image-based) and runs the declared postCreateCommand once.
  5. Resolves the container-side workspace directory (docker exec -w).
  6. Resolves which shell to use, then execs docker exec -it -w … <shell>.

Install

The Quick start one-liner is all you need. The installer honors a couple of environment knobs:

Variable Default Purpose
DEVCON_INSTALL_DIR ~/.local/bin where to put the binary
DEVCON_VERSION latest install a specific tag, e.g. v0.1.0

Update in place any time:

devcon self-update

Requirements

  • docker
  • A .devcontainer/devcontainer.json at (or above) the project root

No VS Code, no Node, no @devcontainers/clidevcon is a single static binary.

Usage

devcon                Bring the stack up (asking first) and drop into a shell
devcon -y             Start the stack without asking if it's down
devcon --shell /bin/bash   Override the shell for this run
devcon self-update    Update to the latest release
devcon --help         Show help

Shell resolution

devcon figures out which shell to drop you into, and remembers the answer:

  1. --shell flag
  2. .devcontainer/devcon.json (persisted from a previous run)
  3. auto-detect inside the container ($SHELL, then probe zsh → bash → sh)
  4. if detection is ambiguous, ask once and save the choice

On the standard wellmade images this is silent — they ship zsh, so step 3 resolves immediately.

Lifecycle hooks

Because VS Code isn't in the loop, the lifecycle hooks it normally runs never fire. devcon runs them itself, with the spec's timing — important because these dev containers sleep infinity and stay up across many connects, so a devcon connect is an attach, not a start.

postCreateCommand — once per container creation.

  • Containers devcon creates carry a dev.devcon.postcreate label.
  • Any container (including compose services it didn't create) also gets an in-container sentinel at /tmp/.devcon-postcreate-done.
  • Either signal makes later launches skip it. Survives restarts.

postStartCommand — once per container start.

  • Keyed on the container's State.StartedAt (sentinel /tmp/.devcon-poststart-<startedAt>).
  • Skipped on re-connects to the same running container; re-runs automatically after a real docker restart (new StartedAt → new sentinel). This is what keeps start-time setup (e.g. wellmade's post-start.sh) applied in a VS-Code-free flow.

Hooks run as the declared remoteUser (if that user exists in the container — see below) in the resolved workspace folder. The wellmade scripts are idempotent anyway, so the markers are an optimization, not a correctness crutch.

remoteUser

devcon execs as the remoteUser from devcontainer.json — but only after verifying that user actually exists in the running container (id <user>). If the running image doesn't provide it, devcon warns and falls back to the image's default user instead of failing with unable to find user … in passwd file.

Configuration

Per-project config lives at .devcontainer/devcon.json:

{
  "shell": "/bin/zsh"
}

Global fallback: ~/.config/devcon/config.json. Precedence: project over global; --shell beats both.

Codename derivation

The container name (for containers devcon creates) is derived from the project path, same rule as dcon:

pwd Codename
/home/user/workspaces/totophe/devcon totophe_devcon
/home/user/workspaces/myproject myproject
/home/user/projects/myapp myapp

Roadmap

  • zellij workspace mode — a --workspace flag that execs zellij attach -c <codename> instead of a bare shell, completing the tmux → docker → zellij vision. Parked; the machinery is already in place (it only swaps the final exec command).

Building from source

cargo build --release
cargo test --all
cargo clippy --all-targets -- -D warnings

License

MIT — see LICENSE.

About

A small tool to interact with dev container locally

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors