# lxcd A Distrobox-like wrapper for LXD: it creates, manages, and enters LXD dev containers as drop-in development environments, mapped to your host workspace and home. ## Requirements - LXD (`lxc`) reachable on your host — either the user is in the `lxd` group (invoked directly) or `sudo lxc` is used - Python 3.9+ - Bash completion (optional): `lxcd.completion` ## Install ```sh sudo ./setup.sh # copies lxcd.py to /usr/local/bin/lxcd + installs completion ``` `setup.sh` needs root only to write to `/usr/local/bin` and `/etc/bash_completion.d`; for a user-local install instead: ```sh BIN_DIR=~/.local/bin COMPLETION_DIR=~/.bash_completion.d ./setup.sh ``` If you use GNU Make you can also run `make install` (same thing, delegates to `setup.sh`). Or run in place from this directory: ```sh ./lxcd.py --help ``` ## Quick start ```sh lxcd init # write ~/.lxcdrc (never shown; edit with -e) lxcd init -e # open the config in $EDITOR, created first if missing lxcd create web1 # new container "web1" (defaults from ~/.lxcdrc) lxcd ls # alias for "list" lxcd enter web1 # cloud-init workspaces + mappings auto-applied ``` ## Commands | Command | Description | | --- | --- | | `init` | Write/edit the `~/.lxcdrc` config | | `create` | Create a new container (defaults from config) | | `clone ` | Clone an existing managed container | | `rename\|mv ` | Rename a container | | `enter ` | Enter a container (applies workspace + mappings) | | `list\|ls` | List managed containers | | `delete\|stop\|start\|restart` | Operate on containers (`-a` for all) | Run `lxcd --help` for full options. ## Config (`~/.lxcdrc`) INI format. Keys: - `[options]` — `workspace`, `image`, `nested`, `aptcache`, `ssh` (absolute paths OK for `workspace`/`image` when used as-is) - `[packages]` — default apt packages installed at create time - `[mappings]` under `[options]` or top-level — a list of host paths to mount into every container. A spec ending in `/` mounts a directory; an absolute host path (starting with `/`) is used **as-is** (not relative to `~`) and mounts at the same path in the container. Example: ```ini [options] workspace=/home/andrew/Code # absolute — mounted as-is image=ubuntu: nested=true aptcache=http://10.0.0.1:3142 ssh=ssh-ed25519 AAAA...andrew@host [packages] git vim [mappings] configs/ # directory: ~/configs -> /home//configs/ notes # file: ~/notes -> /home//notes /etc/hosts # absolute: used as-is ``` ## Conventions - Containers are tagged with `user.lxcd=true` for listing. - `security.nesting` is enabled when `nested=true` (cli `-n/--nested`). - Disk mounts use `shift=true` so container writes map cleanly to the host. - `enter` mounts the `[options] workspace=` host dir into the container and applies `[mappings]` before running an interactive shell as the host user. ## Completion `lxcd.completion` (bash). Keep it sourced for container-name + option completion, including `lxcd list --brief [cols]`. ## Building a snap ```sh snapcraft --destructive-mode -v ``` produces `lxcd_0.1.0_amd64.snap` (version pinned in `snap/snapcraft.yaml`). ## License MIT.